Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: compatibility with typing_extensions 4.13 and type statement #12472

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

Closed
wants to merge 3 commits into from

Conversation

Daraan
Copy link
Contributor

@Daraan Daraan commented Mar 26, 2025

typing_extensions 4.13 has a backport typing_extensions.TypeAliasType which differs from typing.TypeAliasType which is created though the type statement.

isinstance which only checks for the typing_extensions variant will return False which can lead to errors.

(future) TODOs:

  • add tests for typing.TypeAliasType

Fixes: #12473

@Daraan Daraan marked this pull request as draft March 26, 2025 17:46
@zzzeek
Copy link
Member

zzzeek commented Mar 26, 2025

hi -

we have been working with this change and we haven't seen a failing test case, do you have one?

@zzzeek
Copy link
Member

zzzeek commented Mar 26, 2025

oh we have one

@Daraan
Copy link
Contributor Author

Daraan commented Mar 26, 2025

I came here from python/typing_extensions#560 which I am looking into

VSCode was to eager in creating the PR :D

@Giuzzilla
Copy link

Giuzzilla commented Mar 26, 2025

I opened an issue with an example: #12473 (comment)

@CaselIT
Copy link
Member

CaselIT commented Mar 26, 2025

thanks for the pr. we will likely take it over since there is also a test to change, also there may be further cases were we are doing some assumptions

@Daraan Daraan marked this pull request as ready for review March 26, 2025 18:24
@CaselIT CaselIT requested a review from sqla-tester March 26, 2025 18:27
Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision 8861a5a of this pull request into gerrit so we can run tests and reviews and stuff

@sqla-tester
Copy link
Collaborator

New Gerrit review created for change 8861a5a: https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5825

@Daraan Daraan requested a review from sqla-tester March 26, 2025 19:26
Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Hi, this is sqla-tester and I see you've pinged me for review. However, user Daraan is not authorized to initiate CI jobs. Please wait for a project member to do this!

@CaselIT
Copy link
Member

CaselIT commented Mar 26, 2025

I've updated the change. I had to duplicate a bunch of tests sadly.
@zzzeek can you take a look? I've also added an utility to automate the "get type from both typing and typing_extension"

@Viicos
Copy link
Contributor

Viicos commented Mar 26, 2025

Heads up from Pydantic: there is an edge case that need to be taken into account in Python 3.10. For more context, see the definition of typing_inspection.typing_objects.is_typealiastype() (that we use internally).

A simplified implementation would look like:

def is_typealiastype(obj):
    return type(obj) is not types.GenericAlias and isinstance(obj, (typing.TypeAliasType, typing_extensions.TypeAliasType))

@CaselIT
Copy link
Member

CaselIT commented Mar 26, 2025

when would that happen? if you use [] on a TypeAliasType?

@CaselIT
Copy link
Member

CaselIT commented Mar 26, 2025

when would that happen? if you use [] on a TypeAliasType?

seems so. it wasn't taken into consideration at all the generic typealiastype case. should not be hard to handle, but I think for sqlalchemy we should consider the generic alias of tat a tat

@CaselIT
Copy link
Member

CaselIT commented Mar 26, 2025

when would that happen? if you use [] on a TypeAliasType?

seems so. it wasn't taken into consideration at all the generic typealiastype case. should not be hard to handle, but I think for sqlalchemy we should consider the generic alias of tat a tat

for how we use this check in sqlalchemy it seems it's already accounted for since the generic types are stripped. will update the fn in any case just to be safe

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Federico Caselli (CaselIT) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/orm/declarative/test_typed_mapping.py (line 1298): this part is only on 2.0

@sqla-tester
Copy link
Collaborator

Federico Caselli (CaselIT) wrote:

the backport to 2.0 has some different test

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5825

@sqla-tester
Copy link
Collaborator

Michael Bayer (zzzeek) wrote:

recheck

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5825

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Michael Bayer (zzzeek) wrote:

recheck

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/orm/declarative/test_typed_mapping.py (line 1298): Done

@sqla-tester
Copy link
Collaborator

Federico Caselli (CaselIT) wrote:

it seems that 3.7 needs special handling

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

@Daraan
Copy link
Contributor Author

Daraan commented Mar 27, 2025

Federico Caselli (CaselIT) wrote:

it seems that 3.7 needs special handling

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

I have a fix for at least one; can I commit it here or work with gerrit? If the later can you give me a quick rundown how to push/commit to it

@CaselIT
Copy link
Member

CaselIT commented Mar 27, 2025

no commits here will be ignored since the change in gerrit is quite a bit different.

It's likely easier if you post a diff here. Note that I was inclined to just skip that on 3.7. No one is using type alias types on it.

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Daraan (Daraan) wrote:

Patch for the 3.7 tests as the TAT attributes are not availiable on a subscripted TATA (_GenericAlias)

diff --git a/test/base/test_typing_utils.py b/test/base/test_typing_utils.py
index bc83c5f2c..a9976c03a 100644
--- a/test/base/test_typing_utils.py
+++ b/test/base/test_typing_utils.py
@@ -425,21 +425,40 @@ class TestTyping(fixtures.TestBase):
         # generics
         eq_(sa_typing.pep695_values(TA_generic), {typing.List[TV]})
         eq_(sa_typing.pep695_values(TAext_generic), {typing.List[TV]})
-        eq_(sa_typing.pep695_values(TA_generic_typed), {typing.List[TV]})
-        eq_(sa_typing.pep695_values(TAext_generic_typed), {typing.List[TV]})
         eq_(sa_typing.pep695_values(TA_generic_null), {None, typing.List[TV]})
         eq_(
             sa_typing.pep695_values(TAext_generic_null),
             {None, typing.List[TV]},
         )
-        eq_(
-            sa_typing.pep695_values(TA_generic_null_typed),
-            {None, typing.List[TV]},
-        )
-        eq_(
-            sa_typing.pep695_values(TAext_generic_null_typed),
-            {None, typing.List[TV]},
-        )
+        if py38:
+            eq_(sa_typing.pep695_values(TA_generic_typed), {typing.List[TV]})
+            eq_(sa_typing.pep695_values(TAext_generic_typed), {typing.List[TV]})
+            eq_(
+                sa_typing.pep695_values(TAext_generic_null_typed),
+                {None, typing.List[TV]},
+            )
+            eq_(
+                sa_typing.pep695_values(TA_generic_null_typed),
+                {None, typing.List[TV]},
+            )
+        else:
+            # for 3.7 the attributes are only available on the origin
+            eq_(sa_typing.pep695_values(
+                typing_extensions.get_origin(TA_generic_typed)),
+                {typing.List[TV]}
+            )
+            eq_(sa_typing.pep695_values(
+                typing_extensions.get_origin(TAext_generic_typed)),
+                {typing.List[TV]}
+            )
+            eq_(sa_typing.pep695_values(
+                typing_extensions.get_origin(TAext_generic_null_typed)),
+                {None, typing.List[TV]}
+            )
+            eq_(
+                sa_typing.pep695_values(typing_extensions.get_origin(TA_generic_null_typed)),
+                {None, typing.List[TV]},
+            )
 
     def test_is_fwd_ref(self):
         eq_(sa_typing.is_fwd_ref(int), False)
@@ -526,9 +545,20 @@ class TestTyping(fixtures.TestBase):
         for t in type_aliases() + new_types():
             if t in false_negatives:
                 exp = False
-            else:
+            elif py38:
                 exp = "null" in t.__name__
-            eq_(sa_typing.includes_none(t), exp, str(t))
+                eq_(sa_typing.includes_none(t), exp, str(t))
+            else:
+                # on 3.7 the attributes are only available on the origin
+                origin = typing_extensions.get_origin(t)
+                if origin is None:
+                    # normal TypeAliasType
+                    exp = "null" in t.__name__
+                    eq_(sa_typing.includes_none(t), exp, str(t))
+                else:
+                    # subscripted TypeAliasType
+                    exp = "null" in origin.__name__
+                    eq_(sa_typing.includes_none(origin), exp, str(t))
 
         for t in annotated_l():
             eq_(

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/base/test_typing_utils.py (line 428): fix for 3.7 tests:
    the attributes are not forwarded to a subscribed TypeAliasType -> _GenericAlias
diff --git a/test/base/test_typing_utils.py b/test/base/test_typing_utils.py
index bc83c5f2c..a9976c03a 100644
--- a/test/base/test_typing_utils.py
+++ b/test/base/test_typing_utils.py
@@ -425,21 +425,40 @@ class TestTyping(fixtures.TestBase):
         # generics
         eq_(sa_typing.pep695_values(TA_generic), {typing.List[TV]})
         eq_(sa_typing.pep695_values(TAext_generic), {typing.List[TV]})
-        eq_(sa_typing.pep695_values(TA_generic_typed), {typing.List[TV]})
-        eq_(sa_typing.pep695_values(TAext_generic_typed), {typing.List[TV]})
         eq_(sa_typing.pep695_values(TA_generic_null), {None, typing.List[TV]})
         eq_(
             sa_typing.pep695_values(TAext_generic_null),
             {None, typing.List[TV]},
         )
-        eq_(
-            sa_typing.pep695_values(TA_generic_null_typed),
-            {None, typing.List[TV]},
-        )
-        eq_(
-            sa_typing.pep695_values(TAext_generic_null_typed),
-            {None, typing.List[TV]},
-        )
+        if py38:
+            eq_(sa_typing.pep695_values(TA_generic_typed), {typing.List[TV]})
+            eq_(sa_typing.pep695_values(TAext_generic_typed), {typing.List[TV]})
+            eq_(
+                sa_typing.pep695_values(TAext_generic_null_typed),
+                {None, typing.List[TV]},
+            )
+            eq_(
+                sa_typing.pep695_values(TA_generic_null_typed),
+                {None, typing.List[TV]},
+            )
+        else:
+            # for 3.7 the attributes are only available on the origin
+            eq_(sa_typing.pep695_values(
+                typing_extensions.get_origin(TA_generic_typed)),
+                {typing.List[TV]}
+            )
+            eq_(sa_typing.pep695_values(
+                typing_extensions.get_origin(TAext_generic_typed)),
+                {typing.List[TV]}
+            )
+            eq_(sa_typing.pep695_values(
+                typing_extensions.get_origin(TAext_generic_null_typed)),
+                {None, typing.List[TV]}
+            )
+            eq_(
+                sa_typing.pep695_values(typing_extensions.get_origin(TA_generic_null_typed)),
+                {None, typing.List[TV]},
+            )
  • test/base/test_typing_utils.py (line 530): In 3.7 a subscripted typing_extensions.TypeAliasType is a rather simple typing._GenericAlias; it lacks a __name__ field causing the tests to fail.
get_origin(t).__name__

will work with 3.7:

patch:

diff --git a/test/base/test_typing_utils.py b/test/base/test_typing_utils.py
index bc83c5f2c..04b3aa6c1 100644
--- a/test/base/test_typing_utils.py
+++ b/test/base/test_typing_utils.py
@@ -526,9 +545,20 @@ class TestTyping(fixtures.TestBase):
         for t in type_aliases() + new_types():
             if t in false_negatives:
                 exp = False
-            else:
+            elif py38:
                 exp = "null" in t.__name__
-            eq_(sa_typing.includes_none(t), exp, str(t))
+                eq_(sa_typing.includes_none(t), exp, str(t))
+            else:
+                # on 3.7 the attributes are only available on the origin
+                origin = typing_extensions.get_origin(t)
+                if origin is None:
+                    # normal TypeAliasType
+                    exp = "null" in t.__name__
+                    eq_(sa_typing.includes_none(t), exp, str(t))
+                else:
+                    # subscripted TypeAliasType
+                    exp = "null" in origin.__name__
+                    eq_(sa_typing.includes_none(origin), exp, str(t))
 
         for t in annotated_l():
             eq_(

@Daraan
Copy link
Contributor Author

Daraan commented Mar 27, 2025

no commits here will be ignored since the change in gerrit is quite a bit different.

It's likely easier if you post a diff here. Note that I was inclined to just skip that on 3.7. No one is using type alias types on it.

Posted a diff on gerrit; sadly I cannot edit there :/, hmm maybe on the original 5825?.

I had a bit trouble with disambiguating "no, commits here will be ignored" and "no commits will be ignored"😄, but I think I got it correctly that they are ignored.

@CaselIT
Copy link
Member

CaselIT commented Mar 27, 2025

I'm inclined to just skip those types in 37, since the lib code also seems to require an update, since it errors with

AttributeError: value

in

sqlalchemy/util/typing.py", line 387, in recursive_value
    value = inner_type.__value__

@Daraan
Copy link
Contributor Author

Daraan commented Mar 27, 2025

I'm inclined to just skip those types in 37, since the lib code also seems to require an update, since it errors with

AttributeError: value

in

sqlalchemy/util/typing.py", line 387, in recursive_value
    value = inner_type.__value__

Yes, makes more sense, and should be easier, to update the utility function for the py3.7 case :)

@CaselIT
Copy link
Member

CaselIT commented Mar 27, 2025

I think it's fine if we just tell people that use TAT on 3.7 to update the python version :)

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Federico Caselli (CaselIT) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/base/test_typing_utils.py (line 333): I'm not sure why this test has run even with this requires in the laterts pipeline

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Michael Bayer (zzzeek) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/base/test_typing_utils.py (line 333): I didnt test it b.c. i didnt have a python 3.7 here. ill go onto the jenkins worker and investigate

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Michael Bayer (zzzeek) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/base/test_typing_utils.py (line 333): the git checkout on the worker failed in an entirely new and very ominous way. going to see if it was a one off

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Federico Caselli (CaselIT) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/base/test_typing_utils.py (line 333): > Took 7 sec on ryzen1

always it :(

Copy link
Collaborator

@sqla-tester sqla-tester left a comment

Choose a reason for hiding this comment

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

Michael Bayer (zzzeek) wrote:

code review left on gerrit

View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826

  • test/base/test_typing_utils.py (line 428): the combination of these patches are failing and I'm not able to apply them, also I can't cut and paste from gerrit very easily since it does not allow me to scroll. I am going to get the python38 decorators through first, if you want to create a complete patch for all fixes in a single file you can attach it to the PR or github issue

@sqla-tester
Copy link
Collaborator

Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5825 has been merged. Congratulations! :)

@sqla-tester
Copy link
Collaborator

Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/5826 has been merged. Congratulations! :)

sqlalchemy-bot pushed a commit that referenced this pull request Mar 27, 2025
Fixed regression caused by ``typing_extension==4.13.0`` that introduced
a different implementation for ``TypeAliasType`` while SQLAlchemy assumed
that it would be equivalent to the ``typing`` version.

Added test regarding generic TypeAliasType

Fixes: #12473
Closes: #12472
Pull-request: #12472
Pull-request-sha: 8861a5a

Change-Id: I053019a222546a625ed6d588314ae9f5b34c2f8a
(cherry picked from commit 61970f9d2b7809116b5a9d339b45d910e276b428)
@Daraan
Copy link
Contributor Author

Daraan commented Mar 27, 2025

A big thanks @ everyone for taking this over so fast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

typing-extensions 4.13.0 possibly breaks ORM declarative codepaths that are deprecated in 2.0
6 participants