summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2022-09-03 16:52:01 +0100
committerda-woods <dw-git@d-woods.co.uk>2022-09-03 16:58:12 +0100
commitd6f585acdd5595b745465b8f479b741806cb4c82 (patch)
treee713925343087578e03f7ecaca4eca75afa1fd8e
parent020ce410c3c90c165ea6c2a968265c9f54ee049d (diff)
downloadcython-d6f585acdd5595b745465b8f479b741806cb4c82.tar.gz
Simplify type checking
Note that there's an error formatting issue on Python 2 unfortunately
-rw-r--r--Cython/Utility/MatchCase.c27
-rw-r--r--tests/run/extra_patma_py.py22
2 files changed, 37 insertions, 12 deletions
diff --git a/Cython/Utility/MatchCase.c b/Cython/Utility/MatchCase.c
index c7cc78900..2f4157143 100644
--- a/Cython/Utility/MatchCase.c
+++ b/Cython/Utility/MatchCase.c
@@ -786,19 +786,17 @@ static int __Pyx__MatchCase_ClassPositional(void *__pyx_refnanny, PyObject *subj
_Py_TPFLAGS_MATCH_SELF);
#else
// probably an earlier version of Python. Go off the known list in the specification
- match_self = (PyType_IsSubtype(type, &PyByteArray_Type) ||
- PyType_IsSubtype(type, &PyBytes_Type) ||
- PyType_IsSubtype(type, &PyDict_Type) ||
+ match_self = ((PyType_GetFlags(type) &
+ // long should capture bool too
+ (Py_TPFLAGS_LONG_SUBCLASS | Py_TPFLAGS_LIST_SUBCLASS | Py_TPFLAGS_TUPLE_SUBCLASS |
+ Py_TPFLAGS_BYTES_SUBCLASS | Py_TPFLAGS_UNICODE_SUBCLASS | Py_TPFLAGS_DICT_SUBCLASS
+ #if PY_MAJOR_VERSION < 3
+ | Py_TPFLAGS_IN_SUBCLASS
+ #endif
+ )) ||
+ PyType_IsSubtype(type, &PyByteArray_Type) ||
PyType_IsSubtype(type, &PyFloat_Type) ||
PyType_IsSubtype(type, &PyFrozenSet_Type) ||
- PyType_IsSubtype(type, &PyLong_Type) || // This should capture bool too
- #if PY_MAJOR_VERSION < 3
- PyType_IsSubtype(type, &PyInt_Type) ||
- #endif
- PyType_IsSubtype(type, &PyList_Type) ||
- PyType_IsSubtype(type, &PySet_Type) ||
- PyType_IsSubtype(type, &PyUnicode_Type) ||
- PyType_IsSubtype(type, &PyTuple_Type)
);
#endif
}
@@ -887,6 +885,13 @@ static PyTypeObject* __Pyx_MatchCase_IsType(PyObject* type); /* proto */
//////////////////////// MatchClassIsType /////////////////////////////
static PyTypeObject* __Pyx_MatchCase_IsType(PyObject* type) {
+ #if PY_MAJOR_VERSION < 3
+ if (PyClass_Check(type)) {
+ // I don't really think it's worth the effort getting this to work!
+ PyErr_Format(PyExc_TypeError, "called match pattern must be a new-style class.");
+ return NULL;
+ }
+ #endif
if (!PyType_Check(type)) {
PyErr_Format(PyExc_TypeError, "called match pattern must be a type");
return NULL;
diff --git a/tests/run/extra_patma_py.py b/tests/run/extra_patma_py.py
index e06d41591..ded678ea7 100644
--- a/tests/run/extra_patma_py.py
+++ b/tests/run/extra_patma_py.py
@@ -2,6 +2,9 @@
# tag: pure3.10
import array
+import sys
+
+__doc__ = ""
def test_array_is_sequence(x):
"""
@@ -43,7 +46,7 @@ def test_duplicate_keys(key1, key2):
return False
-class PyClass:
+class PyClass(object):
pass
@@ -63,3 +66,20 @@ class PrivateAttrLookupOuter:
match x:
case PyClass(__something=y):
return y
+
+
+if sys.version_info[0] < 3:
+ class OldStyleClass:
+ pass
+
+ def test_oldstyle_class_failure(x):
+ match x:
+ case OldStyleClass():
+ return True
+
+ __doc__ += """
+ >>> test_oldstyle_class_failure(1)
+ Traceback (most recent call last):
+ ...
+ TypeError: called match pattern must be a new-style class.
+ """