Skip to content

Commit 2372ea6

Browse files
committed
Document overload alternatives.
Refs #119.
1 parent a7a395e commit 2372ea6

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

README.md

+14-4
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,26 @@ for subclass in (float, list, list[float], tuple[int]):
100100
assert not issubclass(subclass, cls)
101101
```
102102

103-
If a type implements a custom `__instancecheck__`, it can opt-in to dispatch (without caching) by registering its metaclass and bases with `subtype.origins`. `parametric` provides a convenient constructor, with support for predicate functions and checking attributes.
103+
If a type implements a custom `__instancecheck__`, it can opt-in to dispatch (without caching) by registering its metaclass and bases with `subtype.origins`. `parametric` provides a convenient constructor, which will match the base class, predicate functions, and check attributes.
104104

105105
```python
106106
from multimethod import parametric
107107

108-
coro = parametric(Callable, asyncio.iscoroutinefunction)
109-
ints = parametric(array, typecode='i')
108+
Coroutine = parametric(Callable, asyncio.iscoroutinefunction)
109+
IntArray = parametric(array, typecode='i')
110110
```
111111

112-
`overload` used to dispatch on annotated predicate functions. It is deprecated because a custom instance check - including using `parametric` - offers the same functionality.
112+
`overload` used to dispatch on annotated predicate functions. It is deprecated because a custom instance check - including using `parametric` - offers the same functionality. Any predicate function can be wrapped with the closest matching base class, including `object` if necessary.
113+
114+
```python
115+
Cls = parametric(object, predicate)
116+
Digits = parametric(str, str.isdigit)
117+
assert isinstance('0', Digits)
118+
assert not isinstance('a', Digits)
119+
120+
@meth.register
121+
def _(arg: Digits): ...
122+
```
113123

114124
### classes
115125
`classmethod` and `staticmethod` may be used with a multimethod, but must be applied _last_, i.e., wrapping the final multimethod definition after all functions are registered. For class and instance methods, `cls` and `self` participate in the dispatch as usual. They may be left blank when using annotations, otherwise use `object` as a placeholder.

docs/examples.ipynb

+24-3
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@
133133
"metadata": {},
134134
"source": [
135135
"## parametric\n",
136-
"In addition to `issubclass`, multimethods can dispatch on `isinstance` with additional parametric checks."
136+
"In addition to `issubclass`, multimethods can dispatch on `isinstance` with parametric checks."
137137
]
138138
},
139139
{
@@ -148,7 +148,7 @@
148148
"from concurrent import futures\n",
149149
"from multimethod import parametric\n",
150150
"\n",
151-
"coro = parametric(Callable, asyncio.iscoroutinefunction)\n",
151+
"Coroutine = parametric(Callable, asyncio.iscoroutinefunction)\n",
152152
"\n",
153153
"\n",
154154
"@multimethod\n",
@@ -157,7 +157,7 @@
157157
"\n",
158158
"\n",
159159
"@multimethod\n",
160-
"async def wait(timeout, func: coro, *args):\n",
160+
"async def wait(timeout, func: Coroutine, *args):\n",
161161
" return await asyncio.wait_for(func(*args), timeout)\n",
162162
"\n",
163163
"\n",
@@ -173,6 +173,27 @@
173173
"wait(0.5, asyncio.sleep, 0.01)"
174174
]
175175
},
176+
{
177+
"cell_type": "code",
178+
"execution_count": null,
179+
"metadata": {},
180+
"outputs": [],
181+
"source": [
182+
"from array import array\n",
183+
"\n",
184+
"IntArray = parametric(array, typecode='i')\n",
185+
"isinstance(array('i'), IntArray)"
186+
]
187+
},
188+
{
189+
"cell_type": "code",
190+
"execution_count": null,
191+
"metadata": {},
192+
"outputs": [],
193+
"source": [
194+
"isinstance(array('f'), IntArray)"
195+
]
196+
},
176197
{
177198
"cell_type": "markdown",
178199
"metadata": {},

0 commit comments

Comments
 (0)