Skip to content

Commit 6c7c37f

Browse files
committedAug 17, 2021
Closes #264
1 parent fb8cd97 commit 6c7c37f

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
 

‎docs/pages/generics.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,41 @@ not the base ``_User``.
181181
182182
user: UserDict = {'name': 'sobolevn', 'registered': True}
183183
assert get_name(user) == 'sobolevn'
184+
185+
Tuples of concrete shapes
186+
~~~~~~~~~~~~~~~~~~~~~~~~~
187+
188+
The logic is the same with concrete ``Tuple`` items:
189+
190+
.. code:: python
191+
192+
>>> from typing import Tuple
193+
>>> from classes import typeclass
194+
195+
>>> class UserTupleMeta(type):
196+
... def __instancecheck__(cls, arg: object) -> bool:
197+
... try:
198+
... return (
199+
... isinstance(arg, tuple) and
200+
... isinstance(arg[0], str) and
201+
... isinstance(arg[1], bool)
202+
... )
203+
... except IndexError:
204+
... return False
205+
206+
>>> class UserTuple(Tuple[str, bool], metaclass=UserTupleMeta):
207+
... ...
208+
209+
>>> @typeclass
210+
... def get_name(instance) -> str:
211+
... ...
212+
213+
>>> @get_name.instance(delegate=UserTuple)
214+
... def _get_name_user_dict(instance: Tuple[str, bool]) -> str:
215+
... return instance[0]
216+
217+
>>> assert get_name(('sobolevn', True)) == 'sobolevn'
218+
>>> get_name((1, 2))
219+
Traceback (most recent call last):
220+
...
221+
NotImplementedError: Missing matched typeclass instance for type: tuple

‎typesafety/test_typeclass/test_generics/test_generics_concrete.yml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,86 @@
191191
main:11: error: Instance "builtins.list[builtins.int]" does not match inferred type "main.SomeDelegate"
192192
main:11: error: Only a single argument can be applied to `.instance`
193193
main:11: error: Regular type "builtins.str*" passed as a protocol
194+
195+
196+
- case: typeclass_concrete_generic_delegate_and_tuple1
197+
disable_cache: false
198+
main: |
199+
from typing import Tuple
200+
from classes import typeclass
201+
202+
class UserTupleMeta(type):
203+
def __instancecheck__(cls, arg: object) -> bool:
204+
try:
205+
return (
206+
isinstance(arg, tuple) and
207+
isinstance(arg[0], str) and
208+
isinstance(arg[1], bool)
209+
)
210+
except IndexError:
211+
return False
212+
213+
class UserTuple(Tuple[str, bool], metaclass=UserTupleMeta):
214+
...
215+
216+
@typeclass
217+
def get_name(instance) -> str:
218+
...
219+
220+
@get_name.instance(delegate=UserTuple)
221+
def _get_name_user_dict(instance: Tuple[str, bool]) -> str:
222+
return instance[0]
223+
224+
225+
get_name(('a', True)) # ok
226+
227+
get_name(())
228+
get_name(('a', 'b', 'c'))
229+
get_name(('a', 1))
230+
out: |
231+
main:29: error: Argument 1 to "get_name" has incompatible type "Tuple[]"; expected "Tuple[str, bool]"
232+
main:30: error: Argument 1 to "get_name" has incompatible type "Tuple[str, str, str]"; expected "Tuple[str, bool]"
233+
main:31: error: Argument 1 to "get_name" has incompatible type "Tuple[str, int]"; expected "Tuple[str, bool]"
234+
235+
236+
- case: typeclass_concrete_generic_delegate_and_tuple2
237+
disable_cache: false
238+
main: |
239+
from typing import Tuple
240+
from classes import typeclass
241+
242+
class UserTupleMeta(type):
243+
def __instancecheck__(cls, arg: object) -> bool:
244+
try:
245+
return (
246+
isinstance(arg, tuple) and
247+
isinstance(arg[0], str) and
248+
isinstance(arg[1], bool)
249+
)
250+
except IndexError:
251+
return False
252+
253+
class UserTuple(Tuple[str, bool], metaclass=UserTupleMeta):
254+
...
255+
256+
@typeclass
257+
def get_name(instance) -> str:
258+
...
259+
260+
@get_name.instance(delegate=UserTuple)
261+
def _get_name_user_dict(instance: UserTuple) -> str:
262+
return instance[0]
263+
264+
265+
a = UserTuple(('a', True))
266+
get_name(a)
267+
268+
get_name(())
269+
get_name(('a', 'b'))
270+
get_name(('a', True))
271+
get_name(('a', 'b', 'c'))
272+
out: |
273+
main:30: error: Argument 1 to "get_name" has incompatible type "Tuple[]"; expected "UserTuple"
274+
main:31: error: Argument 1 to "get_name" has incompatible type "Tuple[str, str]"; expected "UserTuple"
275+
main:32: error: Argument 1 to "get_name" has incompatible type "Tuple[str, bool]"; expected "UserTuple"
276+
main:33: error: Argument 1 to "get_name" has incompatible type "Tuple[str, str, str]"; expected "UserTuple"

0 commit comments

Comments
 (0)
Please sign in to comment.