Commit 1175bb68 authored by Lisandro Dalcin's avatar Lisandro Dalcin

implementation of 'not in' is broken (ticket #455)

parent 6f9ac4da
...@@ -5226,9 +5226,14 @@ class CmpNode(object): ...@@ -5226,9 +5226,14 @@ class CmpNode(object):
coerce_result = "__Pyx_PyBool_FromLong" coerce_result = "__Pyx_PyBool_FromLong"
else: else:
coerce_result = "" coerce_result = ""
if 'not' in op: negation = "!" if 'not' in op:
else: negation = "" negation = "!"
else:
negation = ""
if op == 'in' or op == 'not_in': if op == 'in' or op == 'not_in':
assert not coerce_result
if op == 'not_in':
negation = "if (likely(%s != -1)) %s = !%s; " % ((result_code,)*3)
if operand2.type is dict_type: if operand2.type is dict_type:
code.globalstate.use_utility_code( code.globalstate.use_utility_code(
raise_none_iter_error_utility_code) raise_none_iter_error_utility_code)
...@@ -5237,23 +5242,22 @@ class CmpNode(object): ...@@ -5237,23 +5242,22 @@ class CmpNode(object):
code.error_goto(self.pos)) code.error_goto(self.pos))
code.putln("} else {") code.putln("} else {")
code.putln( code.putln(
"%s = %s(%sPyDict_Contains(%s, %s)); %s" % ( "%s = PyDict_Contains(%s, %s); %s%s" % (
result_code, result_code,
coerce_result,
negation,
operand2.py_result(), operand2.py_result(),
operand1.py_result(), operand1.py_result(),
negation,
code.error_goto_if_neg(result_code, self.pos))) code.error_goto_if_neg(result_code, self.pos)))
code.putln("}") code.putln("}")
else: else:
code.putln( code.putln(
"%s = %s(%sPySequence_Contains(%s, %s)); %s" % ( "%s = PySequence_Contains(%s, %s); %s%s" % (
result_code, result_code,
coerce_result,
negation,
operand2.py_result(), operand2.py_result(),
operand1.py_result(), operand1.py_result(),
negation,
code.error_goto_if_neg(result_code, self.pos))) code.error_goto_if_neg(result_code, self.pos)))
elif (operand1.type.is_pyobject elif (operand1.type.is_pyobject
and op not in ('is', 'is_not')): and op not in ('is', 'is_not')):
code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % ( code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s" % (
......
def in_sequence(x, seq):
"""
>>> in_sequence(1, [])
False
>>> in_sequence(1, ())
False
>>> in_sequence(1, {})
False
>>> in_sequence(1, [1])
True
>>> in_sequence(1, (1,))
True
>>> in_sequence(1, {1:None})
True
>>> in_sequence(1, None)
Traceback (most recent call last):
...
TypeError: argument of type 'NoneType' is not iterable
>>> in_sequence(1, 1)
Traceback (most recent call last):
...
TypeError: argument of type 'int' is not iterable
"""
return x in seq
def not_in_sequence(x, seq):
"""
>>> not_in_sequence(1, [])
True
>>> not_in_sequence(1, ())
True
>>> not_in_sequence(1, {})
True
>>> not_in_sequence(1, [1])
False
>>> not_in_sequence(1, (1,))
False
>>> not_in_sequence(1, {1:None})
False
>>> not_in_sequence(1, None)
Traceback (most recent call last):
...
TypeError: argument of type 'NoneType' is not iterable
>>> not_in_sequence(1, 1)
Traceback (most recent call last):
...
TypeError: argument of type 'int' is not iterable
"""
return x not in seq
def in_dict(k, dict dct):
"""
>>> in_dict(1, {})
False
>>> in_dict(1, {1:None})
True
>>> in_dict(1, None)
Traceback (most recent call last):
...
TypeError: 'NoneType' object is not iterable
"""
return k in dct
def not_in_dict(k, dict dct):
"""
>>> not_in_dict(1, {})
True
>>> not_in_dict(1, {1:None})
False
>>> not_in_dict(1, None)
Traceback (most recent call last):
...
TypeError: 'NoneType' object is not iterable
"""
return k not in dct
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment