-
Notifications
You must be signed in to change notification settings - Fork 20
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
An issue with forward declarations and recursive type #22
Comments
I think currently forward declarations are only supported directly in annotations. Not sure if a mix of types and forward declarations is supported, but I suppose it's not (yet). Currently you can only use things like
Putting the whole type declaration into a string might work, but I suppose forward declarations are currently parsed in |
Quickly looked into the code. The relevant position is at Line 836 in 15ec80c
_issubclass but then it would resolve the forward declaration again and again for every new subtype check. Or _issubclass is allowed to modify the incoming type. Or we have some kind of cache.
A problem with resolving forward declarations within Maybe the best idea would be to have a public service function (e.g. Also note that resolving a forward ref, even checking if a type needs to resolve a forward ref somewhere internally is expensive and in most cases not necessary. With an explicit service function the user can actively and transparently resolve types as needed. What do you think? |
I think the public service function would be the best. It just has to make sure it resolves recursive types through reusing the same reference instead of copying the type over again and again. But yes, I think this would be the best and could also be done only once/cached on the caller's side. |
Any chance on implementing this soon or helping a bit how to do it? I thought I can make a workaround for us but it seems it does not work and it started blocking one validator we have for code and are using this package to check types. :-( |
Sorry, I was rather busy during christmas time. It would be great to have some help on this one. I already spent some thoughts about implementing the resolve function. I'll try to put a draft together we can iterate on... |
Yea, I completely understand about holidays. I tried to finish this before them, but it seems I got stuck now. Anyway, don't worry, I will try to see what I can do. |
So, I spontaneously committed some work on this as of 0f454ae. This should help with your issue for now.
Note that you need |
You are amazing! I will check it immediately! |
Hm, what is the second return value from |
Oh, I see, I do not even have to check return values. Cool. |
Works like a charm! Thanks. |
Care to release a version with this improvement? |
The first return value is the type itself. In case the input was one pure forward declaration as a string this is relevant. The second return value is a boolean indicating if a change was made, i.e. it is true if at least one actual forward declaration was found and resolved. This is to help people assess if they should eventually repeat or update operations or hashes or whatever they might have already done with their type. It's also useful for testing. There are actually some remaining todos on this issue (so reopening it for now...):
|
I want to have a new release soon, but would like to get some more stuff in, e.g. at least some of the todos listed above, fixes/resolutions for #23, #18, #20, eventually #21, failures mentioned in python-attrs/attrs#301 (comment) Help is welcome! |
Hm, it seems there is no protection against infinite recursion. I get stack overflow with this test: import typing
from pytypes import type_util
Data = typing.Union['Container', float]
Container = typing.Union[Data, int]
type_util.resolve_fw_decl(Data)
type_util.resolve_fw_decl(Container)
type_util._issubclass(list, Container, bound_typevars={}) Of course it is obvious that definition of types is buggy, but maybe |
Is it possible to have a recursion issue with a type not involving If so, I think it would be better to make Otherwise we would have to make It would be good to have an eventual example for recursion issue not involving |
I think Union + forward declarations. Or Union types without forward declarations if somebody manually "patch" Union objects in some other way.
Are you sure? Keeping track might introduce additional performance cost. But from design perspective this is probably cleaner, yes.
I would just have an extra argument to it, similar to bound variables, stored types being in process of resolving. |
I mean are there examples without
My philosophy in |
I cannot imagine a case without Union. This is the only current type which allows multiple options, no? |
Any solution to this would require at least one more new arg for
Me neither. I hope we don't overlook something. |
…d_typevars, c.f. #24. Improved doc of _issubclass and _isinstance.
As of 74ef4b9 |
I have not encountered this in practice but only during testings of new code. So the example above is the only one I have. Hm, but New code seems to work through against my example above. |
No, it actually does not get rid of |
Awesome! |
So it currently returns |
Example:
The text was updated successfully, but these errors were encountered: