Skip to content

Commit 9ba4f66

Browse files
committed
Improved compatibility function reduce (stop condition)
1 parent 91d1975 commit 9ba4f66

File tree

6 files changed

+38
-7
lines changed

6 files changed

+38
-7
lines changed

docs/pages/helpers.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ It also defines a few utility or backward-compatibility functions.
3333
`ensure_str` | ensures the input, either string or bytes, is a string
3434
`execfile` | same function as used in Python 2
3535
`iterbytes` | iterates over the bytes of a string (kept for backward compatibility)
36+
`reduce` | similar to `functools.reduce`, but with a `condition` optional argument to define a stop condition
3637
`u` | dummy alias for `str` (kept for backward compatibility)
3738

3839
!!! warning "Global scope and the `ts` module"

src/tinyscript/VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.30.8
1+
1.30.9

src/tinyscript/helpers/compat.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
"""Formerly common Python2/3 compatibility functions, now left for backward-compatibility.
33
44
"""
5-
from functools import reduce
6-
7-
85
__all__ = __features__ = ["b", "binary_type", "byteindex", "execfile", "ensure_binary", "ensure_str", "iterbytes",
96
"reduce", "string_types", "text_type", "u"]
107

@@ -63,3 +60,21 @@ def iterbytes(text):
6360
for c in text:
6461
yield c
6562

63+
64+
_initial_missing = object()
65+
66+
def reduce(function, sequence, initial=_initial_missing, stop=None):
67+
""" Similar to functools.reduce, but with a stop condition.
68+
reduce(function, sequence[, initial, stop]) -> value """
69+
it = iter(sequence)
70+
try:
71+
value = next(it) if initial is _initial_missing else initial
72+
except StopIteration:
73+
raise TypeError("reduce() of empty sequence with no initial value") from None
74+
for element in it:
75+
v = function(value, element)
76+
if stop and stop(v):
77+
break
78+
value = v
79+
return value
80+

tests/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- coding: UTF-8 -*-
2+
import pytest
3+
4+
from utils import remove
5+
6+
7+
@pytest.fixture(scope="session", autouse=True)
8+
def clear_files_teardown():
9+
yield None
10+
for f in [".test-script.py", ".tinyscript-test.ini", "report.pdf", "test-script.py"]:
11+
remove(f)
12+

tests/test_helpers_compat.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@ def test_compatibility_functions(self):
2121
self.assertRaises(TypeError, ensure_binary, [])
2222
self.assertEqual(ensure_binary("test"), b("test"))
2323
self.assertEqual(ensure_binary(b"test"), b("test"))
24+
l = (_ for _ in range(100000000))
25+
self.assertRaises(TypeError, reduce, lambda x: x, [])
26+
self.assertEqual(reduce(lambda a, b: a+b, l, stop=lambda x: x > 1000), 990)
27+
self.assertEqual(reduce(lambda a, b: a+b, l, 20, stop=lambda x: x > 1000), 938)
2428

tests/utils.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
from os.path import dirname, exists, join
1111
from shutil import rmtree as shutil_rmtree
1212
from time import sleep
13-
from tinyscript.helpers.constants import WINDOWS
14-
from tinyscript.helpers.decorators import failsafe
13+
from tinyscript.helpers import failsafe, Path, WINDOWS
1514
from tinyscript.argreparse import ArgumentParser
1615
from unittest import TestCase
1716
try:
@@ -22,7 +21,7 @@
2221

2322
__all__ = ["args", "dirname", "dummy_function", "dummy_lambda", "dummy_sleep", "exists", "join", "logger", "logging",
2423
"makedirs", "mock_patch", "remove", "rmdir", "rmtree", "sleep", "sys", "temp_stdin", "touch", "temp_stdout",
25-
"tmpf", "FakeLogRecord", "FakeNamespace", "TestCase", "_FakeParserAction", "FIXTURES", "WINDOWS"]
24+
"tmpf", "FakeLogRecord", "FakeNamespace", "Path", "TestCase", "_FakeParserAction", "FIXTURES", "WINDOWS"]
2625

2726

2827
FIXTURES = ArgumentParser._globals_dict = {

0 commit comments

Comments
 (0)