mirror of
https://github.com/python/cpython.git
synced 2024-11-27 11:55:13 +08:00
gh-122445: populate only modified fields in __static_attributes__ (#122446)
This commit is contained in:
parent
9fc1c992d6
commit
498376d7a7
@ -999,7 +999,7 @@ Special attributes:
|
|||||||
a :ref:`generic class <generic-classes>`.
|
a :ref:`generic class <generic-classes>`.
|
||||||
|
|
||||||
:attr:`~class.__static_attributes__`
|
: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.
|
through ``self.X`` from any function in its body.
|
||||||
|
|
||||||
:attr:`__firstlineno__`
|
:attr:`__firstlineno__`
|
||||||
|
@ -247,7 +247,7 @@ Improved Error Messages
|
|||||||
TypeError: split() got an unexpected keyword argument 'max_split'. Did you mean 'maxsplit'?
|
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,
|
* 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
|
through ``self.X`` from any function in its body. (Contributed by Irit Katriel
|
||||||
in :gh:`115775`.)
|
in :gh:`115775`.)
|
||||||
|
|
||||||
|
@ -2089,12 +2089,15 @@ class TestSourcePositions(unittest.TestCase):
|
|||||||
self.assertEqual(end_col, 20)
|
self.assertEqual(end_col, 20)
|
||||||
|
|
||||||
|
|
||||||
class TestExpectedAttributes(unittest.TestCase):
|
class TestStaticAttributes(unittest.TestCase):
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
class C:
|
class C:
|
||||||
def f(self):
|
def f(self):
|
||||||
self.a = self.b = 42
|
self.a = self.b = 42
|
||||||
|
# read fields are not included
|
||||||
|
self.f()
|
||||||
|
self.arr[3]
|
||||||
|
|
||||||
self.assertIsInstance(C.__static_attributes__, tuple)
|
self.assertIsInstance(C.__static_attributes__, tuple)
|
||||||
self.assertEqual(sorted(C.__static_attributes__), ['a', 'b'])
|
self.assertEqual(sorted(C.__static_attributes__), ['a', 'b'])
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
Add only fields which are modified via self.* to :attr:`~class.__static_attributes__`.
|
@ -563,8 +563,16 @@ compiler_unit_free(struct compiler_unit *u)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compiler_add_static_attribute_to_class(struct compiler *c, PyObject *attr)
|
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);
|
Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
|
||||||
for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
|
for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
|
||||||
PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
|
PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
|
||||||
@ -573,7 +581,7 @@ compiler_add_static_attribute_to_class(struct compiler *c, PyObject *attr)
|
|||||||
assert(u);
|
assert(u);
|
||||||
if (u->u_scope_type == COMPILER_SCOPE_CLASS) {
|
if (u->u_scope_type == COMPILER_SCOPE_CLASS) {
|
||||||
assert(u->u_static_attributes);
|
assert(u->u_static_attributes);
|
||||||
RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, attr));
|
RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, e->v.Attribute.attr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6065,11 +6073,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
|
|||||||
ADDOP(c, loc, NOP);
|
ADDOP(c, loc, NOP);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
if (e->v.Attribute.value->kind == Name_kind &&
|
RETURN_IF_ERROR(compiler_maybe_add_static_attribute_to_class(c, e));
|
||||||
_PyUnicode_EqualToASCIIString(e->v.Attribute.value->v.Name.id, "self"))
|
|
||||||
{
|
|
||||||
RETURN_IF_ERROR(compiler_add_static_attribute_to_class(c, e->v.Attribute.attr));
|
|
||||||
}
|
|
||||||
VISIT(c, expr, e->v.Attribute.value);
|
VISIT(c, expr, e->v.Attribute.value);
|
||||||
loc = LOC(e);
|
loc = LOC(e);
|
||||||
loc = update_start_location_to_match_attr(c, loc, e);
|
loc = update_start_location_to_match_attr(c, loc, e);
|
||||||
|
Loading…
Reference in New Issue
Block a user