redis-lua-py 0.5.0__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/ci.yml +15 -1
- redis_lua_py-0.5.1/.release-please-manifest.json +3 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/CHANGELOG.md +7 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/PKG-INFO +1 -1
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/pyproject.toml +1 -1
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/__init__.py +1 -1
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_library.py +20 -1
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_functions.py +22 -0
- redis_lua_py-0.5.0/.release-please-manifest.json +0 -3
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/README.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/banner-dark.svg +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/banner-light.svg +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/generate.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/logo.svg +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/logomark.svg +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/social-preview.png +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/social-preview.svg +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/docs.yml +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/pr-title.yml +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/release.yml +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.gitignore +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.python-version +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/CONTRIBUTING.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/LICENSE +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/README.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/assets/logo.svg +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/contributing.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/development.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/examples.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/async.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/binary-values.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/binding-a-client.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/build-time.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/calling-redis-commands.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/constants.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/generated-lua.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/keys-and-arguments.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/redis-functions.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/return-values.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/testing.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/index.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/installation.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/quickstart.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/api.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/errors.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/lua-vs-python.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/supported-subset.md +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/stylesheets/extra.css +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/release-please-config.json +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/scripts/generate_commands.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/__main__.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_commands.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_compile.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_lua.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_runtime.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_script.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/codegen.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/errors.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/py.typed +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/codegen_scripts.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/conftest.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/module_with_client.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/module_without_import.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_binary.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_binding.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_codegen.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_commands.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_compile.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_constants.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_control_flow.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_errors.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_execute.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_mistranslations.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_namespace.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_semantics.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_strings_and_indexing.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_table_stakes.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_typing.py +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/uv.lock +0 -0
- {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/zensical.toml +0 -0
|
@@ -37,6 +37,17 @@ jobs:
|
|
|
37
37
|
oldest:
|
|
38
38
|
name: Tests (oldest supported Python and redis-py)
|
|
39
39
|
runs-on: ubuntu-latest
|
|
40
|
+
# A real server as well, since what fakeredis cannot run -- Redis Functions
|
|
41
|
+
# and script flags -- is exactly what old redis-py spells differently.
|
|
42
|
+
services:
|
|
43
|
+
redis:
|
|
44
|
+
image: redis:7
|
|
45
|
+
ports: ["6379:6379"]
|
|
46
|
+
options: >-
|
|
47
|
+
--health-cmd "redis-cli ping"
|
|
48
|
+
--health-interval 10s
|
|
49
|
+
--health-timeout 5s
|
|
50
|
+
--health-retries 5
|
|
40
51
|
steps:
|
|
41
52
|
- uses: actions/checkout@v4
|
|
42
53
|
- uses: astral-sh/setup-uv@v5
|
|
@@ -46,8 +57,11 @@ jobs:
|
|
|
46
57
|
# The floor in pyproject.toml is only a claim until something runs on it.
|
|
47
58
|
# fakeredis declares redis>=4.3 but works on 4.2, the first release with
|
|
48
59
|
# redis.asyncio, so the pin goes in after the resolver is done.
|
|
49
|
-
- run: uv pip install --no-deps "redis==4.2.0" async-timeout deprecated
|
|
60
|
+
- run: uv pip install --no-deps "redis==4.2.0" async-timeout deprecated packaging
|
|
50
61
|
- run: uv run --no-sync pytest
|
|
62
|
+
- run: uv run --no-sync pytest
|
|
63
|
+
env:
|
|
64
|
+
REDIS_URL: redis://localhost:6379/0
|
|
51
65
|
|
|
52
66
|
live:
|
|
53
67
|
name: Tests against a real Redis
|
|
@@ -7,6 +7,13 @@ are written by [release-please](https://github.com/googleapis/release-please)
|
|
|
7
7
|
from the conventional commit subjects on `main`; see
|
|
8
8
|
[CONTRIBUTING.md](CONTRIBUTING.md) for how a release is cut.
|
|
9
9
|
|
|
10
|
+
## [0.5.1](https://github.com/IgnaceMaes/redis-lua-py/compare/v0.5.0...v0.5.1) (2026-09-12)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
* load redis functions libraries on redis-py 4.2 ([#16](https://github.com/IgnaceMaes/redis-lua-py/issues/16)) ([85c2ba2](https://github.com/IgnaceMaes/redis-lua-py/commit/85c2ba20056224af7b2c9720176f799cf54b163f))
|
|
16
|
+
|
|
10
17
|
## [0.5.0](https://github.com/IgnaceMaes/redis-lua-py/compare/v0.4.0...v0.5.0) (2026-09-12)
|
|
11
18
|
|
|
12
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: redis-lua-py
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Write Redis Lua scripts as real Python functions, not strings.
|
|
5
5
|
Project-URL: Homepage, https://ignacemaes.com/redis-lua-py/
|
|
6
6
|
Project-URL: Documentation, https://ignacemaes.com/redis-lua-py/
|
|
@@ -43,6 +43,23 @@ def _function_missing(error: BaseException) -> bool:
|
|
|
43
43
|
return "Function not found" in str(error)
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def _modern_function_load(client: object) -> Any:
|
|
47
|
+
"""The client's function_load, if it takes the library code first.
|
|
48
|
+
|
|
49
|
+
Early redis-py releases, 4.2.0 among them, still have the Redis 7
|
|
50
|
+
release-candidate signature, function_load(engine, library, code), which
|
|
51
|
+
no released Redis accepts.
|
|
52
|
+
"""
|
|
53
|
+
function_load = getattr(client, "function_load", None)
|
|
54
|
+
if function_load is None:
|
|
55
|
+
return None
|
|
56
|
+
try:
|
|
57
|
+
parameters = list(inspect.signature(function_load).parameters)
|
|
58
|
+
except (TypeError, ValueError): # a callable without an inspectable signature
|
|
59
|
+
return None
|
|
60
|
+
return function_load if parameters[:1] == ["code"] else None
|
|
61
|
+
|
|
62
|
+
|
|
46
63
|
class Library:
|
|
47
64
|
"""A Redis Functions library, built from Python functions.
|
|
48
65
|
|
|
@@ -130,8 +147,10 @@ class Library:
|
|
|
130
147
|
is only needed ahead of a pipeline, or to load at deploy time. Returns
|
|
131
148
|
what the client returns: an awaitable for an async client.
|
|
132
149
|
"""
|
|
133
|
-
function_load =
|
|
150
|
+
function_load = _modern_function_load(client)
|
|
134
151
|
if function_load is not None:
|
|
152
|
+
# Preferred where it exists, since redis-py routes it to every
|
|
153
|
+
# primary of a cluster.
|
|
135
154
|
return function_load(self.lua, replace=True)
|
|
136
155
|
return client.execute_command("FUNCTION", "LOAD", "REPLACE", self.lua)
|
|
137
156
|
|
|
@@ -163,6 +163,28 @@ class TestLoadingOnDemand:
|
|
|
163
163
|
|
|
164
164
|
assert bump_all(client, keys=["a", "b"]) == ("ran", "FCALL", "bump_all", 2, "a", "b")
|
|
165
165
|
|
|
166
|
+
def test_an_old_function_load_signature_is_not_used(self) -> None:
|
|
167
|
+
"""redis-py 4.2.0 has function_load(engine, library, code), from a Redis 7 RC."""
|
|
168
|
+
|
|
169
|
+
class OldRedisPy(FakeClient):
|
|
170
|
+
def execute_command(self, *args: Any) -> Any:
|
|
171
|
+
if args[:3] == ("FUNCTION", "LOAD", "REPLACE"):
|
|
172
|
+
self.calls.append(args[:3])
|
|
173
|
+
self.loaded = args[3]
|
|
174
|
+
return "rlp_counters"
|
|
175
|
+
return FakeClient.execute_command(self, *args)
|
|
176
|
+
|
|
177
|
+
def function_load( # type: ignore[override]
|
|
178
|
+
self, engine: str, library: str, code: str, replace: bool = False
|
|
179
|
+
) -> str:
|
|
180
|
+
raise AssertionError("the release-candidate signature must not be called")
|
|
181
|
+
|
|
182
|
+
client = OldRedisPy()
|
|
183
|
+
|
|
184
|
+
assert bump(client, key="k", by=2) == ("ran", "FCALL", "bump", 1, "k", "2")
|
|
185
|
+
assert client.loaded == counters.lua
|
|
186
|
+
assert ("FUNCTION", "LOAD", "REPLACE") in client.calls
|
|
187
|
+
|
|
166
188
|
def test_another_error_is_not_swallowed(self) -> None:
|
|
167
189
|
class Failing(FakeClient):
|
|
168
190
|
def execute_command(self, *args: Any) -> Any:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|