From 1fb5c9643300faf8910c02cf0fdffc137d8609eb Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Tue, 21 Dec 2010 01:45:27 -0800 Subject: [PATCH] Fix #632 isinstance bugs. --- Cython/Compiler/ModuleNode.py | 2 ++ Cython/Compiler/Optimize.py | 22 ++++++++++++++-------- tests/run/isinstance.pyx | 16 ++++++---------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index e7e652ef..6cb0d5fe 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -579,6 +579,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #endif +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) + #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 28ed19ff..77fdaac1 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -1986,20 +1986,26 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): test_nodes = [] env = self.current_env() for test_type_node in types: - if not test_type_node.entry: - return node - entry = env.lookup(test_type_node.entry.name) - if not entry or not entry.type or not entry.type.is_builtin_type: - return node - type_check_function = entry.type.type_check_function(exact=False) - if not type_check_function: + builtin_type = None + if isinstance(test_type_node, ExprNodes.NameNode): + if test_type_node.entry: + entry = env.lookup(test_type_node.entry.name) + if entry and entry.type and entry.type.is_builtin_type: + builtin_type = entry.type + if builtin_type and builtin_type is not Builtin.type_type: + type_check_function = entry.type.type_check_function(exact=False) + type_check_args = [arg] + elif test_type_node.type is Builtin.type_type: + type_check_function = '__Pyx_TypeCheck' + type_check_args = [arg, test_type_node] + else: return node if type_check_function not in tests: tests.append(type_check_function) test_nodes.append( ExprNodes.PythonCapiCallNode( test_type_node.pos, type_check_function, self.Py_type_check_func_type, - args = [arg], + args = type_check_args, is_temp = True, )) diff --git a/tests/run/isinstance.pyx b/tests/run/isinstance.pyx index db54a9de..d11b3771 100644 --- a/tests/run/isinstance.pyx +++ b/tests/run/isinstance.pyx @@ -5,8 +5,6 @@ from cpython.bool cimport bool cdef class A: pass -cdef an_A = A() - @cython.test_assert_path_exists('//SimpleCallNode//SimpleCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode//PythonCapiCallNode', '//PythonCapiCallNode//SimpleCallNode') @@ -50,11 +48,11 @@ def test_optimised(): assert isinstance(complex(), complex) assert not isinstance(u"foo", int) assert isinstance(A, type) - assert isinstance(an_A, A) + assert isinstance(A(), A) cdef type typed_type = A - assert isinstance(an_A, typed_type) + assert isinstance(A(), typed_type) cdef object untyped_type = A - assert isinstance(an_A, untyped_type) + assert isinstance(A(), untyped_type) return True @cython.test_assert_path_exists('//PythonCapiCallNode') @@ -66,13 +64,11 @@ def test_optimised_tuple(): >>> test_optimised_tuple() True """ - assert isinstance(int(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice)) - assert isinstance(list(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice)) + assert isinstance(int(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, A)) + assert isinstance(list(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, A)) + assert isinstance(A(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, A)) return True -@cython.test_assert_path_exists('//SimpleCallNode//SimpleCallNode') -@cython.test_fail_if_path_exists('//SimpleCallNode//PythonCapiCallNode', - '//PythonCapiCallNode//SimpleCallNode') def test_custom(): """ >>> test_custom() -- 2.26.2