ovld 0.5.3__tar.gz → 0.5.5__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 (69) hide show
  1. {ovld-0.5.3 → ovld-0.5.5}/.github/workflows/python-package.yml +2 -0
  2. {ovld-0.5.3 → ovld-0.5.5}/PKG-INFO +10 -10
  3. {ovld-0.5.3 → ovld-0.5.5}/README.md +9 -9
  4. ovld-0.5.5/benchmarks/conftest.py +37 -0
  5. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_add.py +2 -2
  6. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_calc.py +2 -2
  7. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_multer.py +2 -2
  8. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_regexp.py +3 -3
  9. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_trivial.py +1 -1
  10. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_tweaknum.py +2 -2
  11. {ovld-0.5.3 → ovld-0.5.5}/docs/compare.md +12 -12
  12. {ovld-0.5.3 → ovld-0.5.5}/pyproject.toml +1 -1
  13. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/codegen.py +18 -7
  14. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/utils.py +5 -1
  15. ovld-0.5.5/src/ovld/version.py +1 -0
  16. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen.py +6 -0
  17. {ovld-0.5.3 → ovld-0.5.5}/tests/test_ovld.py +8 -0
  18. {ovld-0.5.3 → ovld-0.5.5}/uv.lock +47 -20
  19. ovld-0.5.3/src/ovld/version.py +0 -1
  20. {ovld-0.5.3 → ovld-0.5.5}/.github/workflows/publish.yml +0 -0
  21. {ovld-0.5.3 → ovld-0.5.5}/.gitignore +0 -0
  22. {ovld-0.5.3 → ovld-0.5.5}/.python-version +0 -0
  23. {ovld-0.5.3 → ovld-0.5.5}/.readthedocs.yaml +0 -0
  24. {ovld-0.5.3 → ovld-0.5.5}/LICENSE +0 -0
  25. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/__init__.py +0 -0
  26. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/common.py +0 -0
  27. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_ast.py +0 -0
  28. {ovld-0.5.3 → ovld-0.5.5}/benchmarks/test_fib.py +0 -0
  29. {ovld-0.5.3 → ovld-0.5.5}/docs/codegen.md +0 -0
  30. {ovld-0.5.3 → ovld-0.5.5}/docs/dependent.md +0 -0
  31. {ovld-0.5.3 → ovld-0.5.5}/docs/features.md +0 -0
  32. {ovld-0.5.3 → ovld-0.5.5}/docs/index.md +0 -0
  33. {ovld-0.5.3 → ovld-0.5.5}/docs/medley.md +0 -0
  34. {ovld-0.5.3 → ovld-0.5.5}/docs/types.md +0 -0
  35. {ovld-0.5.3 → ovld-0.5.5}/docs/usage.md +0 -0
  36. {ovld-0.5.3 → ovld-0.5.5}/mkdocs.yml +0 -0
  37. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/__init__.py +0 -0
  38. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/abc.py +0 -0
  39. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/core.py +0 -0
  40. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/dependent.py +0 -0
  41. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/medley.py +0 -0
  42. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/mro.py +0 -0
  43. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/py.typed +0 -0
  44. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/recode.py +0 -0
  45. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/signatures.py +0 -0
  46. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/typemap.py +0 -0
  47. {ovld-0.5.3 → ovld-0.5.5}/src/ovld/types.py +0 -0
  48. {ovld-0.5.3 → ovld-0.5.5}/tests/__init__.py +0 -0
  49. {ovld-0.5.3 → ovld-0.5.5}/tests/modules/gingerbread.py +0 -0
  50. {ovld-0.5.3 → ovld-0.5.5}/tests/test_abc.py +0 -0
  51. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen/test_dataclass_gen.txt +0 -0
  52. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen/test_method.txt +0 -0
  53. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen/test_method_metaclass.txt +0 -0
  54. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen/test_method_per_instance.txt +0 -0
  55. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen/test_simple.txt +0 -0
  56. {ovld-0.5.3 → ovld-0.5.5}/tests/test_codegen/test_variant_generation.txt +0 -0
  57. {ovld-0.5.3 → ovld-0.5.5}/tests/test_dependent.py +0 -0
  58. {ovld-0.5.3 → ovld-0.5.5}/tests/test_examples.py +0 -0
  59. {ovld-0.5.3 → ovld-0.5.5}/tests/test_global.py +0 -0
  60. {ovld-0.5.3 → ovld-0.5.5}/tests/test_medley.py +0 -0
  61. {ovld-0.5.3 → ovld-0.5.5}/tests/test_mro.py +0 -0
  62. {ovld-0.5.3 → ovld-0.5.5}/tests/test_ovld/test_display.txt +0 -0
  63. {ovld-0.5.3 → ovld-0.5.5}/tests/test_ovld/test_display_more.txt +0 -0
  64. {ovld-0.5.3 → ovld-0.5.5}/tests/test_ovld/test_doc.txt +0 -0
  65. {ovld-0.5.3 → ovld-0.5.5}/tests/test_ovld/test_doc2.txt +0 -0
  66. {ovld-0.5.3 → ovld-0.5.5}/tests/test_ovld/test_method_doc.txt +0 -0
  67. {ovld-0.5.3 → ovld-0.5.5}/tests/test_typemap.py +0 -0
  68. {ovld-0.5.3 → ovld-0.5.5}/tests/test_types.py +0 -0
  69. {ovld-0.5.3 → ovld-0.5.5}/tests/test_utils.py +0 -0
@@ -39,6 +39,8 @@ jobs:
39
39
  coverage: false
40
40
  - python: '3.11'
41
41
  coverage: false
42
+ - python: 'pypy3.11'
43
+ coverage: false
42
44
  - python: '3.12'
43
45
  coverage: false
44
46
  - python: '3.13'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ovld
3
- Version: 0.5.3
3
+ Version: 0.5.5
4
4
  Summary: Overloading Python functions
5
5
  Project-URL: Homepage, https://ovld.readthedocs.io/en/latest/
6
6
  Project-URL: Documentation, https://ovld.readthedocs.io/en/latest/
@@ -251,13 +251,13 @@ f3 = Total(punctuation="!", factor=3)
251
251
 
252
252
  Time relative to the fastest implementation (1.00) (lower is better).
253
253
 
254
- | Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch) | [runtype](https://github.com/erezsh/runtype) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
254
+ | Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch/) | [runtype](https://github.com/erezsh/runtype) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
255
255
  | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
256
- |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|1.91|
257
- |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|7.32|
258
- |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|x|
259
- |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|1.66|
260
- |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|
261
- |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|
262
- |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|
263
- |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|
256
+ |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.56|1.00|3.38|4.92|2.00|2.38|2.15|
257
+ |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.22|1.00|11.06|4.67|9.22|2.24|3.92|
258
+ |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.27|1.00|3.61|4.93|2.24|2.62|x|
259
+ |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.01|1.00|22.98|2.72|1.52|1.70|1.57|
260
+ |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.28|57.86|29.79|x|x|x|
261
+ |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|2.28|22.71|x|x|x|x|
262
+ |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.39|403.38|114.69|x|x|x|
263
+ |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|1.86|x|x|x|x|x||[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|1.86|x|x|x|x|x|
@@ -238,13 +238,13 @@ f3 = Total(punctuation="!", factor=3)
238
238
 
239
239
  Time relative to the fastest implementation (1.00) (lower is better).
240
240
 
241
- | Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch) | [runtype](https://github.com/erezsh/runtype) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
241
+ | Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch/) | [runtype](https://github.com/erezsh/runtype) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
242
242
  | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
243
- |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|1.91|
244
- |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|7.32|
245
- |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|x|
246
- |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|1.66|
247
- |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|
248
- |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|
249
- |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|
250
- |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|
243
+ |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.56|1.00|3.38|4.92|2.00|2.38|2.15|
244
+ |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.22|1.00|11.06|4.67|9.22|2.24|3.92|
245
+ |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.27|1.00|3.61|4.93|2.24|2.62|x|
246
+ |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.01|1.00|22.98|2.72|1.52|1.70|1.57|
247
+ |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.28|57.86|29.79|x|x|x|
248
+ |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|2.28|22.71|x|x|x|x|
249
+ |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.39|403.38|114.69|x|x|x|
250
+ |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|1.86|x|x|x|x|x||[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|1.86|x|x|x|x|x|
@@ -0,0 +1,37 @@
1
+ import json
2
+
3
+ from pytest_benchmark import utils
4
+
5
+ from ovld import ovld, recurse
6
+
7
+
8
+ @ovld
9
+ def _cleanup(obj: str | int | float):
10
+ return obj
11
+
12
+
13
+ @ovld
14
+ def _cleanup(obj: list):
15
+ return [recurse(x) for x in obj]
16
+
17
+
18
+ @ovld
19
+ def _cleanup(obj: dict):
20
+ if type(obj) is not dict:
21
+ return f"UNSERIALIZABLE[{obj}]"
22
+ return {k: recurse(v) for k, v in obj.items()}
23
+
24
+
25
+ @ovld
26
+ def _cleanup(obj: object):
27
+ return f"UNSERIALIZABLE[{obj}]"
28
+
29
+
30
+ def safer_dumps(obj, **kwargs):
31
+ # multimethod is not safe for dump of benchmarks because it's a subclass of dict
32
+ # with non-str keys and the json serialization just craps out.
33
+ return json.dumps(_cleanup(obj), **kwargs)
34
+
35
+
36
+ utils._cleanup = _cleanup
37
+ utils.safe_dumps.__code__ = safer_dumps.__code__
@@ -85,8 +85,8 @@ C = {"xs": list(range(10, 110, 2)), "ys": ("ox", (13, 13))}
85
85
  multimethod=make_add(multimethod_dispatch),
86
86
  multipledispatch=make_add(multipledispatch_dispatch),
87
87
  runtype=make_add(runtype_dispatch),
88
- isinstance=add_isinstance,
89
- match=add_match,
88
+ custom__isinstance=add_isinstance,
89
+ custom__match=add_match,
90
90
  )
91
91
  def test_add(fn, benchmark):
92
92
  result = benchmark(fn, A, B)
@@ -135,8 +135,8 @@ expected_result = 19
135
135
  ovld=make_calc(ovld_dispatch),
136
136
  plum=make_calc(plum_dispatch),
137
137
  multimethod=make_calc(multimethod_dispatch),
138
- custom_dict=calc_dict,
139
- custom_match=calc_match,
138
+ custom__dict=calc_dict,
139
+ custom__match=calc_match,
140
140
  )
141
141
  def test_calc(fn, benchmark):
142
142
  result = benchmark(fn, expr)
@@ -143,13 +143,13 @@ C = {"xs": list(range(0, 150, 3)), "ys": ("ooo", (18, 21))}
143
143
  @pytest.mark.benchmark(group="multer")
144
144
  @with_functions(
145
145
  ovld=make_multer(ovld_dispatch),
146
- recurse=OvldRecurseMulter,
146
+ ovld__recurse=OvldRecurseMulter,
147
147
  plum=make_multer(plum_dispatch),
148
148
  multimethod=make_multer(multimethod_dispatch),
149
149
  singledispatch=SingleDispatchMulter,
150
150
  multipledispatch=MultipleDispatchMulter,
151
151
  runtype=make_multer(runtype_dispatch),
152
- isinstance=IsinstanceMulter,
152
+ custom=IsinstanceMulter,
153
153
  )
154
154
  def test_multer(fn, benchmark):
155
155
  result = benchmark(fn(3), A)
@@ -82,9 +82,9 @@ def regexp_compiled_nonexclusive(x):
82
82
  @with_functions(
83
83
  ovld=make_regexp(ovld_dispatch),
84
84
  plum=make_regexp(plum_dispatch),
85
- custom_search=regexp_search,
86
- custom_compiled=regexp_compiled,
87
- custom_compiled_nx=regexp_compiled_nonexclusive,
85
+ custom__search=regexp_search,
86
+ custom__compiled=regexp_compiled,
87
+ custom__compiled_nx=regexp_compiled_nonexclusive,
88
88
  )
89
89
  def test_regexp(fn, benchmark):
90
90
  def run():
@@ -107,7 +107,7 @@ def trivial_isinstance(x):
107
107
  multipledispatch=make_trivial(multipledispatch_dispatch),
108
108
  runtype=make_trivial(runtype_dispatch),
109
109
  singledispatch=make_trivial(singledispatch_dispatch),
110
- custom_isinstance=trivial_isinstance,
110
+ custom__isinstance=trivial_isinstance,
111
111
  )
112
112
  def test_trivial(fn, benchmark):
113
113
  def run():
@@ -66,8 +66,8 @@ def tweaknum_match(n, **kwargs):
66
66
  @pytest.mark.benchmark(group="tweaknum")
67
67
  @with_functions(
68
68
  ovld=make_tweaknum(ovld_dispatch),
69
- custom_ifs=tweaknum_ifs,
70
- custom_match=tweaknum_match,
69
+ custom__ifs=tweaknum_ifs,
70
+ custom__match=tweaknum_match,
71
71
  )
72
72
  def test_tweaknum(fn, benchmark):
73
73
  def run():
@@ -3,7 +3,7 @@
3
3
 
4
4
  ## Unique features
5
5
 
6
- Current as of October 2024: I have investigated and benchmarked six other multiple/single dispatch libraries. Performance-wise, `ovld` is faster than all of them, ranging from 1.5x to 100x less overhead. Feature-wise, `ovld` is among the most featureful. Some features I could not find elsewhere:
6
+ Current as of May 2025: I have investigated and benchmarked five other multiple/single dispatch libraries. Performance-wise, `ovld` is faster than all of them, ranging from 1.5x to 100x less overhead. Feature-wise, `ovld` is among the most featureful. Some features I could not find elsewhere:
7
7
 
8
8
  * Support for [keyword arguments](usage.md#keyword-arguments).
9
9
  * [Variants](usage.md#variants), especially working with recursion.
@@ -18,7 +18,6 @@ Current as of October 2024: I have investigated and benchmarked six other multip
18
18
  * [**multimethod**](https://github.com/coady/multimethod): Also pretty featureful. Performs a bit worse than plum in simple cases, but better in more complicated cases.
19
19
  * [**multipledispatch**](https://github.com/mrocklin/multipledispatch/): Fair performance, interface is a bit dated, does not support dependent types.
20
20
  * [**runtype**](https://github.com/erezsh/runtype): Fair performance. Runtype supports Literal in theory, but it unfortunately bugged out on the calc and fib benchmarks.
21
- * [**fastcore**](https://github.com/fastai/fastcore): Somewhat limited (seems like it only dispatches on two arguments at most), and for a library with "fast" in its name, I must say it is impressively slow.
22
21
  * [**singledispatch**](https://docs.python.org/3/library/functools.html#functools.singledispatch): Comes native in Python, but only supports dispatch on a single argument.
23
22
 
24
23
 
@@ -38,20 +37,21 @@ Applicable libraries were tested on the following problems:
38
37
 
39
38
  ## Results
40
39
 
41
- Time relative to the fastest implementation (1.00) (lower is better). Python version: 3.12.4
40
+ Time relative to the fastest implementation (1.00) (lower is better). Python version: 3.13.0
42
41
 
43
42
  The **custom** column represents custom implementations using isinstance, match, a dispatch dict, etc. They are usually the fastest, but that should not be surprising. ovld's performance ranges from 1.5x faster to 3.3x slower.
44
43
 
45
- | Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch) | [runtype](https://github.com/erezsh/runtype) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
44
+ | Benchmark | custom | [ovld](https://github.com/breuleux/ovld) | [plum](https://github.com/beartype/plum) | [multim](https://github.com/coady/multimethod) | [multid](https://github.com/mrocklin/multipledispatch/) | [runtype](https://github.com/erezsh/runtype) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
46
45
  | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
47
- |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|1.91|
48
- |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|7.32|
49
- |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|x|
50
- |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|1.66|
51
- |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|
52
- |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|
53
- |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|
54
- |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|
46
+ |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.56|1.00|3.38|4.92|2.00|2.38|2.15|
47
+ |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.22|1.00|11.06|4.67|9.22|2.24|3.92|
48
+ |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.27|1.00|3.61|4.93|2.24|2.62|x|
49
+ |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.01|1.00|22.98|2.72|1.52|1.70|1.57|
50
+ |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.28|57.86|29.79|x|x|x|
51
+ |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|2.28|22.71|x|x|x|x|
52
+ |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.39|403.38|114.69|x|x|x|
53
+ |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|1.86|x|x|x|x|x||[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|1.86|x|x|x|x|x|
54
+
55
55
 
56
56
  ## Comments
57
57
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ovld"
3
- version = "0.5.3"
3
+ version = "0.5.5"
4
4
  description = "Overloading Python functions"
5
5
  authors = [
6
6
  { name = "Olivier Breuleux", email = "breuleux@gmail.com" }
@@ -45,13 +45,22 @@ def transfer_function(
45
45
  globals=MISSING,
46
46
  name=MISSING,
47
47
  ):
48
- new_fn = FunctionType(
49
- argdefs=func.__defaults__ if argdefs is MISSING else argdefs,
50
- closure=func.__closure__ if closure is MISSING else closure,
51
- code=func.__code__ if code is MISSING else code,
52
- globals=func.__globals__ if globals is MISSING else globals,
53
- name=func.__name__ if name is MISSING else name,
54
- )
48
+ closure = func.__closure__ if closure is MISSING else closure
49
+ if closure:
50
+ new_fn = FunctionType(
51
+ argdefs=func.__defaults__ if argdefs is MISSING else argdefs,
52
+ closure=func.__closure__ if closure is MISSING else closure,
53
+ code=func.__code__ if code is MISSING else code,
54
+ globals=func.__globals__ if globals is MISSING else globals,
55
+ name=func.__name__ if name is MISSING else name,
56
+ )
57
+ else:
58
+ new_fn = FunctionType(
59
+ argdefs=func.__defaults__ if argdefs is MISSING else argdefs,
60
+ code=func.__code__ if code is MISSING else code,
61
+ globals=func.__globals__ if globals is MISSING else globals,
62
+ name=func.__name__ if name is MISSING else name,
63
+ )
55
64
  new_fn.__kwdefaults__ = func.__kwdefaults__
56
65
  new_fn.__annotations__ = func.__annotations__
57
66
  new_fn.__dict__.update(func.__dict__)
@@ -161,6 +170,8 @@ class Code:
161
170
  elif isinstance(v, (list, tuple)):
162
171
  if any(isinstance(x, Code) for x in v):
163
172
  return [_rename_step(x) for x in v]
173
+ else:
174
+ return v
164
175
  else:
165
176
  return v
166
177
 
@@ -1,10 +1,14 @@
1
1
  """Miscellaneous utilities."""
2
2
 
3
+ import builtins
3
4
  import functools
4
5
  import re
5
6
  import typing
6
7
  from itertools import count
7
8
 
9
+ _builtins_dict = vars(builtins)
10
+
11
+
8
12
  try:
9
13
  from types import UnionType
10
14
 
@@ -152,7 +156,7 @@ class NameDatabase:
152
156
  i = 1
153
157
  name = desired_name
154
158
  while name in self.registered or (
155
- name in __builtins__ and __builtins__[name] != value
159
+ name in _builtins_dict and _builtins_dict[name] != value
156
160
  ):
157
161
  name = f"{desired_name}{i}"
158
162
  i += 1
@@ -0,0 +1 @@
1
+ version = "0.5.5"
@@ -231,6 +231,11 @@ class TwoPoints:
231
231
  b: Point
232
232
 
233
233
 
234
+ @dataclass
235
+ class Empty:
236
+ pass
237
+
238
+
234
239
  @pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10+ for UnionType")
235
240
  def test_inlining_generator():
236
241
  from types import UnionType
@@ -289,6 +294,7 @@ def test_inlining_generator():
289
294
  assert f(TwoPoints, TwoPoints(Point(1, 2), Point(7, 8))) == TwoPoints(
290
295
  Point(2, 3), Point(8, 9)
291
296
  )
297
+ assert f(Empty, Empty()) == Empty()
292
298
 
293
299
 
294
300
  def test_scoped_subcodes():
@@ -1160,6 +1160,10 @@ def test_unregister():
1160
1160
  f([-2, -1, 0, 1, 2, 3])
1161
1161
 
1162
1162
 
1163
+ @pytest.mark.xfail(
1164
+ condition="platform.python_implementation() == 'PyPy'",
1165
+ reason="codefind dependency fails here",
1166
+ )
1163
1167
  def test_conform():
1164
1168
  @ovld
1165
1169
  def f(xs: list):
@@ -1182,6 +1186,10 @@ def test_conform():
1182
1186
  f([-2, -1, 0, 1, 2, 3])
1183
1187
 
1184
1188
 
1189
+ @pytest.mark.xfail(
1190
+ condition="platform.python_implementation() == 'PyPy'",
1191
+ reason="codefind dependency fails here",
1192
+ )
1185
1193
  def test_conform_2():
1186
1194
  @ovld
1187
1195
  def f(xs: list):
@@ -1,5 +1,10 @@
1
1
  version = 1
2
+ revision = 1
2
3
  requires-python = ">=3.9"
4
+ resolution-markers = [
5
+ "python_full_version >= '3.10'",
6
+ "python_full_version < '3.10'",
7
+ ]
3
8
 
4
9
  [[package]]
5
10
  name = "beartype"
@@ -14,14 +19,32 @@ wheels = [
14
19
  name = "click"
15
20
  version = "8.1.8"
16
21
  source = { registry = "https://pypi.org/simple" }
22
+ resolution-markers = [
23
+ "python_full_version < '3.10'",
24
+ ]
17
25
  dependencies = [
18
- { name = "colorama", marker = "platform_system == 'Windows'" },
26
+ { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
19
27
  ]
20
28
  sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
21
29
  wheels = [
22
30
  { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 },
23
31
  ]
24
32
 
33
+ [[package]]
34
+ name = "click"
35
+ version = "8.2.0"
36
+ source = { registry = "https://pypi.org/simple" }
37
+ resolution-markers = [
38
+ "python_full_version >= '3.10'",
39
+ ]
40
+ dependencies = [
41
+ { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" },
42
+ ]
43
+ sdist = { url = "https://files.pythonhosted.org/packages/cd/0f/62ca20172d4f87d93cf89665fbaedcd560ac48b465bd1d92bfc7ea6b0a41/click-8.2.0.tar.gz", hash = "sha256:f5452aeddd9988eefa20f90f05ab66f17fce1ee2a36907fd30b05bbb5953814d", size = 235857 }
44
+ wheels = [
45
+ { url = "https://files.pythonhosted.org/packages/a2/58/1f37bf81e3c689cc74ffa42102fa8915b59085f54a6e4a80bc6265c0f6bf/click-8.2.0-py3-none-any.whl", hash = "sha256:6b303f0b2aa85f1cb4e5303078fadcbcd4e476f114fab9b5007005711839325c", size = 102156 },
46
+ ]
47
+
25
48
  [[package]]
26
49
  name = "codefind"
27
50
  version = "0.1.7"
@@ -117,11 +140,14 @@ toml = [
117
140
 
118
141
  [[package]]
119
142
  name = "exceptiongroup"
120
- version = "1.2.2"
143
+ version = "1.3.0"
121
144
  source = { registry = "https://pypi.org/simple" }
122
- sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
145
+ dependencies = [
146
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
147
+ ]
148
+ sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749 }
123
149
  wheels = [
124
- { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
150
+ { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674 },
125
151
  ]
126
152
 
127
153
  [[package]]
@@ -138,14 +164,14 @@ wheels = [
138
164
 
139
165
  [[package]]
140
166
  name = "importlib-metadata"
141
- version = "8.6.1"
167
+ version = "8.7.0"
142
168
  source = { registry = "https://pypi.org/simple" }
143
169
  dependencies = [
144
170
  { name = "zipp" },
145
171
  ]
146
- sdist = { url = "https://files.pythonhosted.org/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580", size = 55767 }
172
+ sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641 }
147
173
  wheels = [
148
- { url = "https://files.pythonhosted.org/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e", size = 26971 },
174
+ { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656 },
149
175
  ]
150
176
 
151
177
  [[package]]
@@ -284,8 +310,9 @@ name = "mkdocs"
284
310
  version = "1.6.1"
285
311
  source = { registry = "https://pypi.org/simple" }
286
312
  dependencies = [
287
- { name = "click" },
288
- { name = "colorama", marker = "platform_system == 'Windows'" },
313
+ { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
314
+ { name = "click", version = "8.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
315
+ { name = "colorama", marker = "sys_platform == 'win32'" },
289
316
  { name = "ghp-import" },
290
317
  { name = "importlib-metadata", marker = "python_full_version < '3.10'" },
291
318
  { name = "jinja2" },
@@ -339,7 +366,7 @@ wheels = [
339
366
 
340
367
  [[package]]
341
368
  name = "ovld"
342
- version = "0.5.0"
369
+ version = "0.5.4"
343
370
  source = { editable = "." }
344
371
 
345
372
  [package.dev-dependencies]
@@ -365,7 +392,7 @@ benchmark = [
365
392
  { name = "multimethod", specifier = ">=1.12" },
366
393
  { name = "multipledispatch", specifier = ">=1.0.0" },
367
394
  { name = "plum-dispatch", specifier = ">=2.5.2" },
368
- { name = "runtype", specifier = ">=0.5.0" },
395
+ { name = "runtype", specifier = ">=0.5.3" },
369
396
  ]
370
397
  dev = [
371
398
  { name = "codefind", specifier = "~=0.1.6" },
@@ -378,11 +405,11 @@ dev = [
378
405
 
379
406
  [[package]]
380
407
  name = "packaging"
381
- version = "24.2"
408
+ version = "25.0"
382
409
  source = { registry = "https://pypi.org/simple" }
383
- sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
410
+ sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 }
384
411
  wheels = [
385
- { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
412
+ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 },
386
413
  ]
387
414
 
388
415
  [[package]]
@@ -396,11 +423,11 @@ wheels = [
396
423
 
397
424
  [[package]]
398
425
  name = "platformdirs"
399
- version = "4.3.7"
426
+ version = "4.3.8"
400
427
  source = { registry = "https://pypi.org/simple" }
401
- sdist = { url = "https://files.pythonhosted.org/packages/b6/2d/7d512a3913d60623e7eb945c6d1b4f0bddf1d0b7ada5225274c87e5b53d1/platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351", size = 21291 }
428
+ sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362 }
402
429
  wheels = [
403
- { url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499 },
430
+ { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567 },
404
431
  ]
405
432
 
406
433
  [[package]]
@@ -580,14 +607,14 @@ wheels = [
580
607
 
581
608
  [[package]]
582
609
  name = "pyyaml-env-tag"
583
- version = "0.1"
610
+ version = "1.1"
584
611
  source = { registry = "https://pypi.org/simple" }
585
612
  dependencies = [
586
613
  { name = "pyyaml" },
587
614
  ]
588
- sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 }
615
+ sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737 }
589
616
  wheels = [
590
- { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 },
617
+ { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722 },
591
618
  ]
592
619
 
593
620
  [[package]]
@@ -1 +0,0 @@
1
- version = "0.5.3"
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