From ac66403cb4374b858786350b96e7f5972db84bcd Mon Sep 17 00:00:00 2001 From: Adrian Freund Date: Tue, 16 Mar 2021 12:55:54 +0100 Subject: [PATCH] Fix mypyc failing to compile on CPython 3.10.0a6 (#10202) * Fix mypyc failing to compile on CPython 3.10.0a6 _PyObject_HasAttrId() has been removed in https://github.com/python/cpython/pull/22629 * Keep using _PyObject_HasAttrId when python version is too old We could potentionally already use _PyObject_LookupAttrId starting with python 3.7 instead of 3.10. I'm not sure if we should switch as soon or as late as possible. Alternatively we could also try backporting _PyObject_LookupAttrId to <3.7. --- mypyc/lib-rt/dict_ops.c | 4 ++-- mypyc/lib-rt/pythonsupport.h | 14 ++++++++++++++ mypyc/test-data/run-misc.test | 5 ++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mypyc/lib-rt/dict_ops.c b/mypyc/lib-rt/dict_ops.c index 1e635ada2c00..4f831d0ba850 100644 --- a/mypyc/lib-rt/dict_ops.c +++ b/mypyc/lib-rt/dict_ops.c @@ -115,7 +115,7 @@ int CPyDict_UpdateFromAny(PyObject *dict, PyObject *stuff) { if (PyDict_CheckExact(dict)) { // Argh this sucks _Py_IDENTIFIER(keys); - if (PyDict_Check(stuff) || _PyObject_HasAttrId(stuff, &PyId_keys)) { + if (PyDict_Check(stuff) || _CPyObject_HasAttrId(stuff, &PyId_keys)) { return PyDict_Update(dict, stuff); } else { return PyDict_MergeFromSeq2(dict, stuff, 1); @@ -135,7 +135,7 @@ PyObject *CPyDict_FromAny(PyObject *obj) { return NULL; } _Py_IDENTIFIER(keys); - if (_PyObject_HasAttrId(obj, &PyId_keys)) { + if (_CPyObject_HasAttrId(obj, &PyId_keys)) { res = PyDict_Update(dict, obj); } else { res = PyDict_MergeFromSeq2(dict, obj, 1); diff --git a/mypyc/lib-rt/pythonsupport.h b/mypyc/lib-rt/pythonsupport.h index 864a1d152aa0..a8b00e168bb7 100644 --- a/mypyc/lib-rt/pythonsupport.h +++ b/mypyc/lib-rt/pythonsupport.h @@ -389,4 +389,18 @@ _CPyDictView_New(PyObject *dict, PyTypeObject *type) } #endif +#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >=10 +static int +_CPyObject_HasAttrId(PyObject *v, _Py_Identifier *name) { + PyObject *tmp = NULL; + int result = _PyObject_LookupAttrId(v, name, &tmp); + if (tmp) { + Py_DECREF(tmp); + } + return result; +} +#else +#define _CPyObject_HasAttrId _PyObject_HasAttrId +#endif + #endif diff --git a/mypyc/test-data/run-misc.test b/mypyc/test-data/run-misc.test index cc9ef444f31b..8b79949b55ad 100644 --- a/mypyc/test-data/run-misc.test +++ b/mypyc/test-data/run-misc.test @@ -940,7 +940,10 @@ import sys # We lie about the version we are running in tests if it is 3.5, so # that hits a crash case. -if sys.version_info[:2] == (3, 9): +if sys.version_info[:2] == (3, 10): + def version() -> int: + return 10 +elif sys.version_info[:2] == (3, 9): def version() -> int: return 9 elif sys.version_info[:2] == (3, 8):