Introduce a boundary parameter for typing.get_type_hints when used with a class object
In one of my projects I'm reusing class-level type annotations to identify relevant attributes for serialization, e.g. similar to the following: attrs = {name: getattr(obj, name) for name in get_type_hints(type(obj))} This is convenient because it merges the type annotations from the various stages in the class hierarchy, e.g. class Base: a: int class Derived(Base): b: str results in `attrs == dict(a=..., b=...)`. However it becomes inconvenient if external base classes are involved that define their own, unrelated type annotations, e.g. class External: # from some other distribution unrelated: float class Base(External): a: int It would be helpful if `get_type_hints` had a `boundary` parameter that, when used with a class object, determines the upper boundary for the MRO. So it could be used in the following way: get_type_hints(type(derived_obj), boundary=Base) to exclude any type annotations further up the class hierarchy (including the ones from `Base`). Regarding the implementation this would effectively skip over base classes in the reverse MRO until it reaches the `boundary`. What do you think?
This definitely feels to me like though if an oddball case that "write your own function" seems like the best solution. I accept the OP needs it, but I have trouble imagining that many others would. On Tue, Aug 4, 2020, 7:42 AM Dominik Vilsmeier <dominik.vilsmeier@gmx.de> wrote:
In one of my projects I'm reusing class-level type annotations to identify relevant attributes for serialization, e.g. similar to the following:
attrs = {name: getattr(obj, name) for name in get_type_hints(type(obj))}
This is convenient because it merges the type annotations from the various stages in the class hierarchy, e.g.
class Base: a: int class Derived(Base): b: str
results in `attrs == dict(a=..., b=...)`.
However it becomes inconvenient if external base classes are involved that define their own, unrelated type annotations, e.g.
class External: # from some other distribution unrelated: float class Base(External): a: int
It would be helpful if `get_type_hints` had a `boundary` parameter that, when used with a class object, determines the upper boundary for the MRO. So it could be used in the following way:
get_type_hints(type(derived_obj), boundary=Base)
to exclude any type annotations further up the class hierarchy (including the ones from `Base`).
Regarding the implementation this would effectively skip over base classes in the reverse MRO until it reaches the `boundary`.
What do you think? _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/T6K4DW... Code of Conduct: http://python.org/psf/codeofconduct/
Maybe get-type-hints can be refactored to make writing such a function simpler. IIRC the part that takes a single annotation and evaluates it is a private function. On Tue, Aug 4, 2020 at 12:57 David Mertz <mertz@gnosis.cx> wrote:
This definitely feels to me like though if an oddball case that "write your own function" seems like the best solution. I accept the OP needs it, but I have trouble imagining that many others would.
On Tue, Aug 4, 2020, 7:42 AM Dominik Vilsmeier <dominik.vilsmeier@gmx.de> wrote:
In one of my projects I'm reusing class-level type annotations to identify relevant attributes for serialization, e.g. similar to the following:
attrs = {name: getattr(obj, name) for name in get_type_hints(type(obj))}
This is convenient because it merges the type annotations from the various stages in the class hierarchy, e.g.
class Base: a: int class Derived(Base): b: str
results in `attrs == dict(a=..., b=...)`.
However it becomes inconvenient if external base classes are involved that define their own, unrelated type annotations, e.g.
class External: # from some other distribution unrelated: float class Base(External): a: int
It would be helpful if `get_type_hints` had a `boundary` parameter that, when used with a class object, determines the upper boundary for the MRO. So it could be used in the following way:
get_type_hints(type(derived_obj), boundary=Base)
to exclude any type annotations further up the class hierarchy (including the ones from `Base`).
Regarding the implementation this would effectively skip over base classes in the reverse MRO until it reaches the `boundary`.
What do you think? _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/T6K4DW... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OBZ5UE... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido (mobile)
On 04.08.20 22:05, Guido van Rossum wrote:
Maybe get-type-hints can be refactored to make writing such a function simpler. IIRC the part that takes a single annotation and evaluates it is a private function.
That's what I considered and indeed it relies on `typing._eval_type`. If this was public then all building blocks would be in place.
On Tue, Aug 4, 2020 at 12:57 David Mertz <mertz@gnosis.cx <mailto:mertz@gnosis.cx>> wrote:
This definitely feels to me like though if an oddball case that "write your own function" seems like the best solution. I accept the OP needs it, but I have trouble imagining that many others would.
On Tue, Aug 4, 2020, 7:42 AM Dominik Vilsmeier <dominik.vilsmeier@gmx.de <mailto:dominik.vilsmeier@gmx.de>> wrote:
In one of my projects I'm reusing class-level type annotations to identify relevant attributes for serialization, e.g. similar to the following:
attrs = {name: getattr(obj, name) for name in get_type_hints(type(obj))}
This is convenient because it merges the type annotations from the various stages in the class hierarchy, e.g.
class Base: a: int class Derived(Base): b: str
results in `attrs == dict(a=..., b=...)`.
However it becomes inconvenient if external base classes are involved that define their own, unrelated type annotations, e.g.
class External: # from some other distribution unrelated: float class Base(External): a: int
It would be helpful if `get_type_hints` had a `boundary` parameter that, when used with a class object, determines the upper boundary for the MRO. So it could be used in the following way:
get_type_hints(type(derived_obj), boundary=Base)
to exclude any type annotations further up the class hierarchy (including the ones from `Base`).
Regarding the implementation this would effectively skip over base classes in the reverse MRO until it reaches the `boundary`.
What do you think? _______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/T6K4DW... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OBZ5UE... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido (mobile)
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EMGFAB... Code of Conduct: http://python.org/psf/codeofconduct/
On Wed, Aug 5, 2020 at 12:25 AM Dominik Vilsmeier <dominik.vilsmeier@gmx.de> wrote:
On 04.08.20 22:05, Guido van Rossum wrote:
Maybe get-type-hints can be refactored to make writing such a function simpler. IIRC the part that takes a single annotation and evaluates it is a private function.
That's what I considered and indeed it relies on `typing._eval_type`. If this was public then all building blocks would be in place.
In that case I recommend that you create a bpo issue about adding it and submit a PR to resolve the issue. I think the public API should have the same defaults for globalns and localns as get_type_hints(), and it should probably not expose the recursive_guard argument. Since this is a new feature and the 3.9 release is already closed for new features, this can be added in 3.10 -- in earlier releases you'll have to use `_eval_type`. (It does not seem important enough to add it to the typing_extensions module.) -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
participants (3)
-
David Mertz
-
Dominik Vilsmeier
-
Guido van Rossum