diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index c1b6a88e..1de95877 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -57,7 +57,7 @@ jobs: max-parallel: 15 fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', 'pypy-3.9', 'pypy-3.10'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9', 'pypy-3.10'] test-type: ['standalone', 'cluster'] connection-type: ['hiredis', 'plain'] env: @@ -80,6 +80,9 @@ jobs: invoke devenv sleep 10 # time to settle invoke ${{matrix.test-type}}-tests + if [[ "${{matrix.python-version}}" != pypy-* ]]; then + invoke ${{matrix.test-type}}-tests --uvloop + fi - uses: actions/upload-artifact@v4 if: success() || failure() @@ -111,12 +114,9 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.8', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9', 'pypy-3.10'] test-type: ['standalone', 'cluster'] connection-type: ['hiredis', 'plain'] - exclude: - - test-type: 'cluster' - connection-type: 'hiredis' env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true name: RESP3 [${{ matrix.python-version }} ${{matrix.test-type}}-${{matrix.connection-type}}] @@ -137,7 +137,9 @@ jobs: invoke devenv sleep 10 # time to settle invoke ${{matrix.test-type}}-tests --protocol=3 - invoke ${{matrix.test-type}}-tests --uvloop --protocol=3 + if [[ "${{matrix.python-version}}" != pypy-* ]]; then + invoke ${{matrix.test-type}}-tests --uvloop --protocol=3 + fi - uses: actions/upload-artifact@v4 if: success() || failure() @@ -187,7 +189,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', 'pypy-3.9', 'pypy-3.10'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9', 'pypy-3.10'] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/dev_requirements.txt b/dev_requirements.txt index b1e10f96..2b2dbf9d 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,11 +1,11 @@ -black==24.3.0 +black cachetools -click==8.0.4 -flake8-isort==6.0.0 -flake8==5.0.4 -flynt~=0.69.0 -invoke==1.7.3 -mock==4.0.3 +click +flake8-isort +flake8 +flynt +invoke +mock packaging>=20.4 pytest pytest-asyncio diff --git a/tasks.py b/tasks.py index b3b89f69..ff1466bc 100644 --- a/tasks.py +++ b/tasks.py @@ -25,56 +25,56 @@ def build_docs(c): @task -def linters(c): +def linters(c, color=False): """Run code linters""" - run("flake8 tests valkey") - run("black --target-version py37 --check --diff tests valkey") - run("isort --check-only --diff tests valkey") + run(f"flake8 --color {'always' if color else 'never'} tests valkey") + run(f"black {'--color' if color else ''} --target-version py37 --check --diff tests valkey") + run(f"isort {'--color' if color else ''} --check-only --diff tests valkey") run("vulture valkey whitelist.py --min-confidence 80") run("flynt --fail-on-change --dry-run tests valkey") @task -def all_tests(c): +def all_tests(c, color=False): """Run all linters, and tests in valkey-py.""" - linters(c) - tests(c) + linters(c, color=color) + tests(c, color=color) @task -def tests(c, uvloop=False, protocol=2): +def tests(c, uvloop=False, protocol=2, color=False): """Run the valkey-py test suite against the current python, with and without hiredis. """ print("Starting Valkey tests") - standalone_tests(c, uvloop=uvloop, protocol=protocol) - cluster_tests(c, uvloop=uvloop, protocol=protocol) + standalone_tests(c, uvloop=uvloop, protocol=protocol, color=color) + cluster_tests(c, uvloop=uvloop, protocol=protocol, color=color) @task -def standalone_tests(c, uvloop=False, protocol=2): +def standalone_tests(c, uvloop=False, protocol=2, color=False): """Run tests against a standalone valkey instance""" if uvloop: run( - f"pytest --protocol={protocol} --cov=./ --cov-report=xml:coverage_valkey.xml -W always -m 'not onlycluster' --uvloop --junit-xml=standalone-uvloop-results.xml" + f"pytest --color={'yes' if color else 'no'} --protocol={protocol} --cov=./ --cov-report=xml:coverage_valkey.xml -W always -m 'not onlycluster' --uvloop --junit-xml=standalone-uvloop-results.xml" ) else: run( - f"pytest --protocol={protocol} --cov=./ --cov-report=xml:coverage_valkey.xml -W always -m 'not onlycluster' --junit-xml=standalone-results.xml" + f"pytest --color={'yes' if color else 'no'} --protocol={protocol} --cov=./ --cov-report=xml:coverage_valkey.xml -W always -m 'not onlycluster' --junit-xml=standalone-results.xml" ) @task -def cluster_tests(c, uvloop=False, protocol=2): +def cluster_tests(c, uvloop=False, protocol=2, color=False): """Run tests against a valkey cluster""" cluster_url = "valkey://localhost:16379/0" if uvloop: run( - f"pytest --protocol={protocol} --cov=./ --cov-report=xml:coverage_cluster.xml -W always -m 'not onlynoncluster and not valkeymod' --valkey-url={cluster_url} --junit-xml=cluster-uvloop-results.xml --uvloop" + f"pytest --color={'yes' if color else 'no'} --protocol={protocol} --cov=./ --cov-report=xml:coverage_cluster.xml -W always -m 'not onlynoncluster and not valkeymod' --valkey-url={cluster_url} --junit-xml=cluster-uvloop-results.xml --uvloop" ) else: run( - f"pytest --protocol={protocol} --cov=./ --cov-report=xml:coverage_clusteclient.xml -W always -m 'not onlynoncluster and not valkeymod' --valkey-url={cluster_url} --junit-xml=cluster-results.xml" + f"pytest --color={'yes' if color else 'no'} --protocol={protocol} --cov=./ --cov-report=xml:coverage_clusteclient.xml -W always -m 'not onlynoncluster and not valkeymod' --valkey-url={cluster_url} --junit-xml=cluster-results.xml" ) diff --git a/tests/test_asyncio/test_lock.py b/tests/test_asyncio/test_lock.py index b2be86f6..49b593c4 100644 --- a/tests/test_asyncio/test_lock.py +++ b/tests/test_asyncio/test_lock.py @@ -237,4 +237,4 @@ def __init__(self, *args, **kwargs): pass lock = r.lock("foo", lock_class=MyLock) - assert type(lock) == MyLock + assert isinstance(lock, MyLock) diff --git a/tests/test_lock.py b/tests/test_lock.py index 4f2b8fa2..bae5e663 100644 --- a/tests/test_lock.py +++ b/tests/test_lock.py @@ -257,4 +257,4 @@ def __init__(self, *args, **kwargs): pass lock = r.lock("foo", lock_class=MyLock) - assert type(lock) == MyLock + assert isinstance(lock, MyLock) diff --git a/valkey/_parsers/helpers.py b/valkey/_parsers/helpers.py index 8fbd2e82..19e65dc2 100644 --- a/valkey/_parsers/helpers.py +++ b/valkey/_parsers/helpers.py @@ -507,7 +507,7 @@ def parse_geosearch_generic(response, **options): except KeyError: # it means the command was sent via execute_command return response - if type(response) != list: + if not isinstance(response, list): response_list = [response] else: response_list = response diff --git a/valkey/commands/core.py b/valkey/commands/core.py index 33b5abe4..669d3148 100644 --- a/valkey/commands/core.py +++ b/valkey/commands/core.py @@ -1380,9 +1380,6 @@ def failover(self): ) -AsyncManagementCommands = ManagementCommands - - class AsyncManagementCommands(ManagementCommands): async def command_info(self, **kwargs) -> None: return super().command_info(**kwargs) diff --git a/valkey/commands/timeseries/info.py b/valkey/commands/timeseries/info.py index afdf70ec..91794f6e 100644 --- a/valkey/commands/timeseries/info.py +++ b/valkey/commands/timeseries/info.py @@ -78,7 +78,7 @@ def __init__(self, args): self.chunk_size = response["chunkSize"] if "duplicatePolicy" in response: self.duplicate_policy = response["duplicatePolicy"] - if type(self.duplicate_policy) == bytes: + if isinstance(self.duplicate_policy, bytes): self.duplicate_policy = self.duplicate_policy.decode() def get(self, item):