ovld 0.4.4__tar.gz → 0.4.6__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 (159) hide show
  1. {ovld-0.4.4 → ovld-0.4.6}/.github/workflows/python-package.yml +3 -0
  2. ovld-0.4.6/.python-version +1 -0
  3. {ovld-0.4.4 → ovld-0.4.6}/PKG-INFO +11 -10
  4. {ovld-0.4.4 → ovld-0.4.6}/README.md +10 -9
  5. ovld-0.4.6/beary.py +120 -0
  6. {ovld-0.4.4 → ovld-0.4.6}/bench.py +32 -0
  7. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_calc.py +1 -1
  8. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_multer.py +1 -1
  9. ovld-0.4.6/benchmarks/test_regexp.py +96 -0
  10. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_tuple.py +3 -0
  11. ovld-0.4.6/benchmarks/test_typechecking.py +160 -0
  12. {ovld-0.4.4 → ovld-0.4.6}/docs/compare.md +14 -13
  13. {ovld-0.4.4 → ovld-0.4.6}/gen_comparison_table.py +12 -2
  14. ovld-0.4.6/gen_typecheck_table.py +60 -0
  15. ovld-0.4.6/ichk.py +39 -0
  16. ovld-0.4.6/kraken.py +30 -0
  17. {ovld-0.4.4 → ovld-0.4.6}/pyproject.toml +1 -1
  18. {ovld-0.4.4 → ovld-0.4.6}/reddit.md +7 -6
  19. ovld-0.4.6/refun.py +16 -0
  20. ovld-0.4.6/reper.py +6 -0
  21. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/__init__.py +0 -2
  22. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/core.py +186 -191
  23. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/dependent.py +59 -26
  24. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/mro.py +5 -0
  25. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/recode.py +64 -75
  26. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/types.py +11 -7
  27. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/utils.py +47 -0
  28. ovld-0.4.6/src/ovld/version.py +1 -0
  29. ovld-0.4.6/tests/__init__.py +0 -0
  30. {ovld-0.4.4 → ovld-0.4.6}/tests/test_dependent.py +4 -0
  31. {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_method_doc.txt +1 -1
  32. {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld.py +34 -43
  33. {ovld-0.4.4 → ovld-0.4.6}/typo.py +13 -2
  34. {ovld-0.4.4 → ovld-0.4.6}/uv.lock +1 -1
  35. ovld-0.4.4/.python-version +0 -1
  36. ovld-0.4.4/beary.py +0 -30
  37. ovld-0.4.4/src/ovld/version.py +0 -1
  38. {ovld-0.4.4 → ovld-0.4.6}/.bsync-snap-20220324145902.852076 +0 -0
  39. {ovld-0.4.4 → ovld-0.4.6}/.bsync-snap-20240916114026.355340 +0 -0
  40. {ovld-0.4.4 → ovld-0.4.6}/.envrc +0 -0
  41. {ovld-0.4.4 → ovld-0.4.6}/.gitignore +0 -0
  42. {ovld-0.4.4 → ovld-0.4.6}/.readthedocs.yaml +0 -0
  43. {ovld-0.4.4 → ovld-0.4.6}/LICENSE +0 -0
  44. {ovld-0.4.4 → ovld-0.4.6}/add.py +0 -0
  45. {ovld-0.4.4 → ovld-0.4.6}/anal.py +0 -0
  46. {ovld-0.4.4 → ovld-0.4.6}/bench/requirements.txt +0 -0
  47. {ovld-0.4.4 → ovld-0.4.6}/benchd.py +0 -0
  48. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/__init__.py +0 -0
  49. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/common.py +0 -0
  50. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_add.py +0 -0
  51. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_ast.py +0 -0
  52. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_fib.py +0 -0
  53. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_trivial.py +0 -0
  54. {ovld-0.4.4 → ovld-0.4.6}/benchmarks/test_tweaknum.py +0 -0
  55. {ovld-0.4.4 → ovld-0.4.6}/cloz.py +0 -0
  56. {ovld-0.4.4 → ovld-0.4.6}/coco.py +0 -0
  57. {ovld-0.4.4 → ovld-0.4.6}/data.py +0 -0
  58. {ovld-0.4.4 → ovld-0.4.6}/didi.py +0 -0
  59. {ovld-0.4.4 → ovld-0.4.6}/docs/dependent.md +0 -0
  60. {ovld-0.4.4 → ovld-0.4.6}/docs/features.md +0 -0
  61. {ovld-0.4.4 → ovld-0.4.6}/docs/index.md +0 -0
  62. {ovld-0.4.4 → ovld-0.4.6}/docs/types.md +0 -0
  63. {ovld-0.4.4 → ovld-0.4.6}/docs/usage.md +0 -0
  64. {ovld-0.4.4 → ovld-0.4.6}/doo.py +0 -0
  65. {ovld-0.4.4 → ovld-0.4.6}/edges.py +0 -0
  66. {ovld-0.4.4 → ovld-0.4.6}/explore.py +0 -0
  67. {ovld-0.4.4 → ovld-0.4.6}/facto.py +0 -0
  68. {ovld-0.4.4 → ovld-0.4.6}/gentest.py +0 -0
  69. {ovld-0.4.4 → ovld-0.4.6}/hello.py +0 -0
  70. {ovld-0.4.4 → ovld-0.4.6}/hntest.py +0 -0
  71. {ovld-0.4.4 → ovld-0.4.6}/klos.py +0 -0
  72. {ovld-0.4.4 → ovld-0.4.6}/mkdocs.yml +0 -0
  73. {ovld-0.4.4 → ovld-0.4.6}/nxt.py +0 -0
  74. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.0-py3-none-any.whl +0 -0
  75. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.0.tar.gz +0 -0
  76. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.1-py3-none-any.whl +0 -0
  77. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.1.tar.gz +0 -0
  78. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.2-py3-none-any.whl +0 -0
  79. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.2.tar.gz +0 -0
  80. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.3-py3-none-any.whl +0 -0
  81. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.3.tar.gz +0 -0
  82. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.4-py3-none-any.whl +0 -0
  83. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.4.tar.gz +0 -0
  84. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.5-py3-none-any.whl +0 -0
  85. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.5.tar.gz +0 -0
  86. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.6-py3-none-any.whl +0 -0
  87. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.6.tar.gz +0 -0
  88. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.7-py3-none-any.whl +0 -0
  89. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.7.tar.gz +0 -0
  90. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.8-py3-none-any.whl +0 -0
  91. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.8.tar.gz +0 -0
  92. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.9-py3-none-any.whl +0 -0
  93. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.1.9.tar.gz +0 -0
  94. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.0-py3-none-any.whl +0 -0
  95. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.0.tar.gz +0 -0
  96. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.1-py3-none-any.whl +0 -0
  97. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.1.tar.gz +0 -0
  98. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.10-py3-none-any.whl +0 -0
  99. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.10.tar.gz +0 -0
  100. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.11-py3-none-any.whl +0 -0
  101. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.11.tar.gz +0 -0
  102. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.2-py3-none-any.whl +0 -0
  103. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.2.tar.gz +0 -0
  104. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.3-py3-none-any.whl +0 -0
  105. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.3.tar.gz +0 -0
  106. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.4-py3-none-any.whl +0 -0
  107. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.4.tar.gz +0 -0
  108. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.5-py3-none-any.whl +0 -0
  109. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.5.tar.gz +0 -0
  110. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.6-py3-none-any.whl +0 -0
  111. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.6.tar.gz +0 -0
  112. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.7-py3-none-any.whl +0 -0
  113. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.7.tar.gz +0 -0
  114. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.8-py3-none-any.whl +0 -0
  115. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.8.tar.gz +0 -0
  116. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.9-py3-none-any.whl +0 -0
  117. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.2.9.tar.gz +0 -0
  118. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.0-py3-none-any.whl +0 -0
  119. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.0.tar.gz +0 -0
  120. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.1-py3-none-any.whl +0 -0
  121. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.1.tar.gz +0 -0
  122. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.2-py3-none-any.whl +0 -0
  123. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.2.tar.gz +0 -0
  124. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.3-py3-none-any.whl +0 -0
  125. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.3.tar.gz +0 -0
  126. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.4-py3-none-any.whl +0 -0
  127. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.4.tar.gz +0 -0
  128. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.5-py3-none-any.whl +0 -0
  129. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.5.tar.gz +0 -0
  130. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.8-py3-none-any.whl +0 -0
  131. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.8.tar.gz +0 -0
  132. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.9-py3-none-any.whl +0 -0
  133. {ovld-0.4.4 → ovld-0.4.6}/old-dist/ovld-0.3.9.tar.gz +0 -0
  134. {ovld-0.4.4 → ovld-0.4.6}/one_two_three.py +0 -0
  135. {ovld-0.4.4 → ovld-0.4.6}/outoftheway.toml +0 -0
  136. {ovld-0.4.4 → ovld-0.4.6}/reddit.py +0 -0
  137. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/abc.py +0 -0
  138. /ovld-0.4.4/tests/__init__.py → /ovld-0.4.6/src/ovld/py.typed +0 -0
  139. {ovld-0.4.4 → ovld-0.4.6}/src/ovld/typemap.py +0 -0
  140. {ovld-0.4.4 → ovld-0.4.6}/stuff.md +0 -0
  141. {ovld-0.4.4 → ovld-0.4.6}/tb.py +0 -0
  142. {ovld-0.4.4 → ovld-0.4.6}/tensor.py +0 -0
  143. {ovld-0.4.4 → ovld-0.4.6}/tests/modules/gingerbread.py +0 -0
  144. {ovld-0.4.4 → ovld-0.4.6}/tests/test_abc.py +0 -0
  145. {ovld-0.4.4 → ovld-0.4.6}/tests/test_examples.py +0 -0
  146. {ovld-0.4.4 → ovld-0.4.6}/tests/test_global.py +0 -0
  147. {ovld-0.4.4 → ovld-0.4.6}/tests/test_mro.py +0 -0
  148. {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_display.txt +0 -0
  149. {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_display_more.txt +0 -0
  150. {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_doc.txt +0 -0
  151. {ovld-0.4.4 → ovld-0.4.6}/tests/test_ovld/test_doc2.txt +0 -0
  152. {ovld-0.4.4 → ovld-0.4.6}/tests/test_typemap.py +0 -0
  153. {ovld-0.4.4 → ovld-0.4.6}/tests/test_types.py +0 -0
  154. {ovld-0.4.4 → ovld-0.4.6}/tests/test_utils.py +0 -0
  155. {ovld-0.4.4 → ovld-0.4.6}/todo.q +0 -0
  156. {ovld-0.4.4 → ovld-0.4.6}/toot.py +0 -0
  157. {ovld-0.4.4 → ovld-0.4.6}/world.yaml +0 -0
  158. {ovld-0.4.4 → ovld-0.4.6}/x.py +0 -0
  159. {ovld-0.4.4 → ovld-0.4.6}/zaggo +0 -0
@@ -40,6 +40,8 @@ jobs:
40
40
  - python: '3.11'
41
41
  coverage: false
42
42
  - python: '3.12'
43
+ coverage: false
44
+ - python: '3.13'
43
45
  coverage: true
44
46
  steps:
45
47
  - name: Check out the code
@@ -70,6 +72,7 @@ jobs:
70
72
  - python: '3.10'
71
73
  - python: '3.11'
72
74
  - python: '3.12'
75
+ - python: '3.13'
73
76
  steps:
74
77
  - name: Check out the code
75
78
  uses: actions/checkout@v3
@@ -0,0 +1 @@
1
+ 3.13
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ovld
3
- Version: 0.4.4
3
+ Version: 0.4.6
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/
@@ -201,16 +201,17 @@ assert Two().f("s") == "a string"
201
201
 
202
202
  # Benchmarks
203
203
 
204
- `ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it is 1.5x to 100x faster.
204
+ `ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it has 1.5x to 100x less overhead.
205
205
 
206
206
  Time relative to the fastest implementation (1.00) (lower is better).
207
207
 
208
- | Bench | 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) | [fastcore](https://github.com/fastai/fastcore) | [singled](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
208
+ | 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) | [fastcore](https://github.com/fastai/fastcore) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
209
209
  | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
210
- |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.14|1.00|2.53|3.64|1.61|1.86|41.31|1.54|
211
- |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.01|1.00|3.46|4.83|2.21|2.66|56.08|x|
212
- |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.00|1.06|9.79|4.11|7.19|1.89|40.37|6.34|
213
- |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.06|23.07|3.04|1.68|1.87|29.11|1.63|
214
- |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.96|80.00|43.21|x|x|x|x|
215
- |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.58|438.97|123.58|x|x|x|x|
216
- |[tweak](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.59|x|x|x|x|x|x|
210
+ |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|51.93|1.91|
211
+ |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|46.74|7.32|
212
+ |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|59.31|x|
213
+ |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|28.39|1.66|
214
+ |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|x|
215
+ |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|x|
216
+ |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|x|
217
+ |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|x|
@@ -188,16 +188,17 @@ assert Two().f("s") == "a string"
188
188
 
189
189
  # Benchmarks
190
190
 
191
- `ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it is 1.5x to 100x faster.
191
+ `ovld` is pretty fast: the overhead is comparable to `isinstance` or `match`, and only 2-3x slower when dispatching on `Literal` types. Compared to other multiple dispatch libraries, it has 1.5x to 100x less overhead.
192
192
 
193
193
  Time relative to the fastest implementation (1.00) (lower is better).
194
194
 
195
- | Bench | 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) | [fastcore](https://github.com/fastai/fastcore) | [singled](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
195
+ | 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) | [fastcore](https://github.com/fastai/fastcore) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
196
196
  | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
197
- |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.14|1.00|2.53|3.64|1.61|1.86|41.31|1.54|
198
- |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.01|1.00|3.46|4.83|2.21|2.66|56.08|x|
199
- |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.00|1.06|9.79|4.11|7.19|1.89|40.37|6.34|
200
- |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.06|23.07|3.04|1.68|1.87|29.11|1.63|
201
- |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.96|80.00|43.21|x|x|x|x|
202
- |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.58|438.97|123.58|x|x|x|x|
203
- |[tweak](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.59|x|x|x|x|x|x|
197
+ |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.45|1.00|3.32|4.63|2.04|2.41|51.93|1.91|
198
+ |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.13|1.00|11.05|4.53|8.31|2.19|46.74|7.32|
199
+ |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.08|1.00|3.73|5.21|2.37|2.79|59.31|x|
200
+ |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.08|23.14|3.09|1.68|1.91|28.39|1.66|
201
+ |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.23|54.61|29.32|x|x|x|x|
202
+ |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|x|x|x|x|
203
+ |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.30|444.31|125.77|x|x|x|x|
204
+ |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|x|
ovld-0.4.6/beary.py ADDED
@@ -0,0 +1,120 @@
1
+ import timeit
2
+ from dataclasses import dataclass
3
+
4
+ from beartype import (
5
+ BeartypeConf, # <-- this isn't your fault
6
+ beartype,
7
+ )
8
+ from beartype.claw import (
9
+ beartype_all,
10
+ ) # <-- you didn't sign up for this
11
+ from strongtyping.strong_typing import match_typing
12
+ from typeguard import typechecked
13
+
14
+ # from enforce import runtime_validation
15
+ from ovld import ovld
16
+
17
+ # from ovld.check import typecheck
18
+
19
+ beartype_all(conf=BeartypeConf())
20
+ # beartype_this_package() # <-- raise exceptions in your code
21
+ # beartype_all(conf=BeartypeConf(violation_type=UserWarning))
22
+
23
+
24
+ @beartype
25
+ def f_bear(x: int, y: int):
26
+ return x + y
27
+
28
+
29
+ @ovld
30
+ def f_ovld(x: int, y: int):
31
+ return x + y
32
+
33
+
34
+ @ovld
35
+ def f_ovld_D(x: int, y: int):
36
+ # breakpoint()
37
+ return x + y
38
+
39
+
40
+ @match_typing
41
+ def f_strong(x: int, y: int):
42
+ return x + y
43
+
44
+
45
+ @typechecked
46
+ def f_guard(x: int, y: int):
47
+ return x + y
48
+
49
+
50
+ # @runtime_validation
51
+ # def f_enforce(x: int, y: int):
52
+ # return x + y
53
+
54
+
55
+ def f_custom(x: int, y: int):
56
+ assert isinstance(x, int) and isinstance(y, int)
57
+ return x + y
58
+
59
+
60
+ class digdug(dict):
61
+ pass
62
+
63
+
64
+ def adder(x, y):
65
+ return x + y
66
+
67
+
68
+ didi = digdug({int: adder})
69
+ didi2 = digdug({(int, int): adder})
70
+
71
+
72
+ @dataclass
73
+ class Poop:
74
+ didi: dict
75
+
76
+
77
+ poo2 = Poop(didi2)
78
+
79
+
80
+ def f_custom_2(x: int, y: int):
81
+ assert didi2[type(x), type(y)]
82
+ return x + y
83
+
84
+
85
+ # def f_custom_2(x: int, y: int):
86
+ # func = didi[type(x)] and didi[type(y)]
87
+ # return func(x, y)
88
+
89
+
90
+ class Gusto:
91
+ def __init__(self, didi):
92
+ self.didi = didi
93
+ self.__name__ = "gusto"
94
+
95
+ def __call__(self, x: int, y: int):
96
+ func = self.didi[type(x), type(y)]
97
+ return func(x, y)
98
+
99
+
100
+ # f_bear(7, 8)
101
+ # f_ovld("a", 3)
102
+ # assert f_ovld(3, 4) == 7
103
+
104
+
105
+ for fn in (
106
+ f_bear,
107
+ f_strong,
108
+ f_guard,
109
+ f_ovld_D,
110
+ f_ovld,
111
+ f_custom,
112
+ f_custom_2,
113
+ Gusto(didi2),
114
+ Gusto(didi2).__call__,
115
+ ):
116
+ timing = timeit.timeit(stmt=lambda: fn(3, 4), number=300000)
117
+ print(f"{fn.__name__:10}{1000 * timing:>10.3f}ms")
118
+
119
+ breakpoint()
120
+ f_ovld(4, 5)
@@ -4,6 +4,7 @@ from multimethod import multimethod
4
4
  from multipledispatch import dispatch
5
5
  from plum import dispatch as plum
6
6
 
7
+ # from strongtyping_pyoverload import overload
7
8
  from ovld import ovld, recurse
8
9
 
9
10
  # OVLD
@@ -157,6 +158,35 @@ def smap_pl(x: object, y: object):
157
158
  return x + y
158
159
 
159
160
 
161
+ # # strongtyping
162
+
163
+
164
+ # @overload
165
+ # def smap_wh(x: list, y: list):
166
+ # """Three."""
167
+ # return [smap_wh(a, b) for a, b in zip(x, y)]
168
+
169
+
170
+ # @overload
171
+ # def smap_wh(x: tuple, y: tuple):
172
+ # return tuple(smap_wh(a, b) for a, b in zip(x, y))
173
+
174
+
175
+ # @overload
176
+ # def smap_wh(x: dict, y: dict):
177
+ # return {k: smap_wh(v, y[k]) for k, v in x.items()}
178
+
179
+
180
+ # @overload
181
+ # def smap_wh(x: object, y: object):
182
+ # return x + y
183
+
184
+
185
+ # @overload
186
+ # def smap_wh(x: str, y: str):
187
+ # return x + y
188
+
189
+
160
190
  ###
161
191
 
162
192
 
@@ -171,6 +201,7 @@ results = {
171
201
  "smap_ii": smap_ii(A, B),
172
202
  "smap_mh": smap_mh(A, B),
173
203
  "smap_c": smap_c(A, B),
204
+ # "smap_wh": smap_wh(A, B),
174
205
  }
175
206
 
176
207
  expected = results["smap"]
@@ -186,5 +217,6 @@ print("smap_md\t", 10 * timeit.timeit(lambda: smap_md(A, B), number=10000))
186
217
  print("smap_pl\t", 10 * timeit.timeit(lambda: smap_pl(A, B), number=10000))
187
218
  print("smap_ov\t", 10 * timeit.timeit(lambda: smap(A, B), number=10000))
188
219
  print("smap_c\t", 10 * timeit.timeit(lambda: smap_c(A, B), number=10000))
220
+ # print("smap_wh\t", 10 * timeit.timeit(lambda: smap_wh(A, B), number=10000))
189
221
  print("smap_ii\t", 10 * timeit.timeit(lambda: smap_ii(A, B), number=10000))
190
222
  print("smap_mh\t", 10 * timeit.timeit(lambda: smap_mh(A, B), number=10000))
@@ -115,7 +115,7 @@ ops = {
115
115
  def calc_dict(expr):
116
116
  if isinstance(expr, tuple):
117
117
  return ops[expr[0]](*expr[1:])
118
- elif isinstance(expr, (int, float)):
118
+ elif isinstance(expr, Number):
119
119
  return expr
120
120
 
121
121
 
@@ -148,7 +148,7 @@ def make_test(cls):
148
148
 
149
149
 
150
150
  test_multer_ovld = make_test(make_multer(ovld_dispatch))
151
- test_multer_ovld_recurse = make_test(OvldRecurseMulter)
151
+ test_multer_recurse = make_test(OvldRecurseMulter)
152
152
  test_multer_plum = make_test(make_multer(plum_dispatch))
153
153
  test_multer_multimethod = make_test(make_multer(multimethod_dispatch))
154
154
  test_multer_singledispatch = make_test(SingleDispatchMulter)
@@ -0,0 +1,96 @@
1
+ import re
2
+
3
+ import pytest
4
+
5
+ from ovld.dependent import Regexp
6
+
7
+ from .common import ovld_dispatch, plum_dispatch
8
+
9
+ ###############################
10
+ # multiple dispatch libraries #
11
+ ###############################
12
+
13
+
14
+ def make_regexp(dispatch):
15
+ @dispatch
16
+ def regexp(x: Regexp[r"^a"]):
17
+ return "one"
18
+
19
+ @dispatch
20
+ def regexp(x: Regexp[r"^[bcd]"]):
21
+ return "two"
22
+
23
+ @dispatch
24
+ def regexp(x: Regexp[r"end$"]):
25
+ return "three"
26
+
27
+ return regexp
28
+
29
+
30
+ ##############
31
+ # isinstance #
32
+ ##############
33
+
34
+
35
+ def regexp_search(x):
36
+ if re.search(string=x, pattern=r"^a"):
37
+ return "one"
38
+ if re.search(string=x, pattern=r"^[bcd]"):
39
+ return "two"
40
+ if re.search(string=x, pattern=r"end$"):
41
+ return "three"
42
+
43
+
44
+ re1 = re.compile(r"^a")
45
+ re2 = re.compile(r"^[bcd]")
46
+ re3 = re.compile(r"end$")
47
+
48
+
49
+ def regexp_compiled(x):
50
+ if re1.search(x):
51
+ return "one"
52
+ if re2.search(x):
53
+ return "two"
54
+ if re3.search(x):
55
+ return "three"
56
+
57
+
58
+ def regexp_compiled_nonexclusive(x):
59
+ r1 = bool(re1.search(x))
60
+ r2 = bool(re2.search(x))
61
+ r3 = bool(re3.search(x))
62
+ if r1:
63
+ return "one"
64
+ if r2:
65
+ return "two"
66
+ if r3:
67
+ return "three"
68
+
69
+
70
+ ####################
71
+ # Test definitions #
72
+ ####################
73
+
74
+
75
+ def make_test(fn):
76
+ @pytest.mark.benchmark(group="regexp")
77
+ def test(benchmark):
78
+ def run():
79
+ return [
80
+ fn("allo"),
81
+ fn("canada"),
82
+ fn("the end"),
83
+ ]
84
+
85
+ result = benchmark(run)
86
+ assert result == ["one", "two", "three"]
87
+
88
+ return test
89
+
90
+
91
+ test_regexp_ovld = make_test(make_regexp(ovld_dispatch))
92
+ test_regexp_plum = make_test(make_regexp(plum_dispatch))
93
+
94
+ test_regexp_custom_search = make_test(regexp_search)
95
+ test_regexp_custom_compiled = make_test(regexp_compiled)
96
+ # test_regexp_custom_compiled_nx = make_test(regexp_compiled_nonexclusive)
@@ -62,6 +62,9 @@ def tup_match(expr):
62
62
 
63
63
 
64
64
  def make_test(fn):
65
+ fn(())
66
+ fn = fn.__call__
67
+
65
68
  def run():
66
69
  return [fn(()), fn((1,)), fn(("x",)), fn((2, "y"))]
67
70
 
@@ -0,0 +1,160 @@
1
+ # from collections.abc import Collection
2
+ # from dataclasses import dataclass
3
+ # from itertools import product
4
+ # from numbers import Number
5
+ # from typing import Literal
6
+
7
+ # import pytest
8
+ # from beartype import beartype
9
+
10
+ # try:
11
+ # from strongtyping.strong_typing import match_typing
12
+ # except ImportError:
13
+ # match_typing = None
14
+ # from typeguard import typechecked
15
+
16
+ # from ovld import Ovld, ovld
17
+ # from ovld.dependent import Dependent, Regexp
18
+ # from ovld.types import Dataclass
19
+
20
+
21
+ # @dataclass
22
+ # class Point:
23
+ # x: int
24
+ # y: int
25
+
26
+
27
+ # def ovld(fn):
28
+ # o = Ovld()
29
+ # o.register(fn)
30
+ # return o.dispatch
31
+
32
+
33
+ # def typecheck_test(cases, checkers):
34
+ # def deco(fn):
35
+ # def make_test(chk_name, case_name, typecheck, params):
36
+ # group = f"{fn.__name__}_{case_name}"
37
+
38
+ # @pytest.mark.benchmark(group=group)
39
+ # def test(benchmark):
40
+ # *args, out = params
41
+ # tfn = typecheck(fn)
42
+ # result = benchmark(tfn, *args)
43
+ # assert result == out
44
+
45
+ # test.__name__ = f"test_{group}[{chk_name}]"
46
+ # globals()[test.__name__] = test
47
+
48
+ # for (case_name, case), (chk_name, chk) in product(
49
+ # cases.items(), checkers.items()
50
+ # ):
51
+ # if chk is not None:
52
+ # make_test(chk_name, case_name, chk, case)
53
+
54
+ # return deco
55
+
56
+
57
+ # @typecheck_test(
58
+ # cases=dict(normal=(10, 20, 200)),
59
+ # checkers=dict(
60
+ # ovld=ovld,
61
+ # beartype=beartype,
62
+ # typeguard=typechecked,
63
+ # strongtyping=match_typing,
64
+ # ),
65
+ # )
66
+ # def mul(x: int, y: int):
67
+ # return x * y
68
+
69
+
70
+ # @typecheck_test(
71
+ # cases=dict(
72
+ # ints=(10, 20, 30),
73
+ # lists=([1], [2], [1, 2]),
74
+ # ),
75
+ # checkers=dict(
76
+ # ovld=ovld,
77
+ # beartype=beartype,
78
+ # typeguard=typechecked,
79
+ # strongtyping=match_typing,
80
+ # ),
81
+ # )
82
+ # def add(x: int | str | float | list, y: int | str | float | list):
83
+ # return x + y
84
+
85
+
86
+ # @typecheck_test(
87
+ # cases=dict(
88
+ # normal=("http://google.com", "google.com"),
89
+ # ),
90
+ # checkers=dict(
91
+ # ovld=ovld,
92
+ # beartype=beartype,
93
+ # # typeguard=typechecked,
94
+ # # strongtyping=match_typing,
95
+ # ),
96
+ # )
97
+ # def urlregexp(url: Regexp[r"^http://.*"]):
98
+ # return url.split("://")[1]
99
+
100
+
101
+ # @typecheck_test(
102
+ # cases=dict(
103
+ # normal=([1, 2, 3], 1),
104
+ # ),
105
+ # checkers=dict(
106
+ # ovld=ovld,
107
+ # beartype=beartype,
108
+ # typeguard=typechecked,
109
+ # strongtyping=match_typing,
110
+ # ),
111
+ # )
112
+ # def firstelem(elements: list[int]):
113
+ # return elements[0]
114
+
115
+
116
+ # @typecheck_test(
117
+ # cases=dict(
118
+ # normal=(123, Point(1, 2), "low", "whatever"),
119
+ # ),
120
+ # checkers=dict(
121
+ # ovld=ovld,
122
+ # beartype=beartype,
123
+ # typeguard=typechecked,
124
+ # strongtyping=match_typing,
125
+ # ),
126
+ # )
127
+ # def misc(
128
+ # numero: Number, dc: Dataclass, method: Literal["low"] | Literal["high"]
129
+ # ):
130
+ # return "whatever"
131
+
132
+
133
+ # @typecheck_test(
134
+ # cases=dict(
135
+ # normal=(10, 11),
136
+ # ),
137
+ # checkers=dict(
138
+ # ovld=ovld,
139
+ # beartype=beartype,
140
+ # # typeguard=typechecked,
141
+ # # strongtyping=match_typing,
142
+ # ),
143
+ # )
144
+ # def positive(x: Dependent[int, lambda x: x > 0]):
145
+ # return x + 1
146
+
147
+
148
+ # @typecheck_test(
149
+ # cases=dict(
150
+ # normal=((1, Point(2, 3), "blah"), ("blah", Point(2, 3), 1)),
151
+ # ),
152
+ # checkers=dict(
153
+ # ovld=ovld,
154
+ # beartype=beartype,
155
+ # typeguard=typechecked,
156
+ # strongtyping=match_typing,
157
+ # ),
158
+ # )
159
+ # def triple(xyz: tuple[Number, Dataclass, Collection]):
160
+ # return tuple(reversed(xyz))
@@ -3,7 +3,7 @@
3
3
 
4
4
  ## Unique features
5
5
 
6
- Current as of September 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 faster to 100x faster. Feature-wise, `ovld` is among the most featureful. Some features I could not find elsewhere:
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:
7
7
 
8
8
  * Support for [keyword arguments](usage.md#keyword-arguments).
9
9
  * [Variants](usage.md#variants), especially working with recursion.
@@ -27,10 +27,11 @@ Current as of September 2024: I have investigated and benchmarked six other mult
27
27
  Applicable libraries were tested on the following problems:
28
28
 
29
29
  * [trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py): Basic single dispatch test with a bunch of types.
30
- * [add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py): Recursively add lists and dictionaries element-wise.
31
30
  * [multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py): Recursively multiply lists and dictionaries element-wise by a number, but using a class. This tests dispatch on methods.
31
+ * [add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py): Recursively add lists and dictionaries element-wise.
32
32
  * [ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py): Simple transform on a Python AST.
33
33
  * [calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py): Calculator implementation. Dispatches using `op: Literal[<opname>]`.
34
+ * [regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py): Dispatch based on a regular expression (`ovld.dependent.Regexp[<regex>]`).
34
35
  * [fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py): Fibonacci numbers. The base cases are implemented by dispatching on `n: Literal[0]` and `n: Literal[1]`.
35
36
  * [tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py): Dispatching on keyword arguments.
36
37
 
@@ -39,21 +40,21 @@ Applicable libraries were tested on the following problems:
39
40
 
40
41
  Time relative to the fastest implementation (1.00) (lower is better). Python version: 3.12.4
41
42
 
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.1x faster to 3.7x slower.
43
+ 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.
43
44
 
44
- | Bench | 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) | [fastcore](https://github.com/fastai/fastcore) | [singled](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
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) | [fastcore](https://github.com/fastai/fastcore) | [sd](https://docs.python.org/3/library/functools.html#functools.singledispatch) |
45
46
  | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
46
- |[trivial](https://github.com/breuleux/ovld/tree/master/benchmarks/test_trivial.py)|1.14|1.00|2.53|3.64|1.61|1.86|41.31|1.54|
47
- |[add](https://github.com/breuleux/ovld/tree/master/benchmarks/test_add.py)|1.01|1.00|3.46|4.83|2.21|2.66|56.08|x|
48
- |[multer](https://github.com/breuleux/ovld/tree/master/benchmarks/test_multer.py)|1.00|1.06|9.79|4.11|7.19|1.89|40.37|6.34|
49
- |[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.06|23.07|3.04|1.68|1.87|29.11|1.63|
50
- |[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.96|80.00|43.21|x|x|x|x|
51
- |[fib](https://github.com/breuleux/ovld/tree/master/benchmarks/test_fib.py)|1.00|3.58|438.97|123.58|x|x|x|x|
52
- |[tweak](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.59|x|x|x|x|x|x|
53
-
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|51.93|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|46.74|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|59.31|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|28.39|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|x|
52
+ |[regexp](https://github.com/breuleux/ovld/tree/master/benchmarks/test_regexp.py)|1.00|1.87|19.18|x|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|x|
54
+ |[tweaknum](https://github.com/breuleux/ovld/tree/master/benchmarks/test_tweaknum.py)|1.00|2.09|x|x|x|x|x|x|
54
55
 
55
56
  ## Comments
56
57
 
57
58
  A big part of ovld's advantage comes from generating custom dispatch methods depending on the set of signatures that were registered. If you can avoid looping over `*args`, you're basically halving your overhead. Regarding dispatch on `Literal`, ovld also generates custom dispatch methods that unroll a series of specific if/else statements, which is the only way you'll ever get spitting distance from a normal implementation.
58
59
 
59
- I haven't benchmarked the overhead of registering and compiling the methods, nor cache miss resolves, but... yeah... I expect ovld will do pretty badly in that regard. That'll be the next big push, probably.
60
+ I haven't benchmarked the overhead of registering and compiling the methods, nor cache miss resolves, but I expect ovld will do pretty badly in that regard. That'll be the next big push, probably.
@@ -2,7 +2,7 @@ import json
2
2
  from collections import defaultdict
3
3
  from pathlib import Path
4
4
 
5
- file = Path(".benchmarks/Darwin-CPython-3.12-64bit/0011_report.json")
5
+ file = Path(".benchmarks/Darwin-CPython-3.12-64bit/0019_report.json")
6
6
  data = json.loads(file.read_text())
7
7
 
8
8
 
@@ -35,7 +35,16 @@ columns = [
35
35
  "https://docs.python.org/3/library/functools.html#functools.singledispatch",
36
36
  ],
37
37
  ]
38
- bench_names = ["trivial", "add", "multer", "ast", "calc", "fib", "tweaknum"]
38
+ bench_names = [
39
+ "trivial",
40
+ "multer",
41
+ "add",
42
+ "ast",
43
+ "calc",
44
+ "regexp",
45
+ "fib",
46
+ "tweaknum",
47
+ ]
39
48
 
40
49
 
41
50
  template = "https://github.com/breuleux/ovld/tree/master/benchmarks/test_{}.py"
@@ -52,6 +61,7 @@ for name in bench_names:
52
61
  min(bench["stats"]["median"] for bench in benches)
53
62
  for cat, benches in group.items()
54
63
  # if cat != "custom"
64
+ if cat != "recurse"
55
65
  )
56
66
  loc = template.format(name)
57
67
  line = [f"[{name}]({loc})"]