GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-105499: Merge typing.Union and types.UnionType by JelleZijlstra · Pull Request #105511 · python/cpython

Conversation

@JelleZijlstra

@JelleZijlstra JelleZijlstra commented Jun 8, 2023 •
edited by github-actions Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member
  • Issue: Merge typing.Union and types.UnionType #105499

📚 Documentation preview 📚: https://cpython-previews--105511.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ParthSareen and shahshahii reacted with thumbs up emoji johnslavik and shahshahii reacted with hooray emoji
All reactions
  • 👍 2 reactions
  • 🎉 2 reactions
JelleZijlstra added 6 commits June 8, 2023 01:36
@JelleZijlstra
Unify UnionType and Union
8c8b1dd
@JelleZijlstra
test_typing succeeds
aba63eb
@JelleZijlstra
Merge remote-tracking branch 'upstream/main' into unifyunion
f2f23a0
@JelleZijlstra
blurb
e75282f
@JelleZijlstra
Fix test_types
540b04b
@JelleZijlstra
Documentation
ae8fa62
@bedevere-bot bedevere-bot mentioned this pull request Jun 8, 2023
Merge typing.Union and types.UnionType #105499
Closed
JelleZijlstra added 2 commits June 8, 2023 08:09
@JelleZijlstra
stray f
7569c48
@JelleZijlstra
Fix tests
8bcb930
AlexWaygood
AlexWaygood reviewed Jun 8, 2023
View reviewed changes
Comment thread Lib/test/test_typing.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood

AlexWaygood commented Jun 8, 2023

Copy link
Copy Markdown
Member

Would we be able to get rid of typing._make_union, and just have TypeVar etc. call UnionType.__class_getitem__ directly?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra

JelleZijlstra commented Jun 8, 2023

Copy link
Copy Markdown
Member Author

Would we be able to get rid of typing._make_union, and just have TypeVar etc. call UnionType.__class_getitem__ directly?

Yes

AlexWaygood reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra
No more typing._make_union
291953e
@AlexWaygood

AlexWaygood commented Jun 8, 2023

Copy link
Copy Markdown
Member

Instead of deleting typing.Union completely, adding UnionType.__class_getitem__, and making typing.Union an alias for types.UnionType, I wonder if we could just change typing.Union so that it's a special form that just returns instances of UnionType:

from operator import or_
from functools import reduce

@_SpecialForm
def Union(self, parameters):
    return reduce(or_, parameters)

That would avoid the issue of "Should we rename types.UnionType to be Union", as we'd keep them as distinct objects.

But I know your plan is to deal with handling forward refs in | expressions later, which would mean that^ idea above wouldn't work right now (unions involving forward references would break).

So perhaps you could instead expose a _secret_undocumented_constructor method for types.UnionType (we can bikeshed over the name), and then just do

@_SpecialForm
def Union(self, parameters):
    return types.UnionType._secret_undocumented_constructor(parameters)

Or we could just expose the constructor of types.UnionType, of course.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood

AlexWaygood commented Jun 8, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Also you can now get rid of this function as part of this PR; prior callers of the function can now just use isinstance() checks against types.UnionType:

cpython/Lib/functools.py

Lines 842 to 844 in 6a8b862

def _is_union_type(cls):
from typing import get_origin, Union
return get_origin(cls) in {Union, types.UnionType}

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra

JelleZijlstra commented Jun 8, 2023

Copy link
Copy Markdown
Member Author

That would avoid the issue of "Should we rename types.UnionType to be Union", as we'd keep them as distinct objects.

I'd rather not keep them as distinct objects, though; that means we still have two objects that to a user look like the same thing. Plus, we'd have get_origin(Union[int, str]) != Union.

moi90 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood

AlexWaygood commented Jun 8, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I guess one of my reservations here is that UnionType ends up looking like a pretty weird type. You can't construct instances of it directly:

>>> from types import UnionType
>>> UnionType(int, str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot create 'types.UnionType' instances

...Except wait, you can, we now have a "secret __class_getitem__ backdoor" to create instances directly:

>>> UnionType[int, str, bytes]
int | str | bytes

It's very unusual for __class_getitem__ to just directly return instances of the class, and it feels really weird to make that the only way you're allowed to construct instances of the class.

Maybe that means we should just expose the constructor as well as adding __class_getitem__...?

Plus, we'd have get_origin(Union[int, str]) != Union.

Good point, that would indeed be confusing.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra

JelleZijlstra commented Jun 8, 2023

Copy link
Copy Markdown
Member Author

I can make the constructor work. Should it take *args and union them all together?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@AlexWaygood

AlexWaygood commented Jun 8, 2023

Copy link
Copy Markdown
Member

I can make the constructor work. Should it take *args and union them all together?

That makes sense to me!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

JelleZijlstra added 3 commits June 8, 2023 18:25
@JelleZijlstra
Add tp_new
f7ca8d4
@JelleZijlstra
fix a refleak
0f1ab18
@JelleZijlstra
Fix test
eb47a0b
@JelleZijlstra
JelleZijlstra marked this pull request as ready for review June 9, 2023 04:10
@JelleZijlstra
JelleZijlstra requested review from Fidget-Spinner, ericvsmith, gvanrossum, markshannon and rhettinger as code owners June 9, 2023 04:10
@bedevere-bot bedevere-bot added the awaiting core review label Jun 9, 2023
AlexWaygood
AlexWaygood reviewed Jun 9, 2023
View reviewed changes

@AlexWaygood AlexWaygood left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, in my opinion. From a design perspective, the only weirdnesses I can see are that both of these become valid at runtime:

from types import UnionType
from typing import Union

UnionType[int, str]
Union(int, str)

I can live with that, though, and hopefully linters can flag those uses. (Type checkers almost certainly will, anyway.) On our side, we can just not document that you can do either of those things.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
JelleZijlstra added 3 commits September 28, 2024 14:53
@JelleZijlstra
simplify, extend docs
5f9e599
@JelleZijlstra
fix more tests
9927b38
@JelleZijlstra
another
eea6eca
JelleZijlstra
JelleZijlstra commented Sep 29, 2024
View reviewed changes
Comment thread Lib/test/test_types.py
x < y
# Check that we don't crash if typing.Union does not have a tuple in __args__
y = typing.Union[str, int]
y.__args__ = [str, int]

@JelleZijlstra JelleZijlstra Sep 28, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.__args__ is no longer writable.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/test/test_types.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Lib/test/test_types.py

bt = BadType('bt', (), {})
bt2 = BadType('bt2', (), {})
# Comparison should fail and errors should propagate out for bad types.

@JelleZijlstra JelleZijlstra Sep 28, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the new code there are fewer code paths that trigger the equality comparison.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
JelleZijlstra added 3 commits September 29, 2024 06:26
@JelleZijlstra
change hash
0785951
@JelleZijlstra
Merge remote-tracking branch 'upstream/main' into unifyunion
1a39ded
@JelleZijlstra
Merge branch 'main' into unifyunion
eddbfde
@ParthSareen ParthSareen mentioned this pull request Nov 12, 2024
Passing Functions as Tools ollama/ollama-python#321
Merged
@JelleZijlstra
Merge branch 'main' into unifyunion
3ec9271
@JelleZijlstra

JelleZijlstra commented Mar 3, 2025

Copy link
Copy Markdown
Member Author

It's been long enough, I'm planning to merge this once the tests pass again.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra
tweak docs
cab69f0
@JelleZijlstra JelleZijlstra added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Mar 3, 2025
@bedevere-bot

bedevere-bot commented Mar 3, 2025

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @JelleZijlstra for commit cab69f0 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F105511%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Mar 3, 2025
@JelleZijlstra
JelleZijlstra merged commit dc6d66f into python:main Mar 4, 2025
@bedevere-app bedevere-app Bot removed the awaiting merge label Mar 4, 2025
@AA-Turner AA-Turner mentioned this pull request Mar 6, 2025
autosummary: Update test for Python 3.14.0a5+ sphinx-doc/sphinx#13418
Merged
@illia-v illia-v mentioned this pull request Mar 27, 2025
Python 3.14 CI failures due to httpcore issue urllib3/urllib3#3576
Closed
@Viicos Viicos mentioned this pull request Mar 29, 2025
Update typing.Union and types.UnionType definitions for 3.14 python/typeshed#13740
Draft
@hugovk hugovk mentioned this pull request Mar 31, 2025
3.14 regression: Union[int, str] is Union[int, str] does not hold #131933
Closed
@hugovk

hugovk commented Mar 31, 2025

Copy link
Copy Markdown
Member

This PR causes a potential regression: #131933.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this pull request Mar 31, 2025
@JelleZijlstra
typing: Remove an unused function
8d9d071
Leftover from python#105511 I believe. GitHub code search found no usages other
than copies of typing.py and lists of stdlib functions.
@JelleZijlstra JelleZijlstra mentioned this pull request Mar 31, 2025
gh-105499: typing: Remove an unused function #131946
Merged
JelleZijlstra added a commit that referenced this pull request Mar 31, 2025
@JelleZijlstra
gh-105499: typing: Remove an unused function (#131946)
0f511d8
Leftover from #105511 I believe. GitHub code search found no usages other
than copies of typing.py and lists of stdlib functions.
@XuehaiPan XuehaiPan mentioned this pull request Apr 5, 2025
typing.Union does not support attribute assignment post gh-105511 #132139
Closed
@neutrinoceros neutrinoceros mentioned this pull request May 12, 2025
typing._UnionGenericAlias is unhashable in 3.14 #133925
Closed
@cdce8p cdce8p mentioned this pull request May 15, 2025
Initial fixes for Python 3.14 pylint-dev/astroid#2747
Merged
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this pull request Sep 16, 2025
@serhiy-storchaka
pythongh-137065: Revert "pythongh-105499: Merge typing.Union and type…
efdd228
…s.UnionType (python#105511)"

This reverts commit d1db43c.
This reverts commit 0f511d8.
This reverts commit dc6d66f.
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this pull request Sep 16, 2025
@serhiy-storchaka
pythongh-137065: Revert "pythongh-105499: Merge typing.Union and type…
5cd4a72
…s.UnionType (python#105511)"

This reverts commit d1db43c.
This reverts commit 0f511d8.
This reverts commit dc6d66f.
@Maxinho96 Maxinho96 mentioned this pull request Jul 18, 2026
Literal[...] deduplication silently skips when values are unhashable #153896
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@gvanrossum gvanrossum gvanrossum left review comments
@Fidget-Spinner Fidget-Spinner Fidget-Spinner left review comments
@kumaraditya303 kumaraditya303 kumaraditya303 left review comments
@carljm carljm carljm approved these changes
@ericvsmith ericvsmith Awaiting requested review from ericvsmith ericvsmith is a code owner
@markshannon markshannon Awaiting requested review from markshannon
@AlexWaygood AlexWaygood Awaiting requested review from AlexWaygood AlexWaygood is a code owner
+1 more reviewer
@Gobot1234 Gobot1234 Gobot1234 left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

9 participants

@JelleZijlstra @AlexWaygood @carljm @bedevere-bot @hugovk @gvanrossum @Fidget-Spinner @Gobot1234 @kumaraditya303
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.