New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider adding generics support #8
Comments
I am not certain the use case is entirely clear. Does Regarding |
The usecase I have in mind is: @some.instance(Some[FirstType])
...
@some.instance(Some[SecondType])
...
@some.instance(Some[ThirdType])
... |
Understood. I am all for I could propose an implementation for that as follows. First of all, class Success(...):
def __class_getitem__(cls, value):
if blablabla:
return type(
f'{cls.__name__}[{value.__name__}]',
(cls, ),
{
'_contained_type': value
}
) (I know However, >>> Success[str]._contained_type
<type 'str'> Now, let's define an instance method: class Success(...):
def wrapped_type(self) -> type:
return type(self._inner_value) This means that: >>> Success(5).wrapped_type()
<type 'int'> Why is all this needed anyway? That's why. class Success(...):
def _instancecheck_(cls, instance):
return isinstance(instance, Success) and (
instance.wrapped_type() == self._contained_type
or self._contained_type is None
)
>>> isintance(Success(5), Success[int])
True
>>> isintance(Success(5), Success[str])
False
>>> isinstance(Success(5), Success)
True This probably means the implementation for containers in P. S. |
@anatoly-scherbakov great idea! So, we can provide a protocol for other generics to follow. And possibly leave |
Thanks. I have stumbled across I've come to believe that fixing runtime type erasure is a valid and sufficiently generic use case to be implemented as an independent component useful in many contexts. As per my links above, however, calls like def very_slow_stuff():
v = Mapping[int](5) ... would be quite undesirable and should be avoided. But, if used in inheritance context - they would only slow down the startup of the application and provide a neat interface to type specification which is also well supported by static analysis. Example: class PeopleGraph(Graph[Person, Friendship]):
... looks more pythonic and native than class PeopleGraph(Graph):
node_type = Person
edge_type = Friendship Thoughts? |
Hey! Don't know how I ended up here, but actually |
@MadcowD thanks! 👍 |
(Be careful with isinstance calls as well). Lastly, you might consider implementing you're own generic's system which doesn't do class instantiation, but rather acts as a partial function on an object constructor: class Meta(type):
def __getitem__(cls, typin):
def partial(*args, **kwargs):
return cls(typin, *args, **kwargs)
partial.__doc__ = cls.__doc__
# Do other things here
return partial
class TypeSpecificClass(metaclass=Meta):
def __init__(self, mytype, someotherarg, somekwarg=0):
assert isinstance(mytype, type), "Must instantiate with a type."
self._type = mytype
# Usage
intlabeledobj = TypeSpecificClass[int]("hi", somekwarg=1) This is honestly so much faster than using the typing library (mainly for isinstance resolution). You can also extend this Good luck :) |
@MadcowD it seems to me like I am using a cache to avoid re-creating new subclasses every time, but this idea of yours is an interesting alternative. Thanks! |
We need to be able to work with generic like
List[str]
orResult[str, Exception]
andMaybe[int]
I propose the following API:
It should be supported on both side: types and runtime.
The text was updated successfully, but these errors were encountered: