Skip to content

Conversation

@jacobtylerwalls
Copy link
Member

Trac ticket number

ticket-36712

Branch description

Python 3.14 introduces deferred evaluation of type annotations, which can make headaches around circular definitions go away.

inspect.getfullargspec wasn't updated to take the new annotation_format arg that was provided to let inspecting libraries (us) avoid eagerly evaluating user annotations, see python/cpython#141560.

One solution would have been to copy and paste the entire function--along with importing the seven or eight other symbols it needed--and do the tweak, long-term forking the implementation.

Instead, patching the module helper anticipating the change we want Python to make felt more future-proof and sufficiently self-documenting. However, I'm happy to swap this out for a copy-and-paste approach if that's preferable, but we'd want to redistribute the python license in that case, I suppose?

Ideally, this will be reverted when an upstream solution is available for python/cpython#141560.

Thanks Patrick Rauscher for the report and Augusto Pontes for the first iteration and test.

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

…istration.

Ideally, this will be reverted when an upstream solution is available for
python/cpython#141560.

Thanks Patrick Rauscher for the report and Augusto Pontes for the
first iteration and test.
Copy link
Contributor

@nessita nessita left a comment

Choose a reason for hiding this comment

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

Looks good, added a few naming suggestions. Thank you! 🌟

annotation_format=annotationlib.Format.FORWARDREF,
)

lock = threading.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this lock also be inside the if PY314: guard?

yield
return
with lock:
helper_was_already_replaced = False
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest using the slightly shorter:

Suggested change
helper_was_already_replaced = False
helper_was_replaced = False



@contextmanager
def leave_deferred_annotations_unevaluated():
Copy link
Contributor

Choose a reason for hiding this comment

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

How about:

Suggested change
def leave_deferred_annotations_unevaluated():
def lazy_deferred_annotations():

Comment on lines +30 to +32
* Fixed a bug where template tag functions relying on the Python 3.14 behavior
of deferred evaluation of type annotations could not be registered
(:ticket:`36712`).
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the bug in 5.2? or in 5.2.8? ideally we should be explicit about that. Also how about:

Suggested change
* Fixed a bug where template tag functions relying on the Python 3.14 behavior
of deferred evaluation of type annotations could not be registered
(:ticket:`36712`).
* Fixed a crashed in Django 5.2 and Python 3.14+ that prevented template tag
functions from being registered when their type annotations required deferred
evaluation (:ticket:`36712`).

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.

3 participants