Skip to content
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

Implement PEP 649 and PEP 749 #119180

Open
14 of 29 tasks
JelleZijlstra opened this issue May 19, 2024 · 4 comments
Open
14 of 29 tasks

Implement PEP 649 and PEP 749 #119180

JelleZijlstra opened this issue May 19, 2024 · 4 comments
Assignees
Labels
3.14 new features, bugs and security fixes topic-typing

Comments

@JelleZijlstra
Copy link
Member

JelleZijlstra commented May 19, 2024

PEP-649 has been accepted and should be implemented in Python 3.14. Let's use this issue to track the implementation:

Things to revisit:

I am planning to work on the interpreter core first.

cc @larryhastings @carljm @samuelcolvin

Linked PRs

@JelleZijlstra JelleZijlstra added topic-typing 3.14 new features, bugs and security fixes labels May 19, 2024
@JelleZijlstra JelleZijlstra self-assigned this May 19, 2024
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue May 21, 2024
The PEP 649 implementation will require a way to load NotImplementedError
from the bytecode. @markshannon suggested implementing this by converting
LOAD_ASSERTION_ERROR into a more general mechanism for loading constants.

This PR adds this new opcode. I will work on the rest of the implementation
of the PEP separately.
JelleZijlstra added a commit that referenced this issue May 22, 2024
The PEP 649 implementation will require a way to load NotImplementedError
from the bytecode. @markshannon suggested implementing this by converting
LOAD_ASSERTION_ERROR into a more general mechanism for loading constants.

This PR adds this new opcode. I will work on the rest of the implementation
of the PEP separately.

Co-authored-by: Irit Katriel <[email protected]>
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue May 22, 2024
but did not actually apply the new magic number.
JelleZijlstra added a commit that referenced this issue May 25, 2024
PR #119321 added a comment about the magic number bump
but did not actually apply the new magic number.
@JelleZijlstra JelleZijlstra changed the title Implement PEP 649 Implement PEP 649 and PEP 749 Jun 11, 2024
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Jun 21, 2024
mrahtz pushed a commit to mrahtz/cpython that referenced this issue Jun 30, 2024
noahbkim pushed a commit to hudson-trading/cpython that referenced this issue Jul 11, 2024
noahbkim pushed a commit to hudson-trading/cpython that referenced this issue Jul 11, 2024
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
The PEP 649 implementation will require a way to load NotImplementedError
from the bytecode. @markshannon suggested implementing this by converting
LOAD_ASSERTION_ERROR into a more general mechanism for loading constants.

This PR adds this new opcode. I will work on the rest of the implementation
of the PEP separately.

Co-authored-by: Irit Katriel <[email protected]>
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
PR python#119321 added a comment about the magic number bump
but did not actually apply the new magic number.
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
estyxx pushed a commit to estyxx/cpython that referenced this issue Jul 17, 2024
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 23, 2024
…s and eval()

Often, ForwardRefs represent a single simple name. In that case, we
can avoid going through the overhead of creating AST nodes and code
objects and calling eval(): we can simply look up the name directly
in the relevant namespaces.
JelleZijlstra added a commit that referenced this issue Sep 23, 2024
…4326)

We were sometimes passing None as the globals argument to eval(), which makes it
inherit the globals from the calling scope. Instead, ensure that globals is always
non-None. The test was passing accidentally because I passed "annotationlib" as a
module object; fix that. Also document the parameters to ForwardRef() and remove
two unused private ones.

Co-authored-by: Alex Waygood <[email protected]>
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 24, 2024
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 24, 2024
Larry Hastings pointed out that using an illegal parameter name makes
it impossible to use inspect.signature() on annotate functions.

Cross-ref python/peps#3993.
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 25, 2024
JelleZijlstra added a commit that referenced this issue Sep 25, 2024
…tionlib (#124337)

Often, ForwardRefs represent a single simple name. In that case, we
can avoid going through the overhead of creating AST nodes and code
objects and calling eval(): we can simply look up the name directly
in the relevant namespaces.

Co-authored-by: Victor Stinner <[email protected]>
JelleZijlstra added a commit that referenced this issue Sep 25, 2024
)

From discussion with Larry Hastings and Carl Meyer, this is the desired
behavior.
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 25, 2024
emilyemorehouse added a commit to lysnikolaou/cpython that referenced this issue Sep 26, 2024
* main: (69 commits)
  Add "annotate" SET_FUNCTION_ATTRIBUTE bit to dis. (python#124566)
  pythongh-124412: Add helpers for converting annotations to source format (python#124551)
  pythongh-119180: Disallow instantiation of ConstEvaluator objects (python#124561)
  For-else deserves its own section in the tutorial (python#123946)
  Add 3.13 as a version option to the crash issue template (python#124560)
  pythongh-123242: Note that type.__annotations__ may not exist (python#124557)
  pythongh-119180: Make FORWARDREF format look at __annotations__ first (python#124479)
  pythonGH-58058: Add quick reference for `ArgumentParser` to argparse docs (pythongh-124227)
  pythongh-41431: Add `datetime.time.strptime()` and `datetime.date.strptime()` (python#120752)
  pythongh-102450: Add ISO-8601 alternative for midnight to `fromisoformat()` calls. (python#105856)
  pythongh-124370: Add "howto" for free-threaded Python (python#124371)
  pythongh-121277: Allow `.. versionadded:: next` in docs (pythonGH-121278)
  pythongh-119400:  make_ssl_certs: update reference test data automatically, pass in expiration dates as parameters python#119400  (pythonGH-119401)
  pythongh-119180: Avoid going through AST and eval() when possible in annotationlib (python#124337)
  pythongh-124448: Update Windows builds to use Tcl/Tk 8.6.15 (pythonGH-124449)
  pythongh-123884 Tee of tee was not producing n independent iterators (pythongh-124490)
  pythongh-124378: Update test_ttk for Tcl/Tk 8.6.15 (pythonGH-124542)
  pythongh-124513: Check args in framelocalsproxy_new() (python#124515)
  pythongh-101100: Add a table of class attributes to the "Custom classes" section of the data model docs (python#124480)
  Doc: Use ``major.minor`` for documentation distribution archive filenames (python#124489)
  ...
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 26, 2024
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 26, 2024
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue Sep 28, 2024
This is what Larry wants, and so it shall be. It's a bit of a hack,
but it's localized and not too bad.
@Jens-Dittrich
Copy link

Jens-Dittrich commented Oct 27, 2024

Hi everyone,

just wanted to share a (condensed) example where I had to use Forward references outside of type annotations, but in specific parameters of generics as below:

from typing import TypeVar, Generic


BaseClassType = TypeVar("BaseClassType")


class GenericClass(Generic[BaseClassType]):
    def a_method(self) -> BaseClassType:
        pass


class ConcreteClass(GenericClass["ConcreteFriendClass"]):
    pass


GenericClassType = TypeVar("GenericClassType", bound=GenericClass)


class GenericFriendClass(Generic[GenericClassType]):
    def a_method(self) -> GenericClassType:
        pass


class ConcreteFriendClass(GenericFriendClass[ConcreteClass]):
    pass


instance = ConcreteClass()
friend = ConcreteFriendClass()

res = instance.a_method()

Reason is, that ConcreteClass and ConcreteFriendClass are somehow coupled to each other from a business perspective. Not sure, the design is really great or could be improved, but what I want you guys to point you to is the statement of definition of Class ConcreteClass where the friend's class name is specified as forward reference. PyCharm is already able to correctly determine the type of variable res to be of ConcreteFriedClass - so it is at least ForwardReference-ish.

Question now, is this tbh quite corner case also in scope of the ticket, in that case I am glad to contribute above a test case. Just remove the Forward Reference in that line and it shall work. Or is it out of scope, maybe by a flaw of my own understanding or postponed to a later release etc.

EDIT:
I just happened to realise that I can retrieve the type parameter at runtime in 3.12 and it turns out to be a Forward Reference

from typing import get_args, ForwardRef
from types import get_original_bases

assert ForwardRef("ConcreteFriendClass") == get_args(get_original_bases(ConcreteClass)[0])[0]

/EDIT

Happy to have a conversation on that.

Regards, Jens

@JelleZijlstra
Copy link
Member Author

@Jens-Dittrich your use case is already solved in Python 3.12, where PEP-695 provides a syntax for generic bounds that is lazily evaluated. If you have further questions, please post on https://discuss.python.org instead so we can keep this issue focused on implementing the Python 3.14 changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.14 new features, bugs and security fixes topic-typing
Projects
None yet
Development

No branches or pull requests

3 participants