[Python-checkins] bpo-42266: Handle monkey-patching descriptors in LOAD_ATTR cache (GH-23157)
pablogsal
webhook-mailer at python.org
Thu Nov 5 04:23:33 EST 2020
https://github.com/python/cpython/commit/80449f243b13311d660eab3a751648029bcdd833
commit: 80449f243b13311d660eab3a751648029bcdd833
branch: master
author: Pablo Galindo <Pablogsal at gmail.com>
committer: pablogsal <Pablogsal at gmail.com>
date: 2020-11-05T09:23:15Z
summary:
bpo-42266: Handle monkey-patching descriptors in LOAD_ATTR cache (GH-23157)
files:
A Lib/test/test_opcache.py
A Misc/NEWS.d/next/Core and Builtins/2020-11-04-23-03-25.bpo-42266.G4hGDe.rst
M PCbuild/lib.pyproj
M Python/ceval.c
diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py
new file mode 100644
index 0000000000000..61f337d70ea78
--- /dev/null
+++ b/Lib/test/test_opcache.py
@@ -0,0 +1,23 @@
+import unittest
+
+class TestLoadAttrCache(unittest.TestCase):
+ def test_descriptor_added_after_optimization(self):
+ class Descriptor:
+ pass
+
+ class C:
+ def __init__(self):
+ self.x = 1
+ x = Descriptor()
+
+ def f(o):
+ return o.x
+
+ o = C()
+ for i in range(1025):
+ assert f(o) == 1
+
+ Descriptor.__get__ = lambda self, instance, value: 2
+ Descriptor.__set__ = lambda *args: None
+
+ self.assertEqual(f(o), 2)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-11-04-23-03-25.bpo-42266.G4hGDe.rst b/Misc/NEWS.d/next/Core and Builtins/2020-11-04-23-03-25.bpo-42266.G4hGDe.rst
new file mode 100644
index 0000000000000..a8598cfde0420
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-11-04-23-03-25.bpo-42266.G4hGDe.rst
@@ -0,0 +1,3 @@
+Fixed a bug with the LOAD_ATTR opcode cache that was not respecting
+monkey-patching a class-level attribute to make it a descriptor. Patch by
+Pablo Galindo.
diff --git a/PCbuild/lib.pyproj b/PCbuild/lib.pyproj
index a15165d92ef12..1be60b1a11b93 100644
--- a/PCbuild/lib.pyproj
+++ b/PCbuild/lib.pyproj
@@ -1196,6 +1196,7 @@
<Compile Include="test\test_nntplib.py" />
<Compile Include="test\test_ntpath.py" />
<Compile Include="test\test_numeric_tower.py" />
+ <Compile Include="test\test_opcache.py" />
<Compile Include="test\test_opcodes.py" />
<Compile Include="test\test_openpty.py" />
<Compile Include="test\test_operator.py" />
diff --git a/Python/ceval.c b/Python/ceval.c
index 13b209fc706b6..32e3019682f0a 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3179,7 +3179,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
if (co_opcache != NULL && /* co_opcache can be NULL after a DEOPT() call. */
type->tp_getattro == PyObject_GenericGetAttr)
{
- PyObject *descr;
Py_ssize_t ret;
if (type->tp_dictoffset > 0) {
@@ -3190,12 +3189,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
goto error;
}
}
-
- descr = _PyType_Lookup(type, name);
- if (descr == NULL ||
- Py_TYPE(descr)->tp_descr_get == NULL ||
- !PyDescr_IsData(descr))
- {
+ if (_PyType_Lookup(type, name) == NULL) {
dictptr = (PyObject **) ((char *)owner + type->tp_dictoffset);
dict = *dictptr;
More information about the Python-checkins
mailing list