Skip to content

Start PEP 728 implementation #519

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

Merged
merged 19 commits into from
Mar 18, 2025
Merged

Conversation

JelleZijlstra
Copy link
Member

Early version but need to get this code off the laptop where it currently lives

@JelleZijlstra JelleZijlstra marked this pull request as ready for review February 11, 2025 03:37
@JelleZijlstra
Copy link
Member Author

OK this is finally ready for review.

@Daraan
Copy link
Contributor

Daraan commented Feb 11, 2025

A few days ago I made a PR #1 against your fork branch. Addressing this statement from the PEP:

If closed is not passed, the value of closed is None.

@Daraan
Copy link
Contributor

Daraan commented Feb 12, 2025

I realized python/cpython#109544 is missing

-            if not hasattr(tp_dict, '__total__'):
-                tp_dict.__total__ = total
+           tp_dict.__total__ = total

Resulting in a different behavior when using it outside of the spec, i.e. it being the value and not True.

class TD_with_total(TypedDict):
   __total__ = "I want a total value here"

Copy link
Contributor

@Daraan Daraan left a comment

Choose a reason for hiding this comment

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

From my understanding, this example in the PEP should pass without any errors or warnings:

class BaseMovie(TypedDict, closed=True):
    name: str

class MovieA(BaseMovie):  # OK, still closed
    pass

Currently this does raise a warning; so I think the relevant check should be closed is False (see suggestion below).

This will cause quite a few with self.assertWarns(DeprecationWarning): to fail afterwards which then need a look-over.


From another side should we even check this, or should this only be handled by type-checkers?

It is a type checker error to pass closed=False if a superclass has closed=True or sets extra_items.

Copy link
Contributor

@Daraan Daraan left a comment

Choose a reason for hiding this comment

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

Looking at the runtime specifications once more. __extra_items__ currently should also reflect the constructor and closed=True => extra_items=Never is only implicitly implied/equivalent. Suggested the necessary changes for that.

Also, suggested the GrandGrandChild as an example of an implicit closed subclass. I think such a thing was still missing.

@JelleZijlstra
Copy link
Member Author

I realized python/cpython#109544 is missing

Good catch, I guess when we made that change in CPython we didn't think about the fact that you could set something in the class body. Would you be interested in (1) adding a test case to CPython where there is an assignment to __total__ in the class body and (2) backporting python/cpython#109544 to typing-extensions?

@Daraan
Copy link
Contributor

Daraan commented Feb 22, 2025

Is a new entry to the changelog necessary? Else looks good to me.


(1) you have seen already, (2) added #533

@@ -877,6 +878,59 @@ def inner(func):
return inner


if not hasattr(typing, "NoDefault") or not hasattr(typing, "NoExtraItems"):
class SingletonMeta(type):
Copy link
Collaborator

Choose a reason for hiding this comment

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

kind of surprised we bothered. tbh if someone wants to do type(NoDefault).asdf = 123 i could live with that

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess I did it initially for parity with the C version in CPython for NoDefault, where it's easier to not accept extra attributes, and now that I need another one it makes sense to follow the pattern.

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

Basically LGTM, a few nits

Comment on lines +998 to +999
if closed is not None and extra_items is not NoExtraItems:
raise TypeError(f"Cannot combine closed={closed!r} and extra_items")
Copy link
Member

Choose a reason for hiding this comment

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

I think this branch may also be uncovered, but feel free to merge and tackle this as a followup!

@JelleZijlstra JelleZijlstra merged commit 75c95c4 into python:main Mar 18, 2025
23 checks passed
@JelleZijlstra JelleZijlstra deleted the pep728 branch March 18, 2025 17:35
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.

4 participants