Opened 4 weeks ago

Closed 4 weeks ago

Last modified 4 weeks ago

#36978 closed Uncategorized (invalid)

Should django evaluate typing annotations at all?

Reported by: 93578237 Owned by:
Component: Core (Other) Version: 5.2
Severity: Normal Keywords: typing, inspect, deferred annotations
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I previously opened a bug report #36903 related to deferred annotations in Python 3.14. I believe Django does not need to evaluate annotations using annotationlib.Format.FORWARDREF and could instead use annotationlib.Format.STRING.

Change History (3)

comment:1 by Jacob Walls, 4 weeks ago

Component: UncategorizedCore (Other)
Resolution: invalid
Status: newclosed

Thanks, but I don't quite follow, doesn't FORWARDREF leave the annotations unevaluated? I think I benched this at the time and found it was faster than STRING. It's also more friendly for any package extending Django's behavior, since it makes fewer assumptions.

Last edited 4 weeks ago by Jacob Walls (previous) (diff)

comment:2 by 93578237, 4 weeks ago

from inspect import *; from annotationlib import *; from typing import *

if TYPE_CHECKING: x = int

def foo(a: x) -> None: ...

In [4]: %timeit signature(foo, annotation_format=Format.FORWARDREF)
25 μs ± 445 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [5]: %timeit signature(foo, annotation_format=Format.STRING)
12.4 μs ± 495 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

What am I missing?

comment:3 by Jacob Walls, 4 weeks ago

Good question. Sorry, I wasn't trying to hide details, I just needed to recall what I benched. I benched the case where the annotations are available (e.g. not guarded under TYPE_CHECKING, which is IMO more likely):

In [13]: class Imported:
    ...:     ...
    ...: 

In [14]: def foo(a: Imported, b: Imported, c: Imported): ...

In [15]: %timeit signature(foo, annotation_format=Format.FORWARDREF)
4.52 μs ± 177 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [16]: %timeit signature(foo, annotation_format=Format.STRING)
7.59 μs ± 37.3 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
Note: See TracTickets for help on using tickets.
Back to Top