istr-python 1.1.32__tar.gz → 1.1.33__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: istr-python
3
- Version: 1.1.32
3
+ Version: 1.1.33
4
4
  Summary: istr - strings you can count on
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/salabim/istr
@@ -367,7 +367,18 @@ to unpack multiple values, e.g.
367
367
  a, b, c = istr(5, 6, 7) ==> a=istr('5') , b=istr('6'), c=istr('7')
368
368
  a, b, c = istr(*range(3)) ==> a=istr('0') , b=istr('1'), c=istr('2')
369
369
  ```
370
+ #### Alternative way of range specification
371
+
372
+ Instead of `istr(range(..))` it is possible to use `istr,range(..)` instead, like
373
+
374
+ `list(istr.range(3,6))` ==> `[istr('3'), istr('4'), istr('5')]`
375
+
376
+ In contrast to the builtin `range`, `istr.range` supports a non keyword parameter `length`:
377
+
378
+ `list(istr.range(length=3))` is equivalent to `istr.range(100, 1000)`
379
+
370
380
  #### test for even/odd
381
+
371
382
  It is possible to test for even/odd (provided the istr can be interpreted as an int) with the `is_even` and `is_odd` method, e.g.
372
383
 
373
384
  ```
@@ -754,13 +765,17 @@ In contrast to `math.sumprod()`, `istr.sumprod()` supports a `strict` parameter
754
765
  Thus, `istr.sumprod("12", (3,4,5), strict=False)` is `istr(11)`, whereas `istr.sumprod("12", (3,4,5))`
755
766
  raises a ValueError.
756
767
 
757
- #### get all squares, cubes, power ofs or primes in a given range
768
+ #### get all squares, cubes, power ofs or primes in a given range or with a given length
758
769
 
759
770
  The class methods `istr.squares`, `istr.cubes`, `istr.power_ofs` and `istr.primes` can be used to get a list of all squares, cubes, power_ofs or primes up to a given upperbound (non inclusive) or between a given lower bound and upper bound (non inclusive), like:
760
771
 
761
772
  `istr.squares (100)` returns a list of all squares <100
762
773
  `istr.squares(50, 100)` returns a list of all squares in the range [50, 100)
763
774
 
775
+ Alternatively, it is possible to get a list of all squares, cubes, power_ofs or primes with a given length, like:
776
+
777
+ `istr.squares (length=2)` returns a list of all squares of length 2, so between 10 and 99.
778
+
764
779
  Unless `cache=False` is specified, the query result is cached.
765
780
 
766
781
  #### generate istr with digits
@@ -354,7 +354,18 @@ to unpack multiple values, e.g.
354
354
  a, b, c = istr(5, 6, 7) ==> a=istr('5') , b=istr('6'), c=istr('7')
355
355
  a, b, c = istr(*range(3)) ==> a=istr('0') , b=istr('1'), c=istr('2')
356
356
  ```
357
+ #### Alternative way of range specification
358
+
359
+ Instead of `istr(range(..))` it is possible to use `istr,range(..)` instead, like
360
+
361
+ `list(istr.range(3,6))` ==> `[istr('3'), istr('4'), istr('5')]`
362
+
363
+ In contrast to the builtin `range`, `istr.range` supports a non keyword parameter `length`:
364
+
365
+ `list(istr.range(length=3))` is equivalent to `istr.range(100, 1000)`
366
+
357
367
  #### test for even/odd
368
+
358
369
  It is possible to test for even/odd (provided the istr can be interpreted as an int) with the `is_even` and `is_odd` method, e.g.
359
370
 
360
371
  ```
@@ -741,13 +752,17 @@ In contrast to `math.sumprod()`, `istr.sumprod()` supports a `strict` parameter
741
752
  Thus, `istr.sumprod("12", (3,4,5), strict=False)` is `istr(11)`, whereas `istr.sumprod("12", (3,4,5))`
742
753
  raises a ValueError.
743
754
 
744
- #### get all squares, cubes, power ofs or primes in a given range
755
+ #### get all squares, cubes, power ofs or primes in a given range or with a given length
745
756
 
746
757
  The class methods `istr.squares`, `istr.cubes`, `istr.power_ofs` and `istr.primes` can be used to get a list of all squares, cubes, power_ofs or primes up to a given upperbound (non inclusive) or between a given lower bound and upper bound (non inclusive), like:
747
758
 
748
759
  `istr.squares (100)` returns a list of all squares <100
749
760
  `istr.squares(50, 100)` returns a list of all squares in the range [50, 100)
750
761
 
762
+ Alternatively, it is possible to get a list of all squares, cubes, power_ofs or primes with a given length, like:
763
+
764
+ `istr.squares (length=2)` returns a list of all squares of length 2, so between 10 and 99.
765
+
751
766
  Unless `cache=False` is specified, the query result is cached.
752
767
 
753
768
  #### generate istr with digits
@@ -5,7 +5,7 @@
5
5
  # |_||___/ \__||_|
6
6
  # strings you can count on
7
7
 
8
- __version__ = "1.1.32"
8
+ __version__ = "1.1.33"
9
9
  import functools
10
10
  import itertools
11
11
  import types
@@ -16,6 +16,7 @@ import operator
16
16
  import copy
17
17
  import bisect
18
18
  import collections
19
+ import numbers
19
20
 
20
21
  """
21
22
  Note: the changelog is in changelog.md
@@ -33,12 +34,10 @@ class _range:
33
34
  based on https://codereview.stackexchange.com/questions/229073/pure-python-range-implementation
34
35
  """
35
36
 
36
- def __init__(self, cls, start, stop=None, step=1, base=None, int_format=None, repr_mode=None):
37
- if stop is None:
38
- start, stop = 0, start
39
- self.start, self.stop, self.step = (int(obj) for obj in (start, stop, step))
40
- if step == 0:
41
- raise ValueError("range() arg 3 must not be zero")
37
+ def __init__(self, cls, start, stop, step, length, base, int_format, repr_mode):
38
+ self.start, self.stop, self.step = process_start_stop_step_length(start, stop, step, length)
39
+ if self.step == 0:
40
+ raise ValueError(f"step must not be zero, not {self.step}")
42
41
  if self.step < 0:
43
42
  step_sign = -1
44
43
  else:
@@ -232,8 +231,8 @@ class istr(str):
232
231
  _nan = object()
233
232
  _digits_cache = {}
234
233
 
235
- @staticmethod
236
- def _to_base(number, base):
234
+ @classmethod
235
+ def _to_base(cls, number, base):
237
236
  if number < 0:
238
237
  raise ValueError(f"negative numbers are not allowed for base {base}")
239
238
  result = ""
@@ -298,7 +297,7 @@ class istr(str):
298
297
  if base == 10:
299
298
  as_str = str(as_int)
300
299
  else:
301
- as_str = istr._to_base(as_int, base)
300
+ as_str = cls._to_base(as_int, base)
302
301
  else:
303
302
  as_str = f"{as_int:{int_format}}"
304
303
 
@@ -447,24 +446,21 @@ class istr(str):
447
446
  return True
448
447
 
449
448
  @classmethod
450
- def primes(cls, lb_or_ub, ub=None, cache=True):
451
- lb, ub = (0, lb_or_ub) if ub is None else (lb_or_ub, ub)
452
- if lb < 0:
453
- lb = 0
454
- lb = int(lb)
455
- ub = int(ub)
449
+ def primes(cls, start=None, stop=None, /, length=None, cache=True):
456
450
  """
457
451
  returns all primes up to a given upperbound or between a given lowerbound and upperbound
452
+ alternatively, the length can be given
458
453
  """
459
- if (cls, "primes", lb, ub) in _cache:
460
- return _cache[cls, "primes", lb, ub]
454
+ start, stop, step = process_start_stop_step_length(start, stop, 1, length)
455
+ if (cls, "primes", start, stop) in _cache:
456
+ return _cache[cls, "primes", start, stop]
461
457
 
462
- if ub <= 1_000_000:
463
- result = in_range(cls._primes_up_to_1_000_000(), lb, ub)
458
+ if stop <= 1_000_000:
459
+ result = in_range(cls._primes_up_to_1_000_000(), start, stop)
464
460
  else:
465
- result = cls._primes(lb, ub)
461
+ result = cls._primes(start, stop)
466
462
  if cache:
467
- _cache[cls, "primes", lb, ub] = result
463
+ _cache[cls, "primes", start, stop] = result
468
464
  return result
469
465
 
470
466
  @classmethod
@@ -496,8 +492,7 @@ class istr(str):
496
492
 
497
493
  def is_power_of(self, exponent):
498
494
  n = istr.interpret_as_int(self)
499
- if isinstance(exponent, istr):
500
- exponent = int(exponent)
495
+ exponent = check_integer(exponent, "exponent")
501
496
  if n < 0:
502
497
  if exponent % 2 == 0:
503
498
  return False
@@ -510,8 +505,6 @@ class istr(str):
510
505
  return True
511
506
  case x if x < 0:
512
507
  raise ValueError(f"exponent must be >=0; not {exponent}")
513
- case _ if not isinstance(exponent, int):
514
- raise TypeError(f"exponent must be int; not {type(exponent)}")
515
508
  case _ if n < 1_000_000:
516
509
  return n in istr._power_ofs_up_to_1_000_000_as_set(exponent)
517
510
  case _:
@@ -519,41 +512,46 @@ class istr(str):
519
512
  return n == round(n ** (1 / exponent)) ** exponent
520
513
 
521
514
  @classmethod
522
- def squares(cls, lb_or_ub, ub=None, cache=True):
515
+ def squares(cls, start=None, stop=None, /, length=None, cache=True):
523
516
  """
524
- returns all squares up to a given upperbound or between a given lowerbound and upperbound
517
+ returns all squares up to a given stop or between a given start and stop
518
+ alternatively, the length can be given
525
519
  """
526
- return cls.power_ofs(2, lb_or_ub, ub, cache=cache)
520
+ return cls.power_ofs(2, start, stop, length=length, cache=cache)
527
521
 
528
522
  @classmethod
529
- def cubes(cls, lb_or_ub, ub=None, cache=True):
530
- return cls.power_ofs(3, lb_or_ub, ub, cache=cache)
523
+ def cubes(cls, start=None, stop=None, /, length=None, cache=True):
524
+ """
525
+ returns all cubes up to a given stop or between a given start and stop
526
+ alternatively, the length can be given
527
+ """
528
+ return cls.power_ofs(3, start, stop, length=length, cache=cache)
531
529
 
532
530
  @classmethod
533
- def power_ofs(cls, exponent, lb_or_ub, ub=None, cache=True):
531
+ def power_ofs(cls, exponent, start=None, stop=None, /, length=None, cache=True):
534
532
  """
535
- returns all power of n up to a given upperbound or between a given lowerbound and upperbound
533
+ returns all power of n up to a given stop or between a given start and stop
534
+ alternatively, the length can be given
536
535
  """
537
- lb, ub = (0, lb_or_ub) if ub is None else (lb_or_ub, ub)
538
- lb = int(lb)
539
- ub = int(ub)
536
+ start, stop, step = process_start_stop_step_length(start, stop, 1, length)
537
+ exponent = check_integer(exponent, "exponent")
540
538
 
541
- if (cls, "power_ofs", exponent, lb, ub) in _cache:
542
- return _cache[cls, "power_ofs", exponent, lb, ub]
539
+ if (cls, "power_ofs", exponent, start, stop) in _cache:
540
+ return _cache[cls, "power_ofs", exponent, start, stop]
543
541
  match exponent:
544
542
  case 0:
545
- if lb <= 1 < ub:
543
+ if start <= 1 < stop:
546
544
  result = [istr(1)]
547
545
  else:
548
546
  result = []
549
547
  case 1:
550
- result = cls(list(range(lb, ub)))
551
- case x if (x % 2 == 0 or lb >= 0) and ub <= 1_000_000:
552
- result = in_range(cls._power_ofs_up_to_1_000_000(exponent), lb, ub)
548
+ result = cls(list(range(start, stop)))
549
+ case x if (x % 2 == 0 or start >= 0) and stop <= 1_000_000:
550
+ result = in_range(cls._power_ofs_up_to_1_000_000(exponent), start, stop)
553
551
  case _:
554
- result = cls._power_ofs(exponent, lb, ub)
552
+ result = cls._power_ofs(exponent, start, stop)
555
553
  if cache:
556
- _cache[cls, "power_ofs", exponent, lb, ub] = result
554
+ _cache[cls, "power_ofs", exponent, start, stop] = result
557
555
  return result
558
556
 
559
557
  @classmethod
@@ -728,27 +726,26 @@ class istr(str):
728
726
  "removesuffix replace rjust rpartition rsplit rstrip split strip swapcase title translate upper zfill"
729
727
  ).split():
730
728
  locals()[name] = functools.partialmethod(_str_method, name)
731
-
729
+
732
730
  @classmethod
733
- def zip(cls, *iterables, strict=False,join=False):
731
+ def zip(cls, *iterables, strict=False, join=False):
734
732
  if join:
735
- return cls.concat(map(cls, zip(*iterables, strict=strict)))
733
+ return cls.concat(cls(zip(*iterables, strict=strict)))
736
734
  else:
737
- return map(cls, zip(*iterables, strict=strict))
738
-
735
+ return cls(zip(*iterables, strict=strict))
736
+
739
737
  @classmethod
740
- def batched(cls,iterable, n, *, strict=False,join=False):
741
- print("*** batched internal")
738
+ def batched(cls, iterable, n, *, strict=False, join=False): # will be overridden if in itertools and not Python 3.12
742
739
  if n < 1:
743
- raise ValueError('n must be at least one')
740
+ raise ValueError("n must be at least one")
744
741
  iterator = iter(iterable)
745
742
  while batch := tuple(itertools.islice(iterator, n)):
746
743
  if strict and len(batch) != n:
747
- raise ValueError('batched(): incomplete batch')
744
+ raise ValueError("istr.batched(): incomplete batch")
748
745
  if join:
749
- yield cls.join(istr(batch))
746
+ yield cls.join(cls(batch))
750
747
  else:
751
- yield istr(batch)
748
+ yield cls(batch)
752
749
 
753
750
  @classmethod
754
751
  def _itertools_method(cls, name, *args, **kwargs):
@@ -764,9 +761,9 @@ class istr(str):
764
761
  match name:
765
762
  case "groupby" | "tee":
766
763
  locals()[name] = getattr(itertools, name)
767
- case "permutations" | "combinations" | "combinations_with_replacement" | "product"|"batched"|"pairwise"|"zip_longest":
768
- if name=="batched" and sys.version_info[:2] == (3, 12):
769
- continue # version 3.12 does not support the strict parameter, so, we don't use the itertools method
764
+ case "permutations" | "combinations" | "combinations_with_replacement" | "product" | "batched" | "pairwise" | "zip_longest":
765
+ if name == "batched" and sys.version_info[:2] == (3, 12):
766
+ continue # version 3.12 does not support the strict parameter, so, we don't use the itertools method
770
767
  locals()[name] = functools.partialmethod(_itertools_join_method, name)
771
768
  case _:
772
769
  locals()[name] = functools.partialmethod(_itertools_method, name)
@@ -786,12 +783,12 @@ class istr(str):
786
783
  if iterable is None:
787
784
  return istr("").join(self)
788
785
  if not isinstance(self, str):
789
- raise TypeError(f"{self!r} should be str, not {type(self)}")
786
+ raise TypeError(f"{self!r} should be istr, str or iterable, not {type(self)}")
790
787
  return istr(self).join(iterable)
791
788
 
792
789
  @classmethod
793
790
  def concat(cls, iterable):
794
- return map(cls.join, cls(iterable))
791
+ return map(cls.join, cls(iterable))
795
792
 
796
793
  def prod(self, *, start=1):
797
794
  return math.prod(self, start=istr(start))
@@ -831,8 +828,7 @@ class istr(str):
831
828
 
832
829
  cls._int_format = int_format
833
830
 
834
- def __enter__(self):
835
- ...
831
+ def __enter__(self): ...
836
832
 
837
833
  def __exit__(self, exc_type, exc_value, exc_tb):
838
834
  self.saved_cls._int_format = self.saved_int_format
@@ -853,8 +849,7 @@ class istr(str):
853
849
  self.saved_cls = cls
854
850
  cls._repr_mode = mode
855
851
 
856
- def __enter__(self):
857
- ...
852
+ def __enter__(self): ...
858
853
 
859
854
  def __exit__(self, exc_type, exc_value, exc_tb):
860
855
  self.saved_cls._repr_mode = self.saved_repr_mode
@@ -873,15 +868,14 @@ class istr(str):
873
868
  self.saved_cls = cls
874
869
  cls._base = base
875
870
 
876
- def __enter__(self):
877
- ...
871
+ def __enter__(self): ...
878
872
 
879
873
  def __exit__(self, exc_type, exc_value, exc_tb):
880
874
  self.saved_cls._base = self.saved_base
881
875
 
882
876
  @classmethod
883
- def range(cls, start, stop=None, step=1, base=None, int_format=None, repr_mode=None):
884
- return _range(cls, start, stop, step, base=base, int_format=int_format, repr_mode=repr_mode)
877
+ def range(cls, start=None, stop=None, step=1, /, length=None, base=None, int_format=None, repr_mode=None):
878
+ return _range(cls, start, stop, step, length, base=base, int_format=int_format, repr_mode=repr_mode)
885
879
 
886
880
  @classmethod
887
881
  def digits(cls, *args):
@@ -991,7 +985,7 @@ def _map(func, *iterables, strict=False):
991
985
  _cache = {}
992
986
 
993
987
 
994
- def in_range(lst, lb, ub):
988
+ def in_range(lst, start, stop):
995
989
  """
996
990
  this function will give all values of lst in the range [lb, ub)
997
991
 
@@ -1000,28 +994,60 @@ def in_range(lst, lb, ub):
1000
994
  lst : list
1001
995
  must be sorted!
1002
996
 
1003
- lb : int (or istr)
997
+ start : int (or istr)
1004
998
  lowerbound
1005
999
 
1006
- ub : int (or istr)
1000
+ stop : int (or istr)
1007
1001
  non inclusive upperbound
1008
1002
 
1009
1003
  Returns
1010
1004
  -------
1011
- list of all items in [lb, ub)
1005
+ list of all items in [start, stop)
1012
1006
 
1013
1007
  Note
1014
1008
  ----
1015
1009
  Equivalent to
1016
- [item for item in lst if lb <= item < ub], but more efficient.
1010
+ [item for item in lst if start <= item < stop], but more efficient.
1017
1011
  """
1018
- lb = int(lb)
1019
- ub = int(ub)
1020
- left = bisect.bisect_left(lst, lb)
1021
- right = bisect.bisect_left(lst, ub)
1012
+ start = int(start)
1013
+ stop = int(stop)
1014
+ left = bisect.bisect_left(lst, start)
1015
+ right = bisect.bisect_left(lst, stop)
1022
1016
  return lst[left:right]
1023
1017
 
1024
1018
 
1019
+ def check_integer(value, value_description):
1020
+
1021
+ if not isinstance(value, numbers.Number):
1022
+ try:
1023
+ return int(value)
1024
+ except TypeError:
1025
+ raise ValueError(f"{value_description} should be an integer, not {value}")
1026
+
1027
+ if value != int(value):
1028
+ raise ValueError(f"{value_description} should be an integer, not {value}")
1029
+ return int(value)
1030
+
1031
+
1032
+ def process_start_stop_step_length(start, stop, step, length):
1033
+ if start is None and length is None:
1034
+ raise ValueError("no bound(s) or length specified")
1035
+ if length is not None:
1036
+ if start is not None:
1037
+ raise ValueError("both bound(s) and length specified")
1038
+ length = check_integer(length, "length")
1039
+ if length < 1:
1040
+ raise ValueError(f"length must be >=1, not {length}")
1041
+ start = 10 ** (length - 1)
1042
+ stop = start * 10
1043
+ else:
1044
+ start, stop = (0, start) if stop is None else (start, stop)
1045
+ start = check_integer(start, "start")
1046
+ stop = check_integer(stop, "upperbound")
1047
+ step = check_integer(step, "step")
1048
+ return start, stop, step
1049
+
1050
+
1025
1051
  def get_namespace(namespace):
1026
1052
  if namespace is None:
1027
1053
  frame = real_caller_frame()
@@ -1056,4 +1082,3 @@ class istrModule(types.ModuleType):
1056
1082
 
1057
1083
  if __name__ != "__main__":
1058
1084
  sys.modules["istr"].__class__ = istrModule
1059
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: istr-python
3
- Version: 1.1.32
3
+ Version: 1.1.33
4
4
  Summary: istr - strings you can count on
5
5
  Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/salabim/istr
@@ -367,7 +367,18 @@ to unpack multiple values, e.g.
367
367
  a, b, c = istr(5, 6, 7) ==> a=istr('5') , b=istr('6'), c=istr('7')
368
368
  a, b, c = istr(*range(3)) ==> a=istr('0') , b=istr('1'), c=istr('2')
369
369
  ```
370
+ #### Alternative way of range specification
371
+
372
+ Instead of `istr(range(..))` it is possible to use `istr,range(..)` instead, like
373
+
374
+ `list(istr.range(3,6))` ==> `[istr('3'), istr('4'), istr('5')]`
375
+
376
+ In contrast to the builtin `range`, `istr.range` supports a non keyword parameter `length`:
377
+
378
+ `list(istr.range(length=3))` is equivalent to `istr.range(100, 1000)`
379
+
370
380
  #### test for even/odd
381
+
371
382
  It is possible to test for even/odd (provided the istr can be interpreted as an int) with the `is_even` and `is_odd` method, e.g.
372
383
 
373
384
  ```
@@ -754,13 +765,17 @@ In contrast to `math.sumprod()`, `istr.sumprod()` supports a `strict` parameter
754
765
  Thus, `istr.sumprod("12", (3,4,5), strict=False)` is `istr(11)`, whereas `istr.sumprod("12", (3,4,5))`
755
766
  raises a ValueError.
756
767
 
757
- #### get all squares, cubes, power ofs or primes in a given range
768
+ #### get all squares, cubes, power ofs or primes in a given range or with a given length
758
769
 
759
770
  The class methods `istr.squares`, `istr.cubes`, `istr.power_ofs` and `istr.primes` can be used to get a list of all squares, cubes, power_ofs or primes up to a given upperbound (non inclusive) or between a given lower bound and upper bound (non inclusive), like:
760
771
 
761
772
  `istr.squares (100)` returns a list of all squares <100
762
773
  `istr.squares(50, 100)` returns a list of all squares in the range [50, 100)
763
774
 
775
+ Alternatively, it is possible to get a list of all squares, cubes, power_ofs or primes with a given length, like:
776
+
777
+ `istr.squares (length=2)` returns a list of all squares of length 2, so between 10 and 99.
778
+
764
779
  Unless `cache=False` is specified, the query result is cached.
765
780
 
766
781
  #### generate istr with digits
@@ -10,7 +10,7 @@ authors = [
10
10
  { name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com" },
11
11
  ]
12
12
  description = "istr - strings you can count on"
13
- version = "1.1.32"
13
+ version = "1.1.33"
14
14
  readme = "README.md"
15
15
  requires-python = ">=3.10"
16
16
  dependencies = []
@@ -190,6 +190,12 @@ def test_range():
190
190
 
191
191
  assert str(list(istr.range(5, base=2, repr_mode="str"))) == "['0', '1', '10', '11', '100']"
192
192
 
193
+ assert list(istr.range(length=2)) == list(istr.range(10, 100))
194
+ with pytest.raises(ValueError, match=re.escape("length must be >=1, not 0")):
195
+ istr.range(length=0)
196
+ with pytest.raises(ValueError, match=re.escape("both bound(s) and length specified")):
197
+ istr.range(10, length=2)
198
+
193
199
 
194
200
  def test_misc():
195
201
  assert istr("") == ""
@@ -468,7 +474,7 @@ def test_is_power_of():
468
474
  assert not istr.is_power_of(2, 3)
469
475
  assert istr.is_power_of(8, 3)
470
476
  assert istr.is_power_of(27, 3)
471
- with pytest.raises(TypeError):
477
+ with pytest.raises(ValueError):
472
478
  istr(1).is_power_of(3.1)
473
479
  with pytest.raises(ValueError):
474
480
  istr(1).is_power_of(-1)
@@ -502,18 +508,33 @@ def test_primes():
502
508
  assert istr.primes(17) == [istr("2"), istr("3"), istr("5"), istr("7"), istr("11"), istr("13")]
503
509
  assert istr.primes(40, 50) == [istr("41"), istr("43"), istr("47")]
504
510
  assert id(istr.primes(100)) == id(istr.primes(100)) # test caching
511
+ assert istr.primes(length=2) == istr.primes(10, 100)
512
+ with pytest.raises(ValueError, match=re.escape("both bound(s) and length specified")):
513
+ istr.primes(12, length=2)
514
+ with pytest.raises(ValueError, match=re.escape("no bound(s) or length specified")):
515
+ istr.primes()
505
516
 
506
517
 
507
518
  def test_squares():
508
519
  assert istr.squares(50) == [istr("0"), istr("1"), istr("4"), istr("9"), istr("16"), istr("25"), istr("36"), istr("49")]
509
- assert istr.squares(40, 50) == [istr("49")]
520
+ assert istr.squares(-27, 27) == [istr("0"), istr("1"), istr("4"), istr("9"), istr("16"), istr("25")]
510
521
  assert id(istr.squares(100)) == id(istr.squares(100)) # test caching
522
+ assert istr.squares(length=2) == istr.squares(10, 100)
523
+ with pytest.raises(ValueError, match=re.escape("both bound(s) and length specified")):
524
+ istr.squares(12, length=2)
525
+ with pytest.raises(ValueError, match=re.escape("no bound(s) or length specified")):
526
+ istr.squares()
511
527
 
512
528
 
513
529
  def test_cubes():
514
530
  assert istr.cubes(50) == [istr("0"), istr("1"), istr("8"), istr("27")]
515
- assert istr.cubes(27, 50) == [istr("27")]
531
+ assert istr.cubes(-27, 27) == [istr("-27"), istr("-8"), istr("-1"), istr("0"), istr("1"), istr("8")]
516
532
  assert id(istr.cubes(100)) == id(istr.cubes(100)) # test caching
533
+ assert istr.cubes(length=2) == istr.cubes(10, 100)
534
+ with pytest.raises(ValueError, match=re.escape("both bound(s) and length specified")):
535
+ istr.cubes(12, length=2)
536
+ with pytest.raises(ValueError, match=re.escape("no bound(s) or length specified")):
537
+ istr.cubes()
517
538
 
518
539
 
519
540
  def test_power_ofs():
@@ -881,15 +902,17 @@ def test_digits_cache():
881
902
  assert id(d) == id(istr.digits())
882
903
  assert int(d) == 4886718345
883
904
 
905
+
884
906
  def test_zip():
885
- assert list(istr.zip("12","34"))==[(istr("1"), istr("3")),(istr("2"), istr("4"))]
886
- assert list(istr.zip("12","345"))==[(istr("1"), istr("3")),(istr("2"), istr("4"))]
887
- assert list(istr.zip("12","34", join=True))==[istr("13"),istr("24")]
888
- assert list(istr.zip("12","345", join=True))==[istr("13"),istr("24")]
907
+ assert list(istr.zip("12", "34")) == [(istr("1"), istr("3")), (istr("2"), istr("4"))]
908
+ assert list(istr.zip("12", "345")) == [(istr("1"), istr("3")), (istr("2"), istr("4"))]
909
+ assert list(istr.zip("12", "34", join=True)) == [istr("13"), istr("24")]
910
+ assert list(istr.zip("12", "345", join=True)) == [istr("13"), istr("24")]
889
911
  with pytest.raises(ValueError):
890
- list(istr.zip("12","345",strict=True))
912
+ list(istr.zip("12", "345", strict=True))
891
913
  with pytest.raises(ValueError):
892
- list(istr.zip("12","345",join=True,strict=True))
914
+ list(istr.zip("12", "345", join=True, strict=True))
915
+
893
916
 
894
917
  def test_itertools():
895
918
  def list100(it):
@@ -899,9 +922,11 @@ def test_itertools():
899
922
  assert list(istr.accumulate((1, 3, 4))) == [istr("1"), istr("4"), istr("8")]
900
923
  assert list(istr.chain(range(2), range(2, 5))) == [istr("0"), istr("1"), istr("2"), istr("3"), istr("4")]
901
924
  assert list(istr.combinations(range(5), r=3)) == list(istr(itertools.combinations(range(5), r=3)))
902
- assert list(istr.combinations(range(5), r=3,join=True)) == list(map(istr.join,istr(itertools.combinations(range(5), r=3))) )
925
+ assert list(istr.combinations(range(5), r=3, join=True)) == list(map(istr.join, istr(itertools.combinations(range(5), r=3))))
903
926
  assert list(istr.combinations_with_replacement(range(5), r=3)) == list(istr(itertools.combinations_with_replacement(range(5), r=3)))
904
- assert list(istr.combinations_with_replacement(range(5), r=3,join=True)) == list(map(istr.join,istr(itertools.combinations_with_replacement(range(5), r=3))))
927
+ assert list(istr.combinations_with_replacement(range(5), r=3, join=True)) == list(
928
+ map(istr.join, istr(itertools.combinations_with_replacement(range(5), r=3)))
929
+ )
905
930
  assert list(istr.compress("123456", [1, 0, 1, 0, 1, 1])) == [istr("1"), istr("3"), istr("5"), istr("6")]
906
931
  assert list100(istr.count()) == list100(istr(itertools.count()))
907
932
  assert list100(istr.cycle(range(10))) == list100(istr(itertools.cycle(range(10))))
@@ -909,21 +934,22 @@ def test_itertools():
909
934
  assert list(istr.filterfalse(lambda x: x % 2, range(10))) == [istr("0"), istr("2"), istr("4"), istr("6"), istr("8")]
910
935
  assert list(istr.islice("123456", 2)) == [istr("1"), istr("2")]
911
936
  assert list(istr.permutations(range(5), 3)) == list(istr(itertools.permutations(range(5), 3)))
912
- assert list(istr.permutations(range(5), 3, join=True)) == list(map(istr.join,istr(itertools.permutations(range(5), 3))))
937
+ assert list(istr.permutations(range(5), 3, join=True)) == list(map(istr.join, istr(itertools.permutations(range(5), 3))))
913
938
  assert list(istr.product(range(5), range(4))) == list(istr(itertools.product(range(5), range(4))))
914
- assert list(istr.product(range(5), range(4),join=True)) == list(map(istr.join,istr(itertools.product(range(5), range(4)))) )
939
+ assert list(istr.product(range(5), range(4), join=True)) == list(map(istr.join, istr(itertools.product(range(5), range(4)))))
915
940
  assert list100(istr.repeat(10)) == list100(istr(itertools.repeat(10)))
916
941
  assert list(istr.starmap(pow, [(2, 5), (3, 2), (10, 3)])) == [istr("32"), istr("9"), istr("1000")]
917
942
  assert list(istr.takewhile(lambda x: x < 5, [1, 4, 6, 3, 8])) == [istr("1"), istr("4")]
918
943
  assert list(istr.zip_longest("123", "56", fillvalue="0")) == [(istr("1"), istr("5")), (istr("2"), istr("6")), (istr("3"), istr("0"))]
919
- assert list(istr.zip_longest("123", "56", fillvalue="0",join=True)) == [istr("15"),istr("26"), istr("30")]
944
+ assert list(istr.zip_longest("123", "56", fillvalue="0", join=True)) == [istr("15"), istr("26"), istr("30")]
920
945
  assert list(istr.pairwise("1234")) == [(istr("1"), istr("2")), (istr("2"), istr("3")), (istr("3"), istr("4"))]
921
- assert list(istr.pairwise("1234",join=True)) == [istr("12"), istr("23"), istr("34")]
946
+ assert list(istr.pairwise("1234", join=True)) == [istr("12"), istr("23"), istr("34")]
922
947
  assert list(istr.batched("12345", n=2)) == [(istr("1"), istr("2")), (istr("3"), istr("4")), (istr("5"),)]
923
- assert list(istr.batched("12345", n=2,join=True)) == [istr("12"), istr("34"), istr("5")]
924
- assert list(istr.batched("1234", n=2,strict=True)) == [(istr("1"), istr("2")), (istr("3"), istr("4"))]
948
+ assert list(istr.batched("12345", n=2, join=True)) == [istr("12"), istr("34"), istr("5")]
949
+ assert list(istr.batched("1234", n=2, strict=True)) == [(istr("1"), istr("2")), (istr("3"), istr("4"))]
925
950
  with pytest.raises(ValueError):
926
- list(istr.batched("12345", n=2,strict=True))
951
+ list(istr.batched("12345", n=2, strict=True))
952
+
927
953
 
928
954
  def test_all_distinct():
929
955
  assert istr("abcdef").all_distinct()
@@ -1033,7 +1059,7 @@ def test_tuple_join():
1033
1059
  assert istr.is_even(istr(1, 2))
1034
1060
  assert istr.is_divisible_by(istr(1, 2), 3)
1035
1061
  assert istr.is_triangular(istr(1, 0))
1036
- assert istr.is_consecutive(istr(1,2,3))
1062
+ assert istr.is_consecutive(istr(1, 2, 3))
1037
1063
  assert istr.is_increasing(istr(1, 2))
1038
1064
  assert istr.is_non_decreasing(istr(1, 2, 2, 3))
1039
1065
  assert istr.is_decreasing(istr(2, 1))
@@ -1047,7 +1073,7 @@ def test_tuple_join():
1047
1073
  assert not istr.is_even(istr(1, 3))
1048
1074
  assert not istr.is_divisible_by(istr(1, 2), 5)
1049
1075
  assert not istr.is_triangular(istr(1, 1))
1050
- assert not istr.is_consecutive(istr(1,2,4))
1076
+ assert not istr.is_consecutive(istr(1, 2, 4))
1051
1077
  assert not istr.is_increasing(istr(1, 1))
1052
1078
  assert not istr.is_non_decreasing(istr(1, 2, 2, 1))
1053
1079
  assert not istr.is_decreasing(istr(2, 2))
File without changes