Skip to content

Commit d08c226

Browse files
committed
Improve the wording around string references in the spec
1 parent 7627175 commit d08c226

File tree

2 files changed

+11
-29
lines changed

2 files changed

+11
-29
lines changed

conformance/tests/annotations_forward_refs.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,9 @@ def invalid_annotations(
5757
pass
5858

5959

60-
# > It should evaluate without errors once the module has been fully loaded.
61-
# > The local and global namespace in which it is evaluated should be the same
62-
# > namespaces in which normal non-string types would be evaluated.
63-
60+
# > Names within the expression are looked up in the same way as they would be
61+
# > looked up at runtime in Python 3.14 and higher if the annotation was not
62+
# > enclosed in a string literal.
6463

6564
class ClassB:
6665
def method1(self) -> ClassB: # E?: Runtime error prior to 3.14

docs/spec/annotations.rst

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -222,31 +222,14 @@ String annotations
222222
When a type hint cannot be evaluated at runtime, that
223223
definition may be expressed as a string literal, to be resolved later.
224224

225-
A situation where this occurs commonly is the definition of a
226-
container class, where the class being defined occurs in the signature
227-
of some of the methods. For example, the following code (the start of
228-
a simple binary tree implementation) does not work::
229-
230-
class Tree:
231-
def __init__(self, left: Tree, right: Tree):
232-
self.left = left
233-
self.right = right
234-
235-
To address this, we write::
236-
237-
class Tree:
238-
def __init__(self, left: 'Tree', right: 'Tree'):
239-
self.left = left
240-
self.right = right
241-
242-
The string literal should contain a valid Python expression (i.e.,
243-
``compile(lit, '', 'eval')`` should be a valid code object) and it
244-
should evaluate without errors once the module has been fully loaded.
245-
The local and global namespace in which it is evaluated should be the
246-
same namespaces in which normal non-string types would be evaluated.
247-
248-
Moreover, the expression should be parseable as a valid type hint, i.e.,
249-
it is constrained by the rules from :ref:`the expression grammar <expression-grammar>`.
225+
The string literal should contain a syntactically valid Python expression
226+
(i.e., ``compile(lit, '', 'eval')`` should succeed) that evaluates to a valid
227+
:term:`annotation expression`. Names within the expression are looked up in the
228+
same way as they would be looked up at runtime in Python 3.14 and higher if the
229+
annotation was not enclosed in a string literal. Thus, name lookup follows
230+
general rules (e.g., the current function, class, or module scope first, and
231+
the builtin scope last), but names defined later within the same scope can be
232+
used in an earlier annotation.
250233

251234
If a triple quote is used, the string should be parsed as though it is
252235
implicitly surrounded by parentheses. This allows newline characters to be

0 commit comments

Comments
 (0)