Skip to content

Commit b1ad602

Browse files
committed
Applied minor improvements
1 parent 9ba4f66 commit b1ad602

File tree

9 files changed

+65
-38
lines changed

9 files changed

+65
-38
lines changed

docs/pages/helpers.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ Tinyscript provides some type checking functions, for common data:
334334
`ts.is_file` | dummy shortcut to `os.path.isfile`
335335
`ts.is_filemode` | simple file mode check (for Linux permissions)
336336
`ts.is_filetype` | regex-based check for file's type (relying on [`python-magic`](https://pypi.org/project/python-magic/))
337+
`ts.is_float` / `ts.is_pos_float` / `ts.is_neg_float` | float (positive / negative)
337338
`ts.is_hex` | hexadecimal string (case insensitive)
338339
`ts.is_in_path` | whether the target path is in the PATH environment variable
339340
`ts.is_int` / `ts.is_int_range` / `ts.is_pos_int` / `ts.is_neg_int` / `ts.is_prime` | integer (within range / positive / negative / prime)
@@ -436,8 +437,12 @@ While adding arguments to the parser (relying on `argparse`), Tinyscript provide
436437
`ts.ints` | `list(int)` | list of integers
437438
`ts.int_range` | single integer within range (second bound included!)
438439
`ts.ints_range` | list of integers within range (second bound included!)
440+
`ts.neg_float` / `negative_float` | `float` | single negative float
441+
`ts.neg_floats` / `negative_floats` | `list(float)` | list of negative floats
439442
`ts.neg_int` / `negative_int` | `int` | single negative integer
440443
`ts.neg_ints` / `negative_ints` | `list(int)` | list of negative integers
444+
`ts.pos_float` / `positive_float` | `float` | single positive float
445+
`ts.pos_floats` / `positive_floats` | `list(float)` | list of positive floats
441446
`ts.pos_int` / `positive_int` | `int` | single positive integer
442447
`ts.pos_ints` / `positive_ints` | `list(int)` | list of positive integers
443448
`ts.regular_expression` | `str` | string that can be parsed as a regular expression

src/tinyscript/VERSION.txt

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

src/tinyscript/features/timing.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from .loglib import logger
1111
from ..helpers.constants import WINDOWS
12-
from ..helpers.timeout import TimeoutError
1312

1413

1514
__all__ = ["set_time_items"]

src/tinyscript/helpers/data/types/common.py

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,19 @@
1212

1313

1414
# various object type check functions
15-
__all__ += ["is_bool", "is_dict", "is_int", "is_int_range", "is_list", "is_neg_int", "is_percentage", "is_pos_int",
16-
"is_prime"]
15+
__all__ += ["is_bool", "is_dict", "is_float", "is_int", "is_int_range", "is_list", "is_neg_float", "is_neg_int",
16+
"is_percentage", "is_pos_float", "is_pos_int", "is_prime"]
1717
is_bool = lambda b: isinstance(b, bool)
1818
is_dict = lambda d: isinstance(d, dict)
19+
is_float = lambda f: isinstance(f, float)
1920
is_int = lambda i: isinstance(i, int)
2021
is_int_range = lambda i, i1, i2=None: all(is_int(x) for x in [i, i1, i2 or 0]) and i in (range(i1+1) if i2 is None \
2122
else range(i1, i2+1))
2223
is_list = lambda l: isinstance(l, (list, set, tuple))
24+
is_neg_float = lambda f, zero=False: is_float(f) and (f <= 0. if zero else f < 0.)
2325
is_neg_int = lambda i, zero=False: is_int(i) and (i <= 0 if zero else i < 0)
2426
is_percentage = lambda f: isinstance(f, (int, float)) and 0. <= float(f) <= 1.
27+
is_pos_float = lambda f, zero=False: is_float(f) and (f >= 0. if zero else f > 0.)
2528
is_pos_int = lambda i, zero=True: is_int(i) and (i >= 0 if zero else i > 0)
2629
is_prime = lambda i: __prime_number(i)
2730

@@ -43,29 +46,44 @@
4346

4447

4548
# -------------------- DATA FORMAT ARGUMENT TYPES --------------------
46-
__all__ += ["int_range", "neg_int", "negative_int", "pos_int", "positive_int", "ints", "ints_range", "neg_ints",
47-
"negative_ints", "pos_ints", "positive_ints", "prime_number", "values_list"]
48-
49-
50-
def __ints(l, check_func=lambda x: False, idescr=None, shouldbe=None, **kwargs):
51-
""" Parses a comma-separated list of ints. """
52-
l = _str2list(l)
53-
msg = "{} {}integer{}".format(["Bad list of", "Not a"][len(l) == 1], "" if idescr is None else idescr + " ",
54-
["s", ""][len(l) == 1])
55-
if shouldbe is not None:
56-
msg += " (should be %s)" % shouldbe
57-
if not all(check_func(_, **kwargs) for _ in l):
58-
raise ValueError(msg)
59-
return l
60-
ints = lambda l: __ints(l, is_int)
61-
int_range = lambda i, i1, i2=None: __ints(i, is_int_range, "valid", "in range [%d,%d]" % \
62-
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)[0]
63-
negative_int = neg_int = lambda i, zero=False: __ints(i, is_neg_int, "negative", zero=zero)[0]
64-
positive_int = pos_int = lambda i, zero=True: __ints(i, is_pos_int, "positive", zero=zero)[0]
65-
ints_range = lambda l, i1, i2=None: __ints(l, is_int_range, "valid", "in range [%d,%d]" % \
66-
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)
67-
negative_ints = neg_ints = lambda l, zero=False: __ints(l, is_neg_int, "negative", zero=zero)
68-
positive_ints = pos_ints = lambda l, zero=True: __ints(l, is_pos_int, "positive", zero=zero)
49+
__all__ += ["floats", "int_range", "ints", "ints_range", "neg_float", "neg_floats", "negative_float", "negative_floats",
50+
"neg_int", "neg_ints", "negative_int", "negative_ints", "pos_float", "pos_floats", "positive_float",
51+
"positive_floats", "pos_int", "positive_int", "pos_ints", "positive_ints", "prime_number", "values_list"]
52+
53+
54+
def __n(ntype):
55+
def _wrapper(l, check_func=lambda x: False, idescr=None, shouldbe=None, **kwargs):
56+
""" Parses a comma-separated list of ints. """
57+
l = _str2list(l)
58+
if not all(check_func(x, **kwargs) for x in l):
59+
msg = f"{['Bad list of', 'Not a'][len(l) == 1]} {'' if idescr is None else idescr + ' '}{ntype}" \
60+
f"{['s', ''][len(l) == 1]}"
61+
if shouldbe is not None:
62+
msg += f" (should be {shouldbe})"
63+
raise ValueError(msg)
64+
return l
65+
return _wrapper
66+
67+
floats = lambda l: __n("float")(l, is_float)
68+
negative_float = neg_float = lambda i, zero=False: __n("float")(i, is_neg_float, "negative", zero=zero)[0]
69+
positive_float = pos_float = lambda i, zero=True: __n("float")(i, is_pos_float, "positive", zero=zero)[0]
70+
negative_floats = neg_floats = lambda l, zero=False: __n("float")(l, is_neg_float, "negative", zero=zero)
71+
positive_floats = pos_floats = lambda l, zero=True: __n("float")(l, is_pos_float, "positive", zero=zero)
72+
floats.__name__ = "floats"
73+
negative_float.__name__ = neg_float.__name__ = "negative float"
74+
negative_floats.__name__ = neg_floats.__name__ = "negative floats list"
75+
positive_float.__name__ = pos_float.__name__ = "positive float"
76+
positive_floats.__name__ = pos_floats.__name__ = "positive floats list"
77+
78+
ints = lambda l: __n("integer")(l, is_int)
79+
int_range = lambda i, i1, i2=None: __n("integer")(i, is_int_range, "valid", "in range [%d,%d]" % \
80+
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)[0]
81+
negative_int = neg_int = lambda i, zero=False: __n("integer")(i, is_neg_int, "negative", zero=zero)[0]
82+
positive_int = pos_int = lambda i, zero=True: __n("integer")(i, is_pos_int, "positive", zero=zero)[0]
83+
ints_range = lambda l, i1, i2=None: __n("integer")(l, is_int_range, "valid", "in range [%d,%d]" % \
84+
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)
85+
negative_ints = neg_ints = lambda l, zero=False: __n("integer")(l, is_neg_int, "negative", zero=zero)
86+
positive_ints = pos_ints = lambda l, zero=True: __n("integer")(l, is_pos_int, "positive", zero=zero)
6987
ints.__name__ = "integers"
7088
int_range.__name__ = "integer (from range)"
7189
ints_range.__name__ = "integers list (from range)"

src/tinyscript/helpers/timeout.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
from ..preimports import signal
99

1010

11-
__all__ = __features__ = ["timeout", "Timeout", "TimeoutError"]
12-
13-
14-
class TimeoutError(Exception):
15-
pass # TimeoutError is not handled in Python 2
11+
__all__ = __features__ = ["timeout", "Timeout"]
1612

1713

1814
class Timeout(object):
@@ -40,6 +36,7 @@ def __exit__(self, exc_type, exc_value, exc_traceback):
4036
raise NotImplementedError("signal.SIGALRM does not exist in Windows")
4137
else:
4238
signal.signal(signal.SIGALRM, signal.SIG_IGN)
39+
signal.alarm(0)
4340
return not self.stop
4441

4542
def _handler(self, signum, frame):

tests/test_features_timing.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import time
66

77
from tinyscript.features.timing import set_time_items
8-
from tinyscript.helpers.timeout import TimeoutError
98

109
from utils import *
1110

tests/test_helpers_data_types.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ def test_general_purpose_types(self):
6666
self.assertEqual(int_range(2, 1, 5), 2)
6767
self.assertRaises(ValueError, int_range, 5, 3)
6868
self.assertRaises(ValueError, int_range, 5, 1, 3)
69+
self.assertEqual(neg_float(-1.), -1.)
6970
self.assertEqual(neg_int(-1), -1)
71+
self.assertEqual(negative_float(-1.), -1.)
7072
self.assertEqual(negative_int(-1), -1)
7173
self.assertRaises(ValueError, neg_int, 0)
7274
self.assertRaises(ValueError, neg_int, 1)
@@ -90,6 +92,7 @@ def test_general_purpose_types(self):
9092
self.assertRaises(ValueError, ints_range, "0,1]", 1, 2)
9193
self.assertRaises(ValueError, ints_range, ["a", 1], 1, 2)
9294
self.assertEqual(neg_ints("-1"), [-1])
95+
self.assertEqual(negative_floats("[-1.,-2.]"), [-1., -2.])
9396
self.assertEqual(negative_ints("[-1,-2]"), [-1, -2])
9497
self.assertRaises(ValueError, neg_ints, "-1,-2]")
9598
self.assertRaises(ValueError, neg_ints, [-1, 1])
@@ -225,6 +228,9 @@ def test_network_related_types(self):
225228
self.assertRaises(ValueError, as_number, ASN3)
226229

227230
def test_data_type_check(self):
231+
self.assertTrue(is_float(1.))
232+
self.assertFalse(is_float(1))
233+
self.assertFalse(is_float("a"))
228234
self.assertTrue(is_int(1))
229235
self.assertFalse(is_int("a"))
230236
self.assertTrue(is_int_range(1, 1, 2))
@@ -235,10 +241,13 @@ def test_data_type_check(self):
235241
self.assertFalse(is_percentage(2))
236242
self.assertTrue(is_percentage(.1))
237243
self.assertFalse(is_percentage(".123"))
244+
self.assertTrue(is_pos_float(10.))
245+
self.assertTrue(is_pos_float(0., True))
238246
self.assertTrue(is_pos_int(10))
239247
self.assertTrue(is_pos_int(0, True))
240248
self.assertFalse(is_pos_int(0, False))
241249
self.assertFalse(is_pos_int(-10))
250+
self.assertTrue(is_neg_float(-10.))
242251
self.assertTrue(is_neg_int(-10))
243252
self.assertFalse(is_neg_int(10))
244253
for i in ["a", 2.2, 10, 145, 1537]:

tests/test_helpers_timeout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"""Timeout utility assets' tests.
33
44
"""
5-
from tinyscript.helpers.timeout import timeout, Timeout, TimeoutError
5+
from tinyscript.helpers.timeout import timeout, Timeout
66

77
from utils import *
88

tests/test_preimports_code.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def test_function_line_operations(self):
4040
code.replace_line(dummy2, 1, "# useless modified comment")
4141
self.assertIn("useless modified comment", code.source(dummy2))
4242
code.add_line(dummy2, 1, "# another useless comment before first")
43-
code.add_line(dummy2, 2, "pass", after=True)
43+
code.insert_line(dummy2, 2, "pass", after=True)
4444
self.assertEqual(len(code.source(dummy2).split("\n")), 5)
4545
code.remove_line(dummy2, -1)
4646
self.assertIsNone(dummy2())
@@ -61,11 +61,11 @@ def test_function_line_operations(self):
6161
code.add_lines(dummy2, -1, "return 12345", -2, "# this return will not execute")
6262
self.assertEqual(len(code.source(dummy2).split("\n")), 6)
6363
self.assertEqual(dummy2(), 84)
64-
code.add_line(dummy2, 1, "return 3*42")
64+
code.insert_line(dummy2, 1, "return 3*42")
6565
self.assertEqual(dummy2(), 126)
66-
code.add_line(dummy2, 1, "return 4*42", after=True)
66+
code.insert_line(dummy2, 1, "return 4*42", after=True)
6767
self.assertEqual(dummy2(), 126)
68-
code.add_line(dummy2, 0, "# dummy function")
68+
code.insert_line(dummy2, 0, "# dummy function")
6969
self.assertEqual(len(code.source(dummy2).split("\n")), 9)
7070
code.delete_lines(dummy2, -1, -2, -3, -4)
7171
self.assertEqual(len(code.source(dummy2).split("\n")), 5)

0 commit comments

Comments
 (0)