ovld 0.4.3__tar.gz → 0.4.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.
- {ovld-0.4.3 → ovld-0.4.5}/PKG-INFO +11 -10
- {ovld-0.4.3 → ovld-0.4.5}/README.md +10 -9
- ovld-0.4.5/beary.py +120 -0
- {ovld-0.4.3 → ovld-0.4.5}/bench.py +33 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_calc.py +1 -1
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_multer.py +1 -1
- ovld-0.4.5/benchmarks/test_regexp.py +96 -0
- ovld-0.4.5/benchmarks/test_tuple.py +83 -0
- ovld-0.4.5/benchmarks/test_typechecking.py +160 -0
- ovld-0.4.5/coco.py +79 -0
- ovld-0.4.5/didi.py +60 -0
- {ovld-0.4.3 → ovld-0.4.5}/docs/compare.md +14 -13
- {ovld-0.4.3 → ovld-0.4.5}/docs/types.md +10 -0
- {ovld-0.4.3 → ovld-0.4.5}/gen_comparison_table.py +12 -2
- ovld-0.4.5/gen_typecheck_table.py +60 -0
- ovld-0.4.5/kraken.py +30 -0
- {ovld-0.4.3 → ovld-0.4.5}/pyproject.toml +1 -1
- {ovld-0.4.3 → ovld-0.4.5}/reddit.md +7 -5
- ovld-0.4.5/refun.py +16 -0
- ovld-0.4.5/reper.py +6 -0
- {ovld-0.4.3 → ovld-0.4.5}/src/ovld/__init__.py +1 -2
- ovld-0.4.5/src/ovld/abc.py +48 -0
- {ovld-0.4.3 → ovld-0.4.5}/src/ovld/core.py +197 -214
- ovld-0.4.5/src/ovld/dependent.py +390 -0
- {ovld-0.4.3 → ovld-0.4.5}/src/ovld/mro.py +30 -60
- {ovld-0.4.3 → ovld-0.4.5}/src/ovld/recode.py +92 -90
- {ovld-0.4.3 → ovld-0.4.5}/src/ovld/typemap.py +9 -31
- ovld-0.4.5/src/ovld/types.py +441 -0
- ovld-0.4.5/src/ovld/utils.py +140 -0
- ovld-0.4.5/src/ovld/version.py +1 -0
- ovld-0.4.5/tests/test_abc.py +270 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_dependent.py +56 -77
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_examples.py +7 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_mro.py +80 -11
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_ovld/test_display.txt +12 -12
- ovld-0.4.5/tests/test_ovld/test_display_more.txt +8 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_ovld/test_method_doc.txt +1 -1
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_ovld.py +60 -53
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_typemap.py +42 -25
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_types.py +68 -44
- {ovld-0.4.3 → ovld-0.4.5}/uv.lock +7 -7
- ovld-0.4.3/didi.py +0 -26
- ovld-0.4.3/src/ovld/dependent.py +0 -282
- ovld-0.4.3/src/ovld/types.py +0 -231
- ovld-0.4.3/src/ovld/utils.py +0 -68
- ovld-0.4.3/src/ovld/version.py +0 -1
- {ovld-0.4.3 → ovld-0.4.5}/.bsync-snap-20220324145902.852076 +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/.bsync-snap-20240916114026.355340 +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/.envrc +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/.github/workflows/python-package.yml +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/.gitignore +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/.python-version +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/.readthedocs.yaml +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/LICENSE +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/add.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/anal.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/bench/requirements.txt +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchd.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/__init__.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/common.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_add.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_ast.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_fib.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_trivial.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/benchmarks/test_tweaknum.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/cloz.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/data.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/docs/dependent.md +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/docs/features.md +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/docs/index.md +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/docs/usage.md +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/doo.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/edges.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/explore.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/facto.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/gentest.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/hello.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/hntest.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/klos.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/mkdocs.yml +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/nxt.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.0-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.0.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.1-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.1.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.2-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.2.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.3-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.3.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.4-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.4.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.5-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.5.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.6-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.6.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.7-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.7.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.8-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.8.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.9-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.1.9.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.0-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.0.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.1-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.1.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.10-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.10.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.11-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.11.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.2-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.2.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.3-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.3.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.4-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.4.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.5-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.5.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.6-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.6.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.7-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.7.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.8-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.8.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.9-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.2.9.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.0-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.0.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.1-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.1.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.2-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.2.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.3-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.3.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.4-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.4.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.5-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.5.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.8-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.8.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.9-py3-none-any.whl +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/old-dist/ovld-0.3.9.tar.gz +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/one_two_three.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/outoftheway.toml +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/reddit.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/stuff.md +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tb.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tensor.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/__init__.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/modules/gingerbread.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_global.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_ovld/test_doc.txt +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_ovld/test_doc2.txt +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/tests/test_utils.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/todo.q +5 -5
- {ovld-0.4.3 → ovld-0.4.5}/toot.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/typo.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/world.yaml +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/x.py +0 -0
- {ovld-0.4.3 → ovld-0.4.5}/zaggo +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: ovld
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.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/
|
@@ -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
|
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
|
-
|
|
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.
|
211
|
-
|[
|
212
|
-
|[
|
213
|
-
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.
|
214
|
-
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.
|
215
|
-
|[
|
216
|
-
|[
|
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
|
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
|
-
|
|
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.
|
198
|
-
|[
|
199
|
-
|[
|
200
|
-
|[ast](https://github.com/breuleux/ovld/tree/master/benchmarks/test_ast.py)|1.00|1.
|
201
|
-
|[calc](https://github.com/breuleux/ovld/tree/master/benchmarks/test_calc.py)|1.00|1.
|
202
|
-
|[
|
203
|
-
|[
|
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.5/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
|
@@ -27,6 +28,7 @@ def smap(x: dict, y: dict):
|
|
27
28
|
|
28
29
|
@ovld
|
29
30
|
def smap(x: object, z: object):
|
31
|
+
1 / 0
|
30
32
|
return x + z
|
31
33
|
|
32
34
|
|
@@ -157,6 +159,35 @@ def smap_pl(x: object, y: object):
|
|
157
159
|
return x + y
|
158
160
|
|
159
161
|
|
162
|
+
# # strongtyping
|
163
|
+
|
164
|
+
|
165
|
+
# @overload
|
166
|
+
# def smap_wh(x: list, y: list):
|
167
|
+
# """Three."""
|
168
|
+
# return [smap_wh(a, b) for a, b in zip(x, y)]
|
169
|
+
|
170
|
+
|
171
|
+
# @overload
|
172
|
+
# def smap_wh(x: tuple, y: tuple):
|
173
|
+
# return tuple(smap_wh(a, b) for a, b in zip(x, y))
|
174
|
+
|
175
|
+
|
176
|
+
# @overload
|
177
|
+
# def smap_wh(x: dict, y: dict):
|
178
|
+
# return {k: smap_wh(v, y[k]) for k, v in x.items()}
|
179
|
+
|
180
|
+
|
181
|
+
# @overload
|
182
|
+
# def smap_wh(x: object, y: object):
|
183
|
+
# return x + y
|
184
|
+
|
185
|
+
|
186
|
+
# @overload
|
187
|
+
# def smap_wh(x: str, y: str):
|
188
|
+
# return x + y
|
189
|
+
|
190
|
+
|
160
191
|
###
|
161
192
|
|
162
193
|
|
@@ -171,6 +202,7 @@ results = {
|
|
171
202
|
"smap_ii": smap_ii(A, B),
|
172
203
|
"smap_mh": smap_mh(A, B),
|
173
204
|
"smap_c": smap_c(A, B),
|
205
|
+
# "smap_wh": smap_wh(A, B),
|
174
206
|
}
|
175
207
|
|
176
208
|
expected = results["smap"]
|
@@ -186,5 +218,6 @@ print("smap_md\t", 10 * timeit.timeit(lambda: smap_md(A, B), number=10000))
|
|
186
218
|
print("smap_pl\t", 10 * timeit.timeit(lambda: smap_pl(A, B), number=10000))
|
187
219
|
print("smap_ov\t", 10 * timeit.timeit(lambda: smap(A, B), number=10000))
|
188
220
|
print("smap_c\t", 10 * timeit.timeit(lambda: smap_c(A, B), number=10000))
|
221
|
+
# print("smap_wh\t", 10 * timeit.timeit(lambda: smap_wh(A, B), number=10000))
|
189
222
|
print("smap_ii\t", 10 * timeit.timeit(lambda: smap_ii(A, B), number=10000))
|
190
223
|
print("smap_mh\t", 10 * timeit.timeit(lambda: smap_mh(A, B), number=10000))
|
@@ -148,7 +148,7 @@ def make_test(cls):
|
|
148
148
|
|
149
149
|
|
150
150
|
test_multer_ovld = make_test(make_multer(ovld_dispatch))
|
151
|
-
|
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)
|
@@ -0,0 +1,83 @@
|
|
1
|
+
from typing import Literal
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from .common import (
|
6
|
+
multimethod_dispatch,
|
7
|
+
ovld_dispatch,
|
8
|
+
plum_dispatch,
|
9
|
+
)
|
10
|
+
|
11
|
+
###############################
|
12
|
+
# multiple dispatch libraries #
|
13
|
+
###############################
|
14
|
+
|
15
|
+
|
16
|
+
def make_tup(dispatch):
|
17
|
+
@dispatch
|
18
|
+
def tup(t: tuple[()]):
|
19
|
+
return 0
|
20
|
+
|
21
|
+
@dispatch
|
22
|
+
def tup(t: tuple[int]):
|
23
|
+
return 1
|
24
|
+
|
25
|
+
@dispatch
|
26
|
+
def tup(t: tuple[Literal["x"]]):
|
27
|
+
return 2
|
28
|
+
|
29
|
+
@dispatch
|
30
|
+
def tup(t: tuple[int, str]):
|
31
|
+
return 3
|
32
|
+
|
33
|
+
@dispatch
|
34
|
+
def tup(t: tuple[tuple[str]]):
|
35
|
+
return 4
|
36
|
+
|
37
|
+
return tup
|
38
|
+
|
39
|
+
|
40
|
+
#########
|
41
|
+
# match #
|
42
|
+
#########
|
43
|
+
|
44
|
+
|
45
|
+
def tup_match(expr):
|
46
|
+
match expr:
|
47
|
+
case ():
|
48
|
+
return 0
|
49
|
+
case (int(),):
|
50
|
+
return 1
|
51
|
+
case (str(),):
|
52
|
+
return 2
|
53
|
+
case (int(), str()):
|
54
|
+
return 3
|
55
|
+
case ((str(),),):
|
56
|
+
return 4
|
57
|
+
|
58
|
+
|
59
|
+
####################
|
60
|
+
# Test definitions #
|
61
|
+
####################
|
62
|
+
|
63
|
+
|
64
|
+
def make_test(fn):
|
65
|
+
fn(())
|
66
|
+
fn = fn.__call__
|
67
|
+
|
68
|
+
def run():
|
69
|
+
return [fn(()), fn((1,)), fn(("x",)), fn((2, "y"))]
|
70
|
+
|
71
|
+
@pytest.mark.benchmark(group="tup")
|
72
|
+
def test(benchmark):
|
73
|
+
result = benchmark(run)
|
74
|
+
assert result == [0, 1, 2, 3]
|
75
|
+
|
76
|
+
return test
|
77
|
+
|
78
|
+
|
79
|
+
test_tup_ovld = make_test(make_tup(ovld_dispatch))
|
80
|
+
test_tup_plum = make_test(make_tup(plum_dispatch))
|
81
|
+
test_tup_multimethod = make_test(make_tup(multimethod_dispatch))
|
82
|
+
|
83
|
+
test_tup_custom_match = make_test(tup_match)
|
@@ -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))
|
ovld-0.4.5/coco.py
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
from typing import Callable
|
2
|
+
|
3
|
+
from ovld.core import ovld
|
4
|
+
|
5
|
+
# from plum import dispatch as ovld
|
6
|
+
# from multimethod import multimethod as ovld
|
7
|
+
|
8
|
+
|
9
|
+
class Animal:
|
10
|
+
pass
|
11
|
+
|
12
|
+
|
13
|
+
class Mammal(Animal):
|
14
|
+
pass
|
15
|
+
|
16
|
+
|
17
|
+
class Cat(Mammal):
|
18
|
+
pass
|
19
|
+
|
20
|
+
|
21
|
+
@ovld
|
22
|
+
def f(t: Callable[[Mammal], Mammal]):
|
23
|
+
return 1
|
24
|
+
|
25
|
+
|
26
|
+
@ovld
|
27
|
+
def f(t: Callable[[Mammal, Mammal], Mammal]):
|
28
|
+
return 2
|
29
|
+
|
30
|
+
|
31
|
+
def f1(x: Mammal, y: Mammal) -> Mammal:
|
32
|
+
return "X"
|
33
|
+
|
34
|
+
|
35
|
+
def f2(x: Animal, y: Animal) -> Mammal:
|
36
|
+
return "X"
|
37
|
+
|
38
|
+
|
39
|
+
print(f(f1))
|
40
|
+
print(f(f2))
|
41
|
+
|
42
|
+
|
43
|
+
# @ovld
|
44
|
+
# def f(t: tuple[()]):
|
45
|
+
# return 0
|
46
|
+
|
47
|
+
# @ovld
|
48
|
+
# def f(t: tuple[int]):
|
49
|
+
# return 1
|
50
|
+
|
51
|
+
# @ovld
|
52
|
+
# def f(t: tuple[str]):
|
53
|
+
# return 2
|
54
|
+
|
55
|
+
# @ovld
|
56
|
+
# def f(t: tuple[int, str]):
|
57
|
+
# return 3
|
58
|
+
|
59
|
+
# assert f(()) == 0
|
60
|
+
# assert f((1,)) == 1
|
61
|
+
# assert f(("x",)) == 2
|
62
|
+
# assert f((2, "y")) == 3
|
63
|
+
|
64
|
+
|
65
|
+
# @ovld
|
66
|
+
# def f(d: Sequence[int]):
|
67
|
+
# return 0
|
68
|
+
|
69
|
+
|
70
|
+
# @ovld
|
71
|
+
# def f(d: Sequence[str]):
|
72
|
+
# return 1
|
73
|
+
|
74
|
+
|
75
|
+
# print(f([1]))
|
76
|
+
# print(f(["x"]))
|
77
|
+
# print(f([1, "x"]))
|
78
|
+
# print(f(["x", "y", "z", 1]))
|
79
|
+
# print(f([]))
|