https://github.com/python/cpython/commit/545a328eae058b82d7279a31d7fdce08b6ff4f94
commit: 545a328eae058b82d7279a31d7fdce08b6ff4f94
branch: 3.13
author: Irit Katriel <[email protected]>
committer: iritkatriel <[email protected]>
date: 2024-08-02T19:26:57+01:00
summary:
[3.13] gh-122445: populate only modified fields in __static_attributes__
(#122446) (#122621)
gh-122445: populate only modified fields in __static_attributes__ (#122446)
(cherry picked from commit 498376d7a7d6f704f22a2c963130cc15c17e7a6f)
files:
A Misc/NEWS.d/next/Core and
Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst
M Doc/reference/datamodel.rst
M Doc/whatsnew/3.13.rst
M Lib/test/test_compile.py
M Python/compile.c
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index fa5bd93ebf2185..440f912190a57b 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -996,7 +996,7 @@ Special attributes:
a :ref:`generic class <generic-classes>`.
:attr:`~class.__static_attributes__`
- A tuple containing names of attributes of this class which are accessed
+ A tuple containing names of attributes of this class which are assigned
through ``self.X`` from any function in its body.
:attr:`__firstlineno__`
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index b53f419a59f062..239447f762a408 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -247,7 +247,7 @@ Improved Error Messages
TypeError: split() got an unexpected keyword argument 'max_split'. Did you
mean 'maxsplit'?
* Classes have a new :attr:`~class.__static_attributes__` attribute, populated
by the compiler,
- with a tuple of names of attributes of this class which are accessed
+ with a tuple of names of attributes of this class which are assigned
through ``self.X`` from any function in its body. (Contributed by Irit
Katriel
in :gh:`115775`.)
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index e29c95e8bf263a..7960089c4cdf94 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -2056,12 +2056,15 @@ def test_lambda_return_position(self):
self.assertLessEqual(end_col, code_end)
-class TestExpectedAttributes(unittest.TestCase):
+class TestStaticAttributes(unittest.TestCase):
def test_basic(self):
class C:
def f(self):
self.a = self.b = 42
+ # read fields are not included
+ self.f()
+ self.arr[3]
self.assertIsInstance(C.__static_attributes__, tuple)
self.assertEqual(sorted(C.__static_attributes__), ['a', 'b'])
diff --git a/Misc/NEWS.d/next/Core and
Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst b/Misc/NEWS.d/next/Core
and Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst
new file mode 100644
index 00000000000000..f5aa07c6513ea9
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and
Builtins/2024-07-30-11-41-35.gh-issue-122445.Rq0bjS.rst
@@ -0,0 +1 @@
+Add only fields which are modified via self.* to
:attr:`~class.__static_attributes__`.
diff --git a/Python/compile.c b/Python/compile.c
index 74566683a0400e..6c6260c7add6ac 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -589,9 +589,17 @@ compiler_unit_free(struct compiler_unit *u)
PyMem_Free(u);
}
-static struct compiler_unit *
-get_class_compiler_unit(struct compiler *c)
+static int
+compiler_maybe_add_static_attribute_to_class(struct compiler *c, expr_ty e)
{
+ assert(e->kind == Attribute_kind);
+ expr_ty attr_value = e->v.Attribute.value;
+ if (attr_value->kind != Name_kind ||
+ e->v.Attribute.ctx != Store ||
+ !_PyUnicode_EqualToASCIIString(attr_value->v.Name.id, "self"))
+ {
+ return SUCCESS;
+ }
Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
@@ -599,10 +607,12 @@ get_class_compiler_unit(struct compiler *c)
capsule,
CAPSULE_NAME);
assert(u);
if (u->u_scope_type == COMPILER_SCOPE_CLASS) {
- return u;
+ assert(u->u_static_attributes);
+ RETURN_IF_ERROR(PySet_Add(u->u_static_attributes,
e->v.Attribute.attr));
+ break;
}
}
- return NULL;
+ return SUCCESS;
}
static int
@@ -6283,17 +6293,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
ADDOP(c, loc, NOP);
return SUCCESS;
}
- if (e->v.Attribute.value->kind == Name_kind &&
- _PyUnicode_EqualToASCIIString(e->v.Attribute.value->v.Name.id,
"self"))
- {
- struct compiler_unit *class_u = get_class_compiler_unit(c);
- if (class_u != NULL) {
- assert(class_u->u_scope_type == COMPILER_SCOPE_CLASS);
- assert(class_u->u_static_attributes);
- RETURN_IF_ERROR(
- PySet_Add(class_u->u_static_attributes,
e->v.Attribute.attr));
- }
- }
+ RETURN_IF_ERROR(compiler_maybe_add_static_attribute_to_class(c, e));
VISIT(c, expr, e->v.Attribute.value);
loc = LOC(e);
loc = update_start_location_to_match_attr(c, loc, e);
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]