intersection_examples icon indicating copy to clipboard operation
intersection_examples copied to clipboard

CPython implementation of intersections

Open tomasr8 opened this issue 2 years ago • 8 comments

This is my stab at a reference implementation of the Intersection type in CPython: https://github.com/tomasr8/cpython/tree/intersection-type Contributions/improvements welcome!

Build instructions:

https://devguide.python.org/getting-started/setup-building/ TLDR:

git remote add tomasr8 https://github.com/tomasr8/cpython
git fetch tomasr8
git checkout --track tomasr8/intersection-type
make clean && make -s -j2
./python

TODOs

  • [x] Intersection flattening (same as unions)
  • [x] fix some copy&paste errors - references to Union and UnionGenericAlias and some docstrings
  • [x] isinstance support
  • [ ] Incorporate https://github.com/python/cpython/pull/105511 when it gets merged

Example

from typing import Intersection

Intersection[int, str]
Intersection[int, float, int]  # == Intersection[int, float] (deduped)
Intersection[int, Intersection[float, str]]  # == Intersection[int, float, str] (flattened)
Intersection[int]  # == int

# overloaded __and__ for types
int & str
type(int & str)

class T: ...
T & int

class A: ...
class B: ...
class C(A, B): ...

a = A()
c = C()

isinstance(a, A & B)
isinstance(c, A & B)

tomasr8 avatar Jul 25 '23 18:07 tomasr8

Why create the Intersection name at all only to deprecate it immediately? Union only exists because | wasn't available.

NeilGirdhar avatar Jul 28 '23 05:07 NeilGirdhar

Because we can backport Intersection with typing_extensions making it available also to older python versions. The & will be only available with a newer Python version and nobody wants to way 2 Years for that...

Also some people will be forced to use older version for quite some time and we need backwards compatibility for them.

CarliJoy avatar Jul 28 '23 11:07 CarliJoy

Because we can backport Intersection with typing_extensions making it available also to older python versions.

Right, good point. BTW, you can still use & in annotations by using from __future__ import annotations, but I could see wanting to programmatically generate types.

NeilGirdhar avatar Jul 28 '23 11:07 NeilGirdhar

Also, Intersection should probably not be added to Python—just to typing-extensions.

NeilGirdhar avatar Jul 28 '23 13:07 NeilGirdhar

Also, Intersection should probably not be added to Python—just to typing-extensions.

Strongly disagree with this. typing_extensions is meant to be for backporting typing features, not having it in typing would create confusion.

Gobot1234 avatar Jul 31 '23 01:07 Gobot1234

Strongly disagree with this. typing_extensions is meant to be for backporting typing features, not having it in typing would create confusion.

Good point. I guess as long as the linters push back, that's enough to discourage unnecessary use of it.

NeilGirdhar avatar Jul 31 '23 01:07 NeilGirdhar

Late to the party here, but note that there is precedent for adding something to typing that is immediately sort-of-deprecated: PEP 646 added typing.Unpack so that we could add typing_extensions.Unpack while also adding new syntax that made it unnecessary to ever use typing.Unpack. Analogously we could add a typing.Intersection while simultaneously adding a & operator that means you (almost) never have to use typing.Intersection directly.

JelleZijlstra avatar Sep 07 '23 17:09 JelleZijlstra

Just an FYI, I rebased this on the latest CPython main

tomasr8 avatar Dec 14 '23 09:12 tomasr8