Skip to content

Commit

Permalink
Applied minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
dhondta committed May 7, 2024
1 parent 9ba4f66 commit b1ad602
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 38 deletions.
5 changes: 5 additions & 0 deletions docs/pages/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ Tinyscript provides some type checking functions, for common data:
`ts.is_file` | dummy shortcut to `os.path.isfile`
`ts.is_filemode` | simple file mode check (for Linux permissions)
`ts.is_filetype` | regex-based check for file's type (relying on [`python-magic`](https://pypi.org/project/python-magic/))
`ts.is_float` / `ts.is_pos_float` / `ts.is_neg_float` | float (positive / negative)
`ts.is_hex` | hexadecimal string (case insensitive)
`ts.is_in_path` | whether the target path is in the PATH environment variable
`ts.is_int` / `ts.is_int_range` / `ts.is_pos_int` / `ts.is_neg_int` / `ts.is_prime` | integer (within range / positive / negative / prime)
Expand Down Expand Up @@ -436,8 +437,12 @@ While adding arguments to the parser (relying on `argparse`), Tinyscript provide
`ts.ints` | `list(int)` | list of integers
`ts.int_range` | single integer within range (second bound included!)
`ts.ints_range` | list of integers within range (second bound included!)
`ts.neg_float` / `negative_float` | `float` | single negative float
`ts.neg_floats` / `negative_floats` | `list(float)` | list of negative floats
`ts.neg_int` / `negative_int` | `int` | single negative integer
`ts.neg_ints` / `negative_ints` | `list(int)` | list of negative integers
`ts.pos_float` / `positive_float` | `float` | single positive float
`ts.pos_floats` / `positive_floats` | `list(float)` | list of positive floats
`ts.pos_int` / `positive_int` | `int` | single positive integer
`ts.pos_ints` / `positive_ints` | `list(int)` | list of positive integers
`ts.regular_expression` | `str` | string that can be parsed as a regular expression
Expand Down
2 changes: 1 addition & 1 deletion src/tinyscript/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.30.9
1.30.10
1 change: 0 additions & 1 deletion src/tinyscript/features/timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from .loglib import logger
from ..helpers.constants import WINDOWS
from ..helpers.timeout import TimeoutError


__all__ = ["set_time_items"]
Expand Down
68 changes: 43 additions & 25 deletions src/tinyscript/helpers/data/types/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@


# various object type check functions
__all__ += ["is_bool", "is_dict", "is_int", "is_int_range", "is_list", "is_neg_int", "is_percentage", "is_pos_int",
"is_prime"]
__all__ += ["is_bool", "is_dict", "is_float", "is_int", "is_int_range", "is_list", "is_neg_float", "is_neg_int",
"is_percentage", "is_pos_float", "is_pos_int", "is_prime"]
is_bool = lambda b: isinstance(b, bool)
is_dict = lambda d: isinstance(d, dict)
is_float = lambda f: isinstance(f, float)
is_int = lambda i: isinstance(i, int)
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 \
else range(i1, i2+1))
is_list = lambda l: isinstance(l, (list, set, tuple))
is_neg_float = lambda f, zero=False: is_float(f) and (f <= 0. if zero else f < 0.)
is_neg_int = lambda i, zero=False: is_int(i) and (i <= 0 if zero else i < 0)
is_percentage = lambda f: isinstance(f, (int, float)) and 0. <= float(f) <= 1.
is_pos_float = lambda f, zero=False: is_float(f) and (f >= 0. if zero else f > 0.)
is_pos_int = lambda i, zero=True: is_int(i) and (i >= 0 if zero else i > 0)
is_prime = lambda i: __prime_number(i)

Expand All @@ -43,29 +46,44 @@


# -------------------- DATA FORMAT ARGUMENT TYPES --------------------
__all__ += ["int_range", "neg_int", "negative_int", "pos_int", "positive_int", "ints", "ints_range", "neg_ints",
"negative_ints", "pos_ints", "positive_ints", "prime_number", "values_list"]


def __ints(l, check_func=lambda x: False, idescr=None, shouldbe=None, **kwargs):
""" Parses a comma-separated list of ints. """
l = _str2list(l)
msg = "{} {}integer{}".format(["Bad list of", "Not a"][len(l) == 1], "" if idescr is None else idescr + " ",
["s", ""][len(l) == 1])
if shouldbe is not None:
msg += " (should be %s)" % shouldbe
if not all(check_func(_, **kwargs) for _ in l):
raise ValueError(msg)
return l
ints = lambda l: __ints(l, is_int)
int_range = lambda i, i1, i2=None: __ints(i, is_int_range, "valid", "in range [%d,%d]" % \
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)[0]
negative_int = neg_int = lambda i, zero=False: __ints(i, is_neg_int, "negative", zero=zero)[0]
positive_int = pos_int = lambda i, zero=True: __ints(i, is_pos_int, "positive", zero=zero)[0]
ints_range = lambda l, i1, i2=None: __ints(l, is_int_range, "valid", "in range [%d,%d]" % \
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)
negative_ints = neg_ints = lambda l, zero=False: __ints(l, is_neg_int, "negative", zero=zero)
positive_ints = pos_ints = lambda l, zero=True: __ints(l, is_pos_int, "positive", zero=zero)
__all__ += ["floats", "int_range", "ints", "ints_range", "neg_float", "neg_floats", "negative_float", "negative_floats",
"neg_int", "neg_ints", "negative_int", "negative_ints", "pos_float", "pos_floats", "positive_float",
"positive_floats", "pos_int", "positive_int", "pos_ints", "positive_ints", "prime_number", "values_list"]


def __n(ntype):
def _wrapper(l, check_func=lambda x: False, idescr=None, shouldbe=None, **kwargs):
""" Parses a comma-separated list of ints. """
l = _str2list(l)
if not all(check_func(x, **kwargs) for x in l):
msg = f"{['Bad list of', 'Not a'][len(l) == 1]} {'' if idescr is None else idescr + ' '}{ntype}" \
f"{['s', ''][len(l) == 1]}"
if shouldbe is not None:
msg += f" (should be {shouldbe})"
raise ValueError(msg)
return l
return _wrapper

floats = lambda l: __n("float")(l, is_float)
negative_float = neg_float = lambda i, zero=False: __n("float")(i, is_neg_float, "negative", zero=zero)[0]
positive_float = pos_float = lambda i, zero=True: __n("float")(i, is_pos_float, "positive", zero=zero)[0]
negative_floats = neg_floats = lambda l, zero=False: __n("float")(l, is_neg_float, "negative", zero=zero)
positive_floats = pos_floats = lambda l, zero=True: __n("float")(l, is_pos_float, "positive", zero=zero)
floats.__name__ = "floats"
negative_float.__name__ = neg_float.__name__ = "negative float"
negative_floats.__name__ = neg_floats.__name__ = "negative floats list"
positive_float.__name__ = pos_float.__name__ = "positive float"
positive_floats.__name__ = pos_floats.__name__ = "positive floats list"

ints = lambda l: __n("integer")(l, is_int)
int_range = lambda i, i1, i2=None: __n("integer")(i, is_int_range, "valid", "in range [%d,%d]" % \
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)[0]
negative_int = neg_int = lambda i, zero=False: __n("integer")(i, is_neg_int, "negative", zero=zero)[0]
positive_int = pos_int = lambda i, zero=True: __n("integer")(i, is_pos_int, "positive", zero=zero)[0]
ints_range = lambda l, i1, i2=None: __n("integer")(l, is_int_range, "valid", "in range [%d,%d]" % \
(0 if i2 is None else i1, i1 if i2 is None else i2), i1=i1, i2=i2)
negative_ints = neg_ints = lambda l, zero=False: __n("integer")(l, is_neg_int, "negative", zero=zero)
positive_ints = pos_ints = lambda l, zero=True: __n("integer")(l, is_pos_int, "positive", zero=zero)
ints.__name__ = "integers"
int_range.__name__ = "integer (from range)"
ints_range.__name__ = "integers list (from range)"
Expand Down
7 changes: 2 additions & 5 deletions src/tinyscript/helpers/timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@
from ..preimports import signal


__all__ = __features__ = ["timeout", "Timeout", "TimeoutError"]


class TimeoutError(Exception):
pass # TimeoutError is not handled in Python 2
__all__ = __features__ = ["timeout", "Timeout"]


class Timeout(object):
Expand Down Expand Up @@ -40,6 +36,7 @@ def __exit__(self, exc_type, exc_value, exc_traceback):
raise NotImplementedError("signal.SIGALRM does not exist in Windows")
else:
signal.signal(signal.SIGALRM, signal.SIG_IGN)
signal.alarm(0)
return not self.stop

def _handler(self, signum, frame):
Expand Down
1 change: 0 additions & 1 deletion tests/test_features_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import time

from tinyscript.features.timing import set_time_items
from tinyscript.helpers.timeout import TimeoutError

from utils import *

Expand Down
9 changes: 9 additions & 0 deletions tests/test_helpers_data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ def test_general_purpose_types(self):
self.assertEqual(int_range(2, 1, 5), 2)
self.assertRaises(ValueError, int_range, 5, 3)
self.assertRaises(ValueError, int_range, 5, 1, 3)
self.assertEqual(neg_float(-1.), -1.)
self.assertEqual(neg_int(-1), -1)
self.assertEqual(negative_float(-1.), -1.)
self.assertEqual(negative_int(-1), -1)
self.assertRaises(ValueError, neg_int, 0)
self.assertRaises(ValueError, neg_int, 1)
Expand All @@ -90,6 +92,7 @@ def test_general_purpose_types(self):
self.assertRaises(ValueError, ints_range, "0,1]", 1, 2)
self.assertRaises(ValueError, ints_range, ["a", 1], 1, 2)
self.assertEqual(neg_ints("-1"), [-1])
self.assertEqual(negative_floats("[-1.,-2.]"), [-1., -2.])
self.assertEqual(negative_ints("[-1,-2]"), [-1, -2])
self.assertRaises(ValueError, neg_ints, "-1,-2]")
self.assertRaises(ValueError, neg_ints, [-1, 1])
Expand Down Expand Up @@ -225,6 +228,9 @@ def test_network_related_types(self):
self.assertRaises(ValueError, as_number, ASN3)

def test_data_type_check(self):
self.assertTrue(is_float(1.))
self.assertFalse(is_float(1))
self.assertFalse(is_float("a"))
self.assertTrue(is_int(1))
self.assertFalse(is_int("a"))
self.assertTrue(is_int_range(1, 1, 2))
Expand All @@ -235,10 +241,13 @@ def test_data_type_check(self):
self.assertFalse(is_percentage(2))
self.assertTrue(is_percentage(.1))
self.assertFalse(is_percentage(".123"))
self.assertTrue(is_pos_float(10.))
self.assertTrue(is_pos_float(0., True))
self.assertTrue(is_pos_int(10))
self.assertTrue(is_pos_int(0, True))
self.assertFalse(is_pos_int(0, False))
self.assertFalse(is_pos_int(-10))
self.assertTrue(is_neg_float(-10.))
self.assertTrue(is_neg_int(-10))
self.assertFalse(is_neg_int(10))
for i in ["a", 2.2, 10, 145, 1537]:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_helpers_timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""Timeout utility assets' tests.
"""
from tinyscript.helpers.timeout import timeout, Timeout, TimeoutError
from tinyscript.helpers.timeout import timeout, Timeout

from utils import *

Expand Down
8 changes: 4 additions & 4 deletions tests/test_preimports_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_function_line_operations(self):
code.replace_line(dummy2, 1, "# useless modified comment")
self.assertIn("useless modified comment", code.source(dummy2))
code.add_line(dummy2, 1, "# another useless comment before first")
code.add_line(dummy2, 2, "pass", after=True)
code.insert_line(dummy2, 2, "pass", after=True)
self.assertEqual(len(code.source(dummy2).split("\n")), 5)
code.remove_line(dummy2, -1)
self.assertIsNone(dummy2())
Expand All @@ -61,11 +61,11 @@ def test_function_line_operations(self):
code.add_lines(dummy2, -1, "return 12345", -2, "# this return will not execute")
self.assertEqual(len(code.source(dummy2).split("\n")), 6)
self.assertEqual(dummy2(), 84)
code.add_line(dummy2, 1, "return 3*42")
code.insert_line(dummy2, 1, "return 3*42")
self.assertEqual(dummy2(), 126)
code.add_line(dummy2, 1, "return 4*42", after=True)
code.insert_line(dummy2, 1, "return 4*42", after=True)
self.assertEqual(dummy2(), 126)
code.add_line(dummy2, 0, "# dummy function")
code.insert_line(dummy2, 0, "# dummy function")
self.assertEqual(len(code.source(dummy2).split("\n")), 9)
code.delete_lines(dummy2, -1, -2, -3, -4)
self.assertEqual(len(code.source(dummy2).split("\n")), 5)
Expand Down

0 comments on commit b1ad602

Please sign in to comment.