diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-09-03 16:52:01 +0100 |
---|---|---|
committer | da-woods <dw-git@d-woods.co.uk> | 2022-09-03 16:58:12 +0100 |
commit | d6f585acdd5595b745465b8f479b741806cb4c82 (patch) | |
tree | e713925343087578e03f7ecaca4eca75afa1fd8e | |
parent | 020ce410c3c90c165ea6c2a968265c9f54ee049d (diff) | |
download | cython-d6f585acdd5595b745465b8f479b741806cb4c82.tar.gz |
Simplify type checking
Note that there's an error formatting issue on Python 2
unfortunately
-rw-r--r-- | Cython/Utility/MatchCase.c | 27 | ||||
-rw-r--r-- | tests/run/extra_patma_py.py | 22 |
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. + """ |