From 997fbe7441068b29d6072730b1b85848aa6e27bd Mon Sep 17 00:00:00 2001 From: --get Date: Sun, 2 Jul 2023 12:13:21 -0400 Subject: [PATCH] fix:fix connection method override for django-rq Fix #204 --- docs/about/changelog.md | 4 ++ docs/index.md | 5 ++- fakeredis/__init__.py | 4 +- fakeredis/_server.py | 26 +++++++------ poetry.lock | 86 ++--------------------------------------- test/test_general.py | 9 ----- 6 files changed, 28 insertions(+), 106 deletions(-) diff --git a/docs/about/changelog.md b/docs/about/changelog.md index a3ffd2e5..9f434f94 100644 --- a/docs/about/changelog.md +++ b/docs/about/changelog.md @@ -11,6 +11,10 @@ description: Change log of all fakeredis releases - Implemented support for `JSON.MSET` #174, `JSON.MERGE` #181 +### 🧰 Maintenance + +- Updated how to test django_rq #204 + ## v2.15.0 ### 🚀 Features diff --git a/docs/index.md b/docs/index.md index 68d64fa6..f57f9bc4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -129,9 +129,10 @@ There is a need to override `django_rq.queues.get_redis_connection` with a method returning the same connection. ```python -from fakeredis import FakeRedisConnSingleton +import django_rq +from fakeredis import get_fake_connection -django_rq.queues.get_redis_connection = FakeRedisConnSingleton() +django_rq.queues.get_redis_connection = get_fake_connection ``` ## Known Limitations diff --git a/fakeredis/__init__.py b/fakeredis/__init__.py index ec48efea..0cd392f6 100644 --- a/fakeredis/__init__.py +++ b/fakeredis/__init__.py @@ -1,4 +1,4 @@ -from ._server import FakeServer, FakeRedis, FakeStrictRedis, FakeConnection, FakeRedisConnSingleton +from ._server import FakeServer, FakeRedis, FakeStrictRedis, FakeConnection, get_fake_connection try: from importlib import metadata @@ -7,4 +7,4 @@ __version__ = metadata.version("fakeredis") -__all__ = ["FakeServer", "FakeRedis", "FakeStrictRedis", "FakeConnection", "FakeRedisConnSingleton"] +__all__ = ["FakeServer", "FakeRedis", "FakeStrictRedis", "FakeConnection", "get_fake_connection"] diff --git a/fakeredis/_server.py b/fakeredis/_server.py index 825e41a3..8a63c8c4 100644 --- a/fakeredis/_server.py +++ b/fakeredis/_server.py @@ -7,7 +7,7 @@ import warnings import weakref from collections import defaultdict -from typing import Dict, Tuple +from typing import Dict, Tuple, Any import redis @@ -213,13 +213,17 @@ class FakeRedis(FakeRedisMixin, redis.Redis): # Set up the connection before RQ Django reads the settings. # The connection must be the same because in fakeredis connections # do not share the state. Therefore, we define a singleton object to reuse it. -class FakeRedisConnSingleton: - """Singleton FakeRedis connection.""" - - def __init__(self): - self.conn = None - - def __call__(self, _, strict): - if not self.conn: - self.conn = FakeStrictRedis() if strict else FakeRedis() - return self.conn +def get_fake_connection(config: Dict[str, Any], strict: bool): + redis_cls = FakeStrictRedis if strict else FakeRedis + if 'URL' in config: + return redis_cls.from_url( + config['URL'], + db=config.get('DB'), + ) + return redis_cls( + host=config['HOST'], + port=config['PORT'], + db=config.get('DB', 0), + username=config.get('USERNAME', None), + password=config.get('PASSWORD'), + ) diff --git a/poetry.lock b/poetry.lock index 59b8bf95..63b2e566 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "async-timeout" version = "4.0.2" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -19,7 +18,6 @@ typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -41,7 +39,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -60,7 +57,6 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] name = "cachetools" version = "5.3.1" description = "Extensible memoizing collections and decorators" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -72,7 +68,6 @@ files = [ name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -84,7 +79,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "dev" optional = false python-versions = "*" files = [ @@ -161,7 +155,6 @@ pycparser = "*" name = "chardet" version = "5.1.0" description = "Universal encoding detector for Python 3" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -173,7 +166,6 @@ files = [ name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -258,7 +250,6 @@ files = [ name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -270,7 +261,6 @@ files = [ name = "coverage" version = "7.2.7" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -346,7 +336,6 @@ toml = ["tomli"] name = "cryptography" version = "41.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -388,7 +377,6 @@ test-randomorder = ["pytest-randomly"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -400,7 +388,6 @@ files = [ name = "deprecated" version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -418,7 +405,6 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] name = "distlib" version = "0.3.6" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -430,7 +416,6 @@ files = [ name = "docker" version = "6.1.3" description = "A Python library for the Docker Engine API." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -452,7 +437,6 @@ ssh = ["paramiko (>=2.4.3)"] name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -464,7 +448,6 @@ files = [ name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -479,7 +462,6 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.12.2" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -495,7 +477,6 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "p name = "flake8" version = "6.0.0" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.8.1" files = [ @@ -512,7 +493,6 @@ pyflakes = ">=3.0.0,<3.1.0" name = "flake8-pyproject" version = "1.2.3" description = "Flake8 plug-in loading the configuration from pyproject.toml" -category = "dev" optional = false python-versions = ">= 3.6" files = [ @@ -530,7 +510,6 @@ dev = ["pyTest", "pyTest-cov"] name = "hypothesis" version = "6.79.4" description = "A library for property-based testing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -563,7 +542,6 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2023.3)"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -575,7 +553,6 @@ files = [ name = "importlib-metadata" version = "6.7.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -596,7 +573,6 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -615,7 +591,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -627,7 +602,6 @@ files = [ name = "jaraco-classes" version = "3.2.3" description = "Utility functions for Python class constructs" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -646,7 +620,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "jeepney" version = "0.8.0" description = "Low-level, pure Python DBus protocol wrapper." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -662,7 +635,6 @@ trio = ["async_generator", "trio"] name = "jsonpath-ng" version = "1.5.3" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." -category = "main" optional = true python-versions = "*" files = [ @@ -680,7 +652,6 @@ six = "*" name = "keyring" version = "24.1.1" description = "Store and access your passwords safely." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -705,7 +676,6 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "lupa" version = "1.14.1" description = "Python wrapper around Lua and LuaJIT" -category = "main" optional = true python-versions = "*" files = [ @@ -790,7 +760,6 @@ files = [ name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -816,7 +785,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -828,7 +796,6 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -840,7 +807,6 @@ files = [ name = "more-itertools" version = "9.1.0" description = "More routines for operating on iterables, beyond itertools" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -852,7 +818,6 @@ files = [ name = "mypy" version = "1.4.1" description = "Optional static typing for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -900,7 +865,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -912,7 +876,6 @@ files = [ name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -924,7 +887,6 @@ files = [ name = "pkginfo" version = "1.9.6" description = "Query metadata from sdists / bdists / installed packages." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -939,7 +901,6 @@ testing = ["pytest", "pytest-cov"] name = "platformdirs" version = "3.8.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -958,7 +919,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -977,7 +937,6 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" -category = "main" optional = true python-versions = "*" files = [ @@ -989,7 +948,6 @@ files = [ name = "pycodestyle" version = "2.10.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1001,7 +959,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1013,7 +970,6 @@ files = [ name = "pyflakes" version = "3.0.1" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1025,7 +981,6 @@ files = [ name = "pygithub" version = "1.59.0" description = "Use the full Github API v3" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1043,7 +998,6 @@ requests = ">=2.14.0" name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1058,7 +1012,6 @@ plugins = ["importlib-metadata"] name = "pyjwt" version = "2.7.0" description = "JSON Web Token implementation in Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1080,7 +1033,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1107,7 +1059,6 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "pyproject-api" version = "1.5.2" description = "API to interact with the python pyproject.toml based projects" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1127,7 +1078,6 @@ testing = ["covdefaults (>=2.3)", "importlib-metadata (>=6.6)", "pytest (>=7.3.1 name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1151,7 +1101,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.21.0" description = "Pytest support for asyncio" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1171,7 +1120,6 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1190,7 +1138,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-mock" version = "3.11.1" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1208,7 +1155,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "dev" optional = false python-versions = "*" files = [ @@ -1232,7 +1178,6 @@ files = [ name = "pywin32-ctypes" version = "0.2.2" description = "A (partial) reimplementation of pywin32 using ctypes/cffi" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1244,7 +1189,6 @@ files = [ name = "readme-renderer" version = "37.3" description = "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1264,7 +1208,6 @@ md = ["cmarkgfm (>=0.8.0)"] name = "redis" version = "4.6.0" description = "Python client for Redis database and key-value store" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1285,7 +1228,6 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1307,7 +1249,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1322,7 +1263,6 @@ requests = ">=2.0.1,<3.0.0" name = "rfc3986" version = "2.0.0" description = "Validating URI References per RFC 3986" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1337,7 +1277,6 @@ idna2008 = ["idna"] name = "rich" version = "13.4.2" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -1357,7 +1296,6 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "secretstorage" version = "3.3.3" description = "Python bindings to FreeDesktop.org Secret Service API" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1373,7 +1311,6 @@ jeepney = ">=0.6" name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1385,7 +1322,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "main" optional = false python-versions = "*" files = [ @@ -1397,7 +1333,6 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1409,7 +1344,6 @@ files = [ name = "tox" version = "4.6.3" description = "tox is a generic virtualenv management and test command line tool" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1439,7 +1373,6 @@ testing = ["build[virtualenv] (>=0.10)", "covdefaults (>=2.3)", "detect-test-pol name = "tox-docker" version = "4.1.0" description = "Launch a docker instance around test runs" -category = "dev" optional = false python-versions = "*" files = [ @@ -1456,7 +1389,6 @@ tox = ">=3.0.0,<5.0" name = "twine" version = "4.0.2" description = "Collection of utilities for publishing packages on PyPI" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1479,7 +1411,6 @@ urllib3 = ">=1.26.0" name = "typed-ast" version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1513,7 +1444,6 @@ files = [ name = "types-pyopenssl" version = "23.2.0.1" description = "Typing stubs for pyOpenSSL" -category = "dev" optional = false python-versions = "*" files = [ @@ -1528,7 +1458,6 @@ cryptography = ">=35.0.0" name = "types-redis" version = "4.6.0.1" description = "Typing stubs for redis" -category = "dev" optional = false python-versions = "*" files = [ @@ -1542,21 +1471,19 @@ types-pyOpenSSL = "*" [[package]] name = "typing-extensions" -version = "4.7.0" +version = "4.7.1" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.7.0-py3-none-any.whl", hash = "sha256:5d8c9dac95c27d20df12fb1d97b9793ab8b2af8a3a525e68c80e21060c161771"}, - {file = "typing_extensions-4.7.0.tar.gz", hash = "sha256:935ccf31549830cda708b42289d44b6f74084d616a00be651601a4f968e77c82"}, + {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, + {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] [[package]] name = "urllib3" version = "2.0.3" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1574,7 +1501,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "virtualenv" version = "20.23.1" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1596,7 +1522,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "dev" optional = false python-versions = "*" files = [ @@ -1608,7 +1533,6 @@ files = [ name = "websocket-client" version = "1.6.1" description = "WebSocket client for Python with low level API options" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1625,7 +1549,6 @@ test = ["websockets"] name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -1710,7 +1633,6 @@ files = [ name = "zipp" version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" files = [ diff --git a/test/test_general.py b/test/test_general.py index b972a979..b5efa555 100644 --- a/test/test_general.py +++ b/test/test_general.py @@ -5,15 +5,6 @@ from test.testtools import raw_command -@pytest.mark.fake -def test_singleton(): - conn_generator = fakeredis.FakeRedisConnSingleton() - conn1 = conn_generator(dict(), False) - conn2 = conn_generator(dict(), False) - assert conn1.set('foo', 'bar') is True - assert conn2.get('foo') == b'bar' - - def test_asyncioio_is_used(): """Redis 4.2+ has support for asyncio and should be preferred over aioredis""" from fakeredis import aioredis