cython-devel

changeset 2673:2266c6948c98

implementation of 'not in' is broken (ticket #455)
author Lisandro Dalcin <dalcinl@gmail.com>
date Wed Nov 11 13:11:31 2009 -0200 (2 years ago)
parents e332eaf25cf0
children 1bb2be2073e8
files Cython/Compiler/ExprNodes.py tests/run/contains_T455.pyx
line diff
1.1 --- a/Cython/Compiler/ExprNodes.py Tue Nov 10 23:05:37 2009 -0800 1.2 +++ b/Cython/Compiler/ExprNodes.py Wed Nov 11 13:11:31 2009 -0200 1.3 @@ -5226,9 +5226,14 @@ 1.4 coerce_result = "__Pyx_PyBool_FromLong" 1.5 else: 1.6 coerce_result = "" 1.7 - if 'not' in op: negation = "!" 1.8 - else: negation = "" 1.9 + if 'not' in op: 1.10 + negation = "!" 1.11 + else: 1.12 + negation = "" 1.13 if op == 'in' or op == 'not_in': 1.14 + assert not coerce_result 1.15 + if op == 'not_in': 1.16 + negation = "if (likely(%s != -1)) %s = !%s; " % ((result_code,)*3) 1.17 if operand2.type is dict_type: 1.18 code.globalstate.use_utility_code( 1.19 raise_none_iter_error_utility_code) 1.20 @@ -5237,23 +5242,22 @@ 1.21 code.error_goto(self.pos)) 1.22 code.putln("} else {") 1.23 code.putln( 1.24 - "%s = %s(%sPyDict_Contains(%s, %s)); %s" % ( 1.25 + "%s = PyDict_Contains(%s, %s); %s%s" % ( 1.26 result_code, 1.27 - coerce_result, 1.28 - negation, 1.29 operand2.py_result(), 1.30 operand1.py_result(), 1.31 + negation, 1.32 code.error_goto_if_neg(result_code, self.pos))) 1.33 code.putln("}") 1.34 else: 1.35 code.putln( 1.36 - "%s = %s(%sPySequence_Contains(%s, %s)); %s" % ( 1.37 + "%s = PySequence_Contains(%s, %s); %s%s" % ( 1.38 result_code, 1.39 - coerce_result, 1.40 - negation, 1.41 operand2.py_result(), 1.42 operand1.py_result(), 1.43 + negation, 1.44 code.error_goto_if_neg(result_code, self.pos))) 1.45 + 1.46 elif (operand1.type.is_pyobject 1.47 and op not in ('is', 'is_not')): 1.48 code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tests/run/contains_T455.pyx Wed Nov 11 13:11:31 2009 -0200 2.3 @@ -0,0 +1,82 @@ 2.4 +def in_sequence(x, seq): 2.5 + """ 2.6 + >>> in_sequence(1, []) 2.7 + False 2.8 + >>> in_sequence(1, ()) 2.9 + False 2.10 + >>> in_sequence(1, {}) 2.11 + False 2.12 + >>> in_sequence(1, [1]) 2.13 + True 2.14 + >>> in_sequence(1, (1,)) 2.15 + True 2.16 + >>> in_sequence(1, {1:None}) 2.17 + True 2.18 + 2.19 + >>> in_sequence(1, None) 2.20 + Traceback (most recent call last): 2.21 + ... 2.22 + TypeError: argument of type 'NoneType' is not iterable 2.23 + 2.24 + >>> in_sequence(1, 1) 2.25 + Traceback (most recent call last): 2.26 + ... 2.27 + TypeError: argument of type 'int' is not iterable 2.28 + """ 2.29 + return x in seq 2.30 + 2.31 +def not_in_sequence(x, seq): 2.32 + """ 2.33 + >>> not_in_sequence(1, []) 2.34 + True 2.35 + >>> not_in_sequence(1, ()) 2.36 + True 2.37 + >>> not_in_sequence(1, {}) 2.38 + True 2.39 + >>> not_in_sequence(1, [1]) 2.40 + False 2.41 + >>> not_in_sequence(1, (1,)) 2.42 + False 2.43 + >>> not_in_sequence(1, {1:None}) 2.44 + False 2.45 + 2.46 + >>> not_in_sequence(1, None) 2.47 + Traceback (most recent call last): 2.48 + ... 2.49 + TypeError: argument of type 'NoneType' is not iterable 2.50 + 2.51 + >>> not_in_sequence(1, 1) 2.52 + Traceback (most recent call last): 2.53 + ... 2.54 + TypeError: argument of type 'int' is not iterable 2.55 + """ 2.56 + return x not in seq 2.57 + 2.58 + 2.59 +def in_dict(k, dict dct): 2.60 + """ 2.61 + >>> in_dict(1, {}) 2.62 + False 2.63 + >>> in_dict(1, {1:None}) 2.64 + True 2.65 + 2.66 + >>> in_dict(1, None) 2.67 + Traceback (most recent call last): 2.68 + ... 2.69 + TypeError: 'NoneType' object is not iterable 2.70 + """ 2.71 + return k in dct 2.72 + 2.73 +def not_in_dict(k, dict dct): 2.74 + """ 2.75 + >>> not_in_dict(1, {}) 2.76 + True 2.77 + >>> not_in_dict(1, {1:None}) 2.78 + False 2.79 + 2.80 + >>> not_in_dict(1, None) 2.81 + Traceback (most recent call last): 2.82 + ... 2.83 + TypeError: 'NoneType' object is not iterable 2.84 + """ 2.85 + return k not in dct