8000 bpo-42266: Handle monkey-patching descriptors in LOAD_ATTR cache (GH-… · python/cpython@80449f2 · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 80449f2

Browse files
authored
bpo-42266: Handle monkey-patching descriptors in LOAD_ATTR cache (GH-23157)
1 parent 178695b commit 80449f2

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

Lib/test/test_opcache.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import unittest
2+
3+
class TestLoadAttrCache(unittest.TestCase):
4+
def test_descriptor_added_after_optimization(self):
5+
class Descriptor:
6+
pass
7+
8+
class C:
9+
def __init__(self):
10+
self.x = 1
11+
x = Descriptor()
12+
13+
def f(o):
14+
return o.x
15+
16+
o = C()
17+
for i in range(1025):
18+
assert f(o) == 1
19+
20+
Descriptor.__get__ = lambda self, instance, value: 2
21+
Descriptor.__set__ = lambda *args: None
22+
23+
self.assertEqual(f(o), 2)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed a bug with the LOAD_ATTR opcode cache that was not respecting
2+
monkey-patching a class-level attribute to make it a descriptor. Patch by
3+
Pablo Galindo.

PCbuild/lib.pyproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,7 @@
11961196
<Compile Include="test\test_nntplib.py" />
11971197
<Compile Include="test\test_ntpath.py" />
11981198
<Compile Include="test\test_numeric_tower.py" />
1199+
<Compile Include="test\test_opcache.py" />
11991200
<Compile Include="test\test_opcodes.py" />
12001201
<Compile Include="test\test_openpty.py" />
12011202
<Compile Include="test\test_operator.py" />

Python/ceval.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,7 +3179,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
31793179
if (co_opcache != NULL && /* co_opcache can be NULL after a DEOPT() call. */
31803180
type->tp_getattro == PyObject_GenericGetAttr)
31813181
{
3182-
PyObject *descr;
31833182
Py_ssize_t ret;
31843183

31853184
if (type->tp_dictoffset > 0) {
@@ -3190,12 +3189,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
31903189
goto error;
31913190
}
31923191
}
3193-
3194-
descr = _PyType_Lookup(type, name);
3195-
if (descr == NULL ||
3196-
Py_TYPE(descr)->tp_descr_get == NULL ||
3197-
!PyDescr_IsData(descr))
3198-
{
3192+
if (_PyType_Lookup(type, name) == NULL) {
31993193
dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset);
32003194
dict = *dictptr;
32013195

0 commit comments

Comments
 (0)
0