Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Tests

on:
pull_request:
branches:
- master

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Run tests
run: python -m unittest
29 changes: 29 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[build-system]
requires = ["hatchling", "hatch-requirements-txt"]
build-backend = "hatchling.build"

[project]
name = "python_redis"
version = "0.4.1"
requires-python = ">=3.9"
authors = [
{name = "Stephan Schultchen", email = "stephan.schultchen@gmail.com"},
]
description = "Redis Client"
dynamic = ["dependencies"]
license = {file = "LICENSE.txt"}
keywords = ["redis"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License"
]

[tool.hatch.build.targets.wheel]
packages = ["pyredis"]

[tool.hatch.metadata.hooks.requirements_txt]
files = ["requirements.txt"]

[project.urls]
Repository = "https://github.com/schlitzered/pyredis"
Issues = "https://github.com/schlitzered/pyredis/issues"
6 changes: 6 additions & 0 deletions pyredis/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

class Client(
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand All @@ -28,6 +29,7 @@ class Client(

Inherits the following Command classes:
- commands.Connection,
- commands.Geo,
- commands.Hash,
- commands.HyperLogLog,
- commands.Key,
Expand Down Expand Up @@ -157,6 +159,7 @@ def execute(self, *args):

class ClusterClient(
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand All @@ -171,6 +174,7 @@ class ClusterClient(

Inherits the following Commmand classes:
- commands.Connection,
- commands.Geo,
- commands.Hash,
- commands.HyperLogLog,
- commands.Key,
Expand Down Expand Up @@ -346,6 +350,7 @@ def execute(self, *args, shard_key=None, sock=None, asking=False, retries=3):

class HashClient(
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand Down Expand Up @@ -375,6 +380,7 @@ class HashClient(

Inherits the following Commmand classes:
- commands.Connection,
- commands.Geo,
- commands.Hash,
- commands.HyperLogLog,
- commands.Key,
Expand Down
2 changes: 2 additions & 0 deletions pyredis/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

__all__ = [
"Connection",
"Geo",
"Hash",
"HyperLogLog",
"Key",
Expand All @@ -16,6 +17,7 @@
]



class BaseCommand(object):
def __init__(self):
self._cluster = False
Expand Down
21 changes: 10 additions & 11 deletions pyredis/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,10 @@ def _connect(self):

def _connect_inet46(self):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(self._conn_timeout)
sock.connect((self.host, self.port))
except socket.gaierror:
try:
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.settimeout(self._conn_timeout)
sock.connect((self.host, self.port))
except socket.gaierror:
raise PyRedisConnError("Host is neither a IPv4 or IPv6 address")
sock = socket.create_connection(
address=(self.host, self.port),
timeout=self._conn_timeout
)
except (
ConnectionAbortedError,
ConnectionRefusedError,
Expand All @@ -148,10 +142,15 @@ def _connect_inet46(self):
) as err:
self.close()
raise PyRedisConnError(
"Could not Connect to {0}:{1}: {2}".format(self.host, self.port, err)
"Could not Connect to {0}:{1}: {2}".format(
self.host,
self.port,
err
)
)
return sock


def _connect_unix(self):
try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
Expand Down
5 changes: 2 additions & 3 deletions pyredis/helper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import crc
import binascii
import random
from collections import deque
from threading import Lock
Expand All @@ -9,7 +9,6 @@
from pyredis.protocol import to_bytes


crc16 = crc.Calculator(crc.Crc16.CCITT)


def dict_from_list(source):
Expand Down Expand Up @@ -37,7 +36,7 @@ def tag_from_key(key):


def slot_from_key(key):
return crc16.checksum(tag_from_key(key)) % 16384
return binascii.crc_hqx(tag_from_key(key), 0) % 16384


class ClusterMap(object):
Expand Down
84 changes: 15 additions & 69 deletions pyredis/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,21 @@ def release(self, conn):
finally:
self._lock.release()

def execute(self, *args, **kwargs):
conn = self.acquire()
try:
return conn.execute(
*args,
**kwargs
)
finally:
self.release(conn)


class ClusterPool(
BasePool,
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand Down Expand Up @@ -252,24 +263,11 @@ def _connect(self):
username=self.username,
)

def execute(self, *args, **kwargs):
"""Execute arbitrary redis command.

:param args:
:type args: list, int, float

:return: result, exception
"""
conn = self.acquire()
try:
return conn.execute(*args, **kwargs)
finally:
self.release(conn)


class HashPool(
BasePool,
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand Down Expand Up @@ -329,24 +327,11 @@ def _connect(self):
username=self.username,
)

def execute(self, *args, **kwargs):
"""Execute arbitrary redis command.

:param args:
:type args: list, int, float

:return: result, exception
"""
conn = self.acquire()
try:
return conn.execute(*args, **kwargs)
finally:
self.release(conn)


class Pool(
BasePool,
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand Down Expand Up @@ -422,24 +407,11 @@ def _connect(self):
username=self.username,
)

def execute(self, *args):
"""Execute arbitrary redis command.

:param args:
:type args: list, int, float

:return: result, exception
"""
conn = self.acquire()
try:
return conn.execute(*args)
finally:
self.release(conn)


class SentinelHashPool(
BasePool,
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand Down Expand Up @@ -599,24 +571,11 @@ def _get_slaves(self):
)
return self._get_hash_client(buckets=buckets)

def execute(self, *args, **kwargs):
"""Execute arbitrary redis command.

:param args:
:type args: list, int, float

:return: result, exception
"""
conn = self.acquire()
try:
return conn.execute(*args, **kwargs)
finally:
self.release(conn)


class SentinelPool(
BasePool,
commands.Connection,
commands.Geo,
commands.Hash,
commands.HyperLogLog,
commands.Key,
Expand Down Expand Up @@ -748,16 +707,3 @@ def _get_slave(self):
client = self._get_client(host, port)
return client

def execute(self, *args):
"""Execute arbitrary redis command.

:param args:
:type args: list, int, float

:return: result, exception
"""
conn = self.acquire()
try:
return conn.execute(*args)
finally:
self.release(conn)
15 changes: 11 additions & 4 deletions pyredis/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@ def is_exception(inst, classinfo):
try:
if issubclass(inst, classinfo):
return True
else:
raise TypeError()
except TypeError:
pass
try:
if isinstance(inst("test"), classinfo):
return True
else:
raise TypeError("{0} is not a subclass of {1}".format(inst, classinfo))
except TypeError:
pass
raise TypeError(
"{0} is not a subclass of {1}".format(
inst,
classinfo
)
)



class ReplyParser(object):
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 0 additions & 2 deletions setup.cfg

This file was deleted.

34 changes: 0 additions & 34 deletions setup.py

This file was deleted.

Loading
Loading