Hi Philippe and list,
Long time lurker here, I've had a few spare cycles at $work this week that I
spent exploring an alternate implementation to PEP604 starting with the
implementation from Philippe. I don't say "reference implementation", because
it doesn't implement PEP604 faithfully, but it does try to implement it's goal.
My thinking was that the "runtime" component to it only needs to support the
isinstance/issubclass methods and so can be pretty minimal without need to
import all the typing.py machinery. At which point, when actual type checking
was done (anything in typing.py or mypy), the `union` type can be special
cased, or promoted to a `typing.Union`.
I started by creating a built-in "union" type, that was a thin wrapper around a
tuple, such that type.__or__ will return `union(lhs, rhs)` which stored the two
items in a 2-length tuple. I also changed the methods in `typing.Union` to
return a `union`. However, I hit my first issue: `int | int | str` would then
return `union(int, union(int, str))`, whereas it should deduplicate the types.
So, I implemented logic to detect and merge union | union, but changed the
underlying data to a plain flat tuple. And the next issue I hit was that some
of the other `typing.py` types weren't being detected as valid types (probably
due to my limited understanding of the PyObject datastructure/flags),
specifically, `int | "forwardref"`, I needed a way to signal to typing.py that
I had a forwardref without importing it. This is where I changed my approach to
the problem.
I wanted to find a way to have these metatypes (Union/TypeVar/ForwardRef)
without re-implementing them in c, or importing them. My Idea was to change the
builtin type to what I called a "shadow type". In the C layer it's just holds a
tuple of objects/parameters, and has a type field to say what it is, then when
in the type checking/typing.py layer, if it detects an object is a
"shadowobject", then it promotes it to a full type. What I liked about this
approach, is that for isinstance/issubclass, when it see a "shadowobject" it
can just grab the underlying types from the shadowobject->params tuple and no
import magic needs to happen. All of the type magic can be left to
mypy/typing.py without much knowledge of the shadowobject. I've mostly got
through this implementation with all but one test passing.
At this point, I've got as far as I can go without help, so I'm posting here,
looking for feedback or discussion. I expect that maybe the next step should be
me commenting on the PEP604 itself for implementation concerns regarding
`_GenericAlias`?
Implementation is located at https://github.com/Naddiseo/cpython/tree/PEP604
Richard
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/python-dev@python.org/message/P56ZE6USNIGCQU5PIOLKC65VHD5DM37U/
Code of Conduct: http://python.org/psf/codeofconduct/