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.
Files changed (80) hide show
  1. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/ci.yml +15 -1
  2. redis_lua_py-0.5.1/.release-please-manifest.json +3 -0
  3. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/CHANGELOG.md +7 -0
  4. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/PKG-INFO +1 -1
  5. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/pyproject.toml +1 -1
  6. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/__init__.py +1 -1
  7. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_library.py +20 -1
  8. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_functions.py +22 -0
  9. redis_lua_py-0.5.0/.release-please-manifest.json +0 -3
  10. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/README.md +0 -0
  11. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/banner-dark.svg +0 -0
  12. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/banner-light.svg +0 -0
  13. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/generate.py +0 -0
  14. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/logo.svg +0 -0
  15. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/logomark.svg +0 -0
  16. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/social-preview.png +0 -0
  17. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/assets/social-preview.svg +0 -0
  18. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/docs.yml +0 -0
  19. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/pr-title.yml +0 -0
  20. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.github/workflows/release.yml +0 -0
  21. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.gitignore +0 -0
  22. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/.python-version +0 -0
  23. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/CONTRIBUTING.md +0 -0
  24. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/LICENSE +0 -0
  25. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/README.md +0 -0
  26. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/assets/logo.svg +0 -0
  27. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/contributing.md +0 -0
  28. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/development.md +0 -0
  29. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/examples.md +0 -0
  30. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/async.md +0 -0
  31. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/binary-values.md +0 -0
  32. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/binding-a-client.md +0 -0
  33. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/build-time.md +0 -0
  34. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/calling-redis-commands.md +0 -0
  35. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/constants.md +0 -0
  36. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/generated-lua.md +0 -0
  37. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/keys-and-arguments.md +0 -0
  38. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/redis-functions.md +0 -0
  39. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/return-values.md +0 -0
  40. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/guide/testing.md +0 -0
  41. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/index.md +0 -0
  42. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/installation.md +0 -0
  43. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/quickstart.md +0 -0
  44. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/api.md +0 -0
  45. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/errors.md +0 -0
  46. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/lua-vs-python.md +0 -0
  47. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/reference/supported-subset.md +0 -0
  48. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/docs/stylesheets/extra.css +0 -0
  49. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/release-please-config.json +0 -0
  50. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/scripts/generate_commands.py +0 -0
  51. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/__main__.py +0 -0
  52. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_commands.py +0 -0
  53. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_compile.py +0 -0
  54. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_lua.py +0 -0
  55. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_runtime.py +0 -0
  56. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/_script.py +0 -0
  57. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/codegen.py +0 -0
  58. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/errors.py +0 -0
  59. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/src/redis_lua_py/py.typed +0 -0
  60. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/codegen_scripts.py +0 -0
  61. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/conftest.py +0 -0
  62. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/module_with_client.py +0 -0
  63. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/module_without_import.py +0 -0
  64. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_binary.py +0 -0
  65. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_binding.py +0 -0
  66. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_codegen.py +0 -0
  67. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_commands.py +0 -0
  68. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_compile.py +0 -0
  69. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_constants.py +0 -0
  70. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_control_flow.py +0 -0
  71. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_errors.py +0 -0
  72. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_execute.py +0 -0
  73. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_mistranslations.py +0 -0
  74. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_namespace.py +0 -0
  75. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_semantics.py +0 -0
  76. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_strings_and_indexing.py +0 -0
  77. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_table_stakes.py +0 -0
  78. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/tests/test_typing.py +0 -0
  79. {redis_lua_py-0.5.0 → redis_lua_py-0.5.1}/uv.lock +0 -0
  80. {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
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.5.1"
3
+ }
@@ -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.0
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/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "redis-lua-py"
3
- version = "0.5.0"
3
+ version = "0.5.1"
4
4
  description = "Write Redis Lua scripts as real Python functions, not strings."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -67,7 +67,7 @@ __all__ = [
67
67
  "script",
68
68
  ]
69
69
 
70
- __version__ = "0.5.0" # x-release-please-version
70
+ __version__ = "0.5.1" # x-release-please-version
71
71
 
72
72
 
73
73
  @overload
@@ -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 = getattr(client, "function_load", None)
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:
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.5.0"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes