Skip to content
This repository has been archived by the owner on May 31, 2020. It is now read-only.

Commit

Permalink
Merge pull request #877 from patiences/contains-bug
Browse files Browse the repository at this point in the history
Contains/Not Contains throws wrong errors
  • Loading branch information
freakboy3742 authored Aug 9, 2018
2 parents 7a9824e + 7529947 commit 2262a71
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 101 deletions.
1 change: 0 additions & 1 deletion python/common/org/python/Object.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ public interface Object extends Comparable {
public org.python.Object __invert__();

public org.python.Object __not__();
public org.python.Object __not_contains__(org.python.Object item);

public org.python.Object __complex__(org.python.Object real, org.python.Object imag);
public org.python.Object __int__();
Expand Down
14 changes: 0 additions & 14 deletions python/common/org/python/types/Dict.java
Original file line number Diff line number Diff line change
Expand Up @@ -341,20 +341,6 @@ public org.python.Object __contains__(org.python.Object item) {
}
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object item) {
// allow unhashable type error to be percolated up.
try {
_getitem(item);
return org.python.types.Bool.FALSE;
} catch (org.python.exceptions.KeyError e) {
return org.python.types.Bool.TRUE;
}
}

@org.python.Method(
__doc__ = "D.clear() -> None. Remove all items from D."
)
Expand Down
9 changes: 0 additions & 9 deletions python/common/org/python/types/DictItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,6 @@ public org.python.Object __contains__(org.python.Object item) {
return set.__contains__(item);
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object other) {
org.python.types.Set set = new org.python.types.Set(this.toTupleSet());
return set.__not_contains__(other);
}

@org.python.Method(
__doc__ = "Return self<value.",
args = {"other"}
Expand Down
8 changes: 0 additions & 8 deletions python/common/org/python/types/DictValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,4 @@ public void __delitem__(org.python.Object item) {
public org.python.Object __contains__(org.python.Object item) {
return org.python.types.Bool.getBool(this.value.contains(item));
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object item) {
return org.python.types.Bool.getBool(!this.value.contains(item));
}
}
8 changes: 0 additions & 8 deletions python/common/org/python/types/FrozenSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,6 @@ public org.python.Object __contains__(org.python.Object other) {
return org.python.types.Bool.getBool(this.value.contains(other));
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object other) {
return org.python.types.Bool.getBool(!this.value.contains(other));
}

@org.python.Method(
__doc__ = "Return a shallow copy of a FrozenSet."
)
Expand Down
56 changes: 13 additions & 43 deletions python/common/org/python/types/Object.java
Original file line number Diff line number Diff line change
Expand Up @@ -556,14 +556,6 @@ public org.python.Object __contains__(org.python.Object item) {
throw new org.python.exceptions.AttributeError(this, "__contains__");
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object item) {
throw new org.python.exceptions.AttributeError(this, "__not_contains__");
}

/**
* Section 3.3.7 - Emulating numeric types
*/
Expand Down Expand Up @@ -1368,47 +1360,25 @@ public static org.python.Object __contains__(org.python.Object v, org.python.Obj
org.python.Object result = null;

if (v_builtin) {
result = v.__contains__(w);
} else {
result = invokeComparison(v, w, "__contains__");
}

if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) {
try {
result = v.__contains__(w);
} catch (org.python.exceptions.AttributeError e) {
throw new org.python.exceptions.TypeError(String.format("argument of type '%s' is not iterable", v.typeName()));
}
return result;
}

// Error case
if (org.Python.VERSION < 0x03060000) {
throw new org.python.exceptions.TypeError(String.format(
"unorderable types: %s() %s %s()", v.typeName(), "in", w.typeName()));
} else {
throw new org.python.exceptions.TypeError(String.format(
"'%s' not supported between instances of '%s' and '%s'", "in", v.typeName(), w.typeName()));
try {
result = invokeComparison(v, w, "__contains__");
} catch (org.python.exceptions.AttributeError e) {
throw new org.python.exceptions.TypeError(String.format("argument of type '%s' is not iterable", v.typeName()));
}
return result;
}
}

public static org.python.Object __not_contains__(org.python.Object v, org.python.Object w) {
boolean v_builtin = isBuiltin(v);
org.python.Object result = null;
// Normal case
if (v_builtin) {
result = v.__not_contains__(w);
} else {
result = invokeComparison(v, w, "__not_contains__");
}

if (result != org.python.types.NotImplementedType.NOT_IMPLEMENTED) {
return result;
}

// Error case
if (org.Python.VERSION < 0x03060000) {
throw new org.python.exceptions.TypeError(String.format(
"unorderable types: %s() %s %s()", v.typeName(), "not in", w.typeName()));
} else {
throw new org.python.exceptions.TypeError(String.format(
"'%s' not supported between instances of '%s' and '%s'", "not in", v.typeName(), w.typeName()));
}
org.python.Object containsObj = org.python.types.Object.__contains__(v, w);
return org.python.types.Bool.getBool(!((org.python.types.Bool) containsObj).value);
}

private static org.python.Object invokeComparison(org.python.Object x, org.python.Object y, String methodName) {
Expand Down
8 changes: 0 additions & 8 deletions python/common/org/python/types/Set.java
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,6 @@ public org.python.Object __contains__(org.python.Object other) {
return org.python.types.Bool.getBool(this.value.contains(other));
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object other) {
return org.python.types.Bool.getBool(!this.value.contains(other));
}

@org.python.Method(
__doc__ = ""
)
Expand Down
6 changes: 4 additions & 2 deletions python/common/org/python/types/Str.java
Original file line number Diff line number Diff line change
Expand Up @@ -401,14 +401,16 @@ public org.python.Object __iter__() {
__doc__ = "Return key in self.",
args = {"item"}
)
public org.python.types.Int __contains__(org.python.Object item) {
public org.python.Object __contains__(org.python.Object item) {
if (item instanceof org.python.types.Str) {

int substr_exists = 0;
org.python.types.Str item_str = (org.python.types.Str) item;

if (this.value.length() == 0 && item_str.value.length() == 0) {
substr_exists = 1;
} else if (this.value == item_str.value) {
substr_exists = 1;
} else {
for (int i = 0; i < this.value.length() - item_str.value.length(); i++) {
boolean mismatch = false;
Expand All @@ -423,7 +425,7 @@ public org.python.types.Int __contains__(org.python.Object item) {
}
}
}
return org.python.types.Int.getInt(substr_exists);
return org.python.types.Bool.getBool(substr_exists);
}
if (org.Python.VERSION < 0x03060000) {
throw new org.python.exceptions.TypeError("Can't convert '" + item.typeName() + "' object to str implicitly");
Expand Down
8 changes: 0 additions & 8 deletions python/common/org/python/types/Super.java
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,6 @@ public org.python.Object __contains__(org.python.Object item) {
throw new org.python.exceptions.AttributeError(this, "__contains__");
}

@org.python.Method(
__doc__ = "",
args = {"item"}
)
public org.python.Object __not_contains__(org.python.Object item) {
throw new org.python.exceptions.AttributeError(this, "__not_contains__");
}

/**
* Section 3.3.7 - Emulating numeric types
*/
Expand Down
13 changes: 13 additions & 0 deletions tests/datatypes/test_str.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,19 @@ def test_zfill(self):
print(err)
""")

def test_contains(self):
self.assertCodeExecution("""
print('abc' in 'abc')
print('a' in 'abc')
print('a' in '')
print('' in 'a')
print('abc' not in 'abc')
print('a' not in 'abc')
print('a' not in '')
print('' in 'a')
""")


class UnaryStrOperationTests(UnaryOperationTestCase, TranspileTestCase):
data_type = 'str'
Expand Down
44 changes: 44 additions & 0 deletions tests/structures/test_comparisons.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,3 +583,47 @@ def test_multiple_comparisons(self):
print(x == (50 + 50) < 2000)
print(x == (50 + 50) > 2000)
""")

def test_bad_contains(self):
self.assertCodeExecution("""
try:
print(0 in 0)
except TypeError as e:
print(e)
try:
print(0 in True)
except TypeError as e:
print(e)
class MyClass():
value = "I am not iterable!"
x = MyClass()
try:
print(0 in x)
except TypeError as e:
print(e)
""")

def test_bad_not_contains(self):
self.assertCodeExecution("""
try:
print(0 not in 0)
except TypeError as e:
print(e)
try:
print(0 not in True)
except TypeError as e:
print(e)
class MyClass():
value = "I am not iterable!"
x = MyClass()
try:
print(0 not in x)
except TypeError as e:
print(e)
""")

0 comments on commit 2262a71

Please sign in to comment.