Skip to content

Commit

Permalink
Merge pull request beeware#525 from ivanistheone/builtin_filter
Browse files Browse the repository at this point in the history
add filter builtin
  • Loading branch information
eliasdorneles authored May 2, 2017
2 parents 72c7864 + 288dbab commit dfdf402
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 43 deletions.
3 changes: 1 addition & 2 deletions python/common/org/Python.java
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,7 @@ public static org.python.Object exec() {
args = {"function", "iterable"}
)
public static org.python.Object filter(org.python.Object function, org.python.Object iterable) {
org.python.Iterable iterator = org.Python.iter(iterable);
throw new org.python.exceptions.NotImplementedError("Builtin function 'filter' not implemented");
return new org.python.types.Filter(function, org.Python.iter(iterable));
}

@org.python.Method(
Expand Down
39 changes: 39 additions & 0 deletions python/common/org/python/types/Filter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.python.types;

public class Filter extends org.python.types.Object implements org.python.Iterable {
private org.python.Callable callable;
private org.python.Iterable iterator;

public Filter(org.python.Object callable, org.python.Iterable iterator) {
if (org.python.types.NoneType.NONE == callable) {
this.callable = null;
} else {
this.callable = (org.python.Callable) callable;
}
this.iterator = iterator;
}

@org.python.Method(
__doc__ = "Implement iter(self)."
)
public org.python.Iterable __iter__() {
return this;
}

@org.python.Method(
__doc__ = "Implement next(self)."
)
public org.python.Object __next__() {
while (true) { // loop until we find first true
org.python.Object current = iterator.__next__();
org.python.Object value = current;
if (callable != null) {
org.python.Object[] args = new org.python.Object[] {current};
value = callable.invoke(args, new java.util.HashMap());
}
if (value.toBoolean()) {
return current;
}
}
}
}
51 changes: 10 additions & 41 deletions tests/builtins/test_filter.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,22 @@
from .. utils import TranspileTestCase, BuiltinTwoargFunctionTestCase

from unittest import expectedFailure


class FilterTests(TranspileTestCase):
base_code = """
#placeholder while list()s etc aren't fully implemented
class ListLike:
x = %s
index = 0
def __iter__(self):
return self
def __next__(self):
self.index = self.index + 1
if self.index > len(self.x):
raise StopIteration
return self.x[self.index]
def testish(x):
return %s
print(filter(testish, ListLike()))
mylist = ListLike()
print(filter(testish, mylist).__next__())
print(filter(testish, mylist).__next__())
print(filter(testish, mylist).__next__())
try:
print(filter(testish, mylist).__next__())
except StopIteration:
pass
"""

@expectedFailure
def test_bool(self):
self.assertCodeExecution(self.base_code % ("[True, False, True]", "bool(x)"))
self.assertCodeExecution('print(list(filter(bool, [True, False, True])))')
self.assertCodeExecution('print(list(filter(bool, [1, 0, 3, -1])))')
self.assertCodeExecution('print(list(filter(bool, [])))')

@expectedFailure
def test_bytearray(self):
self.assertCodeExecution(self.base_code % ("b'123'", "x"))
def test_none(self):
self.assertCodeExecution('print(list(filter(None, [True, False, True])))')
self.assertCodeExecution('print(list(filter(None, [])))')

@expectedFailure
def test_float(self):
self.assertCodeExecution(self.base_code % ("[3.14, 2.17, 1.0]", "x > 1"))
def test_lambda(self):
self.assertCodeExecution('print(list(filter(lambda x: x > 1, [3, 4, 56, 1, -11])))')

@expectedFailure
def test_int(self):
self.assertCodeExecution(self.base_code % ("[1, 2, 3]", "x * 2"))
def test_wrong_argument(self):
self.assertCodeExecution('print(list(filter(None, None)))', exits_early=True)


class BuiltinFilterFunctionTests(BuiltinTwoargFunctionTestCase, TranspileTestCase):
Expand Down

0 comments on commit dfdf402

Please sign in to comment.