istr-python 1.0.12.post0__tar.gz → 1.1.0__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.
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/PKG-INFO +4 -4
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/README.md +3 -3
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr/istr.py +33 -87
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr_python.egg-info/PKG-INFO +4 -4
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/pyproject.toml +1 -1
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/tests/test_istr.py +8 -10
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr/LICENSE.txt +0 -0
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr/__init__.py +0 -0
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr_python.egg-info/SOURCES.txt +0 -0
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr_python.egg-info/dependency_links.txt +0 -0
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/istr_python.egg-info/top_level.txt +0 -0
- {istr_python-1.0.12.post0 → istr_python-1.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
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
|
|
@@ -29,7 +29,7 @@ M O N E Y
|
|
|
29
29
|
can be nicely, albeit not very efficient, coded as:
|
|
30
30
|
```
|
|
31
31
|
import itertools
|
|
32
|
-
|
|
32
|
+
import istr
|
|
33
33
|
|
|
34
34
|
for s, e, n, d, m, o, r, y in istr(itertools.permutations(range(10), 8)):
|
|
35
35
|
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y)):
|
|
@@ -66,7 +66,7 @@ No dependencies!
|
|
|
66
66
|
Just start with
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
|
|
69
|
+
import istr
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
#### Use istr as int
|
|
@@ -558,7 +558,7 @@ When a class is derived from istr, all methods will return that newly derived cl
|
|
|
558
558
|
|
|
559
559
|
E.g.
|
|
560
560
|
```
|
|
561
|
-
class jstr(istr):
|
|
561
|
+
class jstr(istr.type):
|
|
562
562
|
...
|
|
563
563
|
|
|
564
564
|
print(repr(jstr(4) * jstr(5)))
|
|
@@ -16,7 +16,7 @@ M O N E Y
|
|
|
16
16
|
can be nicely, albeit not very efficient, coded as:
|
|
17
17
|
```
|
|
18
18
|
import itertools
|
|
19
|
-
|
|
19
|
+
import istr
|
|
20
20
|
|
|
21
21
|
for s, e, n, d, m, o, r, y in istr(itertools.permutations(range(10), 8)):
|
|
22
22
|
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y)):
|
|
@@ -53,7 +53,7 @@ No dependencies!
|
|
|
53
53
|
Just start with
|
|
54
54
|
|
|
55
55
|
```
|
|
56
|
-
|
|
56
|
+
import istr
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
#### Use istr as int
|
|
@@ -545,7 +545,7 @@ When a class is derived from istr, all methods will return that newly derived cl
|
|
|
545
545
|
|
|
546
546
|
E.g.
|
|
547
547
|
```
|
|
548
|
-
class jstr(istr):
|
|
548
|
+
class jstr(istr.type):
|
|
549
549
|
...
|
|
550
550
|
|
|
551
551
|
print(repr(jstr(4) * jstr(5)))
|
|
@@ -5,17 +5,19 @@
|
|
|
5
5
|
# |_||___/ \__||_|
|
|
6
6
|
# strings you can count on
|
|
7
7
|
|
|
8
|
-
__version__ = "1.0
|
|
8
|
+
__version__ = "1.1.0"
|
|
9
9
|
import functools
|
|
10
10
|
import math
|
|
11
11
|
import itertools
|
|
12
|
+
import types
|
|
13
|
+
import sys
|
|
12
14
|
|
|
13
15
|
"""
|
|
14
16
|
Note: the changelog is now in changelog.md
|
|
15
17
|
|
|
16
18
|
You can view the changelog on www.salabim.org/istr/changelog.html
|
|
17
19
|
|
|
18
|
-
The readme can be viewed on www.salabim.org/istr/
|
|
20
|
+
The readme can be viewed on www.salabim.org/istr/
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
23
|
_0_to_Z = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
@@ -346,9 +348,9 @@ class istr(str):
|
|
|
346
348
|
if isinstance(self, istr):
|
|
347
349
|
if not self.is_int():
|
|
348
350
|
raise TypeError(f"not interpretable as int: {self._frepr(self)}")
|
|
349
|
-
n=self._as_int
|
|
351
|
+
n = self._as_int
|
|
350
352
|
else:
|
|
351
|
-
n=int(self)
|
|
353
|
+
n = int(self)
|
|
352
354
|
|
|
353
355
|
return n % 2 == 0
|
|
354
356
|
|
|
@@ -356,9 +358,9 @@ class istr(str):
|
|
|
356
358
|
if isinstance(self, istr):
|
|
357
359
|
if not self.is_int():
|
|
358
360
|
raise TypeError(f"not interpretable as int: {self._frepr(self)}")
|
|
359
|
-
n=self._as_int
|
|
361
|
+
n = self._as_int
|
|
360
362
|
else:
|
|
361
|
-
n=int(self)
|
|
363
|
+
n = int(self)
|
|
362
364
|
|
|
363
365
|
return n % 2 == 1
|
|
364
366
|
|
|
@@ -366,9 +368,9 @@ class istr(str):
|
|
|
366
368
|
if isinstance(self, istr):
|
|
367
369
|
if not self.is_int():
|
|
368
370
|
raise TypeError(f"not interpretable as int: {self._frepr(self)}")
|
|
369
|
-
n=self._as_int
|
|
371
|
+
n = self._as_int
|
|
370
372
|
else:
|
|
371
|
-
n=int(self)
|
|
373
|
+
n = int(self)
|
|
372
374
|
|
|
373
375
|
return n >= 0 and self == math.isqrt(n) ** 2
|
|
374
376
|
|
|
@@ -376,9 +378,9 @@ class istr(str):
|
|
|
376
378
|
if isinstance(self, istr):
|
|
377
379
|
if not self.is_int():
|
|
378
380
|
raise TypeError(f"not interpretable as int: {self._frepr(self)}")
|
|
379
|
-
n=self._as_int
|
|
381
|
+
n = self._as_int
|
|
380
382
|
else:
|
|
381
|
-
n=int(self)
|
|
383
|
+
n = int(self)
|
|
382
384
|
|
|
383
385
|
if n < 2:
|
|
384
386
|
return False
|
|
@@ -386,7 +388,7 @@ class istr(str):
|
|
|
386
388
|
return True
|
|
387
389
|
if not n & 1:
|
|
388
390
|
return False
|
|
389
|
-
|
|
391
|
+
|
|
390
392
|
for x in range(3, int(n**0.5) + 1, 2):
|
|
391
393
|
if n % x == 0:
|
|
392
394
|
return False
|
|
@@ -429,9 +431,9 @@ class istr(str):
|
|
|
429
431
|
if isinstance(self, istr):
|
|
430
432
|
if not self.is_int():
|
|
431
433
|
raise TypeError(f"not interpretable as int: {self._frepr(self)}")
|
|
432
|
-
n=self._as_int
|
|
434
|
+
n = self._as_int
|
|
433
435
|
else:
|
|
434
|
-
n=int(self)
|
|
436
|
+
n = int(self)
|
|
435
437
|
return n % int(divisor) == 0
|
|
436
438
|
|
|
437
439
|
def _str_method(self, name, *args, **kwargs):
|
|
@@ -481,7 +483,8 @@ class istr(str):
|
|
|
481
483
|
|
|
482
484
|
cls._int_format = int_format
|
|
483
485
|
|
|
484
|
-
def __enter__(self):
|
|
486
|
+
def __enter__(self):
|
|
487
|
+
...
|
|
485
488
|
|
|
486
489
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
487
490
|
self.saved_cls._int_format = self.saved_int_format
|
|
@@ -500,7 +503,8 @@ class istr(str):
|
|
|
500
503
|
self.saved_cls = cls
|
|
501
504
|
cls._repr_mode = mode
|
|
502
505
|
|
|
503
|
-
def __enter__(self):
|
|
506
|
+
def __enter__(self):
|
|
507
|
+
...
|
|
504
508
|
|
|
505
509
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
506
510
|
self.saved_cls._repr_mode = self.saved_repr_mode
|
|
@@ -519,7 +523,8 @@ class istr(str):
|
|
|
519
523
|
self.saved_cls = cls
|
|
520
524
|
cls._base = base
|
|
521
525
|
|
|
522
|
-
def __enter__(self):
|
|
526
|
+
def __enter__(self):
|
|
527
|
+
...
|
|
523
528
|
|
|
524
529
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
525
530
|
self.saved_cls._base = self.saved_base
|
|
@@ -596,82 +601,23 @@ class istr(str):
|
|
|
596
601
|
result = istr("".join(result))
|
|
597
602
|
cls._digits_cache[key] = result
|
|
598
603
|
return result
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
# this function is only for AnacondaCode !!!
|
|
602
|
-
|
|
603
|
-
import importlib.abc
|
|
604
|
-
import sys
|
|
605
|
-
import types
|
|
606
|
-
import re
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
def load_module(module_name, source):
|
|
610
|
-
"""
|
|
611
|
-
load a module from memory
|
|
612
|
-
based on:
|
|
613
|
-
https://stackoverflow.com/questions/65009309/dynamically-import-module-from-memory-in-python-3-using-hooks
|
|
614
|
-
"""
|
|
615
|
-
|
|
616
|
-
class StringLoader(importlib.abc.Loader):
|
|
617
|
-
def __init__(self, modules):
|
|
618
|
-
self._modules = modules
|
|
619
|
-
|
|
620
|
-
def has_module(self, fullname):
|
|
621
|
-
return fullname in self._modules
|
|
622
|
-
|
|
623
|
-
def create_module(self, spec):
|
|
624
|
-
if self.has_module(spec.name):
|
|
625
|
-
module = types.ModuleType(spec.name)
|
|
626
|
-
exec(self._modules[spec.name], module.__dict__)
|
|
627
|
-
return module
|
|
628
|
-
|
|
629
|
-
def exec_module(self, module):
|
|
630
|
-
pass
|
|
631
|
-
|
|
632
|
-
class StringFinder(importlib.abc.MetaPathFinder):
|
|
633
|
-
def __init__(self, loader):
|
|
634
|
-
self._loader = loader
|
|
635
|
-
|
|
636
|
-
def find_spec(self, fullname, path, target=None):
|
|
637
|
-
if self._loader.has_module(fullname):
|
|
638
|
-
return importlib.machinery.ModuleSpec(fullname, self._loader)
|
|
639
|
-
|
|
640
|
-
if module_name in sys.modules: # remove from modules
|
|
641
|
-
del sys.modules[module_name]
|
|
642
|
-
|
|
643
|
-
for obj in sys.meta_path[:]: # remove from sys.meta_path
|
|
644
|
-
try:
|
|
645
|
-
if obj._loader.has_module(module_name):
|
|
646
|
-
sys.meta_path.remove(obj)
|
|
647
|
-
except:
|
|
648
|
-
...
|
|
649
|
-
|
|
650
|
-
sys.meta_path.append(StringFinder(StringLoader({module_name: source})))
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
regex = re.compile(r"(?i)#\s*module\s*=\s*(\w+)")
|
|
654
|
-
|
|
655
|
-
for column in zip(*range):
|
|
656
|
-
module_name = None
|
|
657
|
-
for line in column:
|
|
658
|
-
if line is not None:
|
|
659
|
-
if (match_object := re.match(regex, line)) is not None:
|
|
660
|
-
module_name = match_object.group(1)
|
|
661
|
-
break
|
|
662
|
-
|
|
663
|
-
source = "\n".join("" if line is None else str(line) for line in column)
|
|
664
|
-
if module_name:
|
|
665
|
-
load_module(module_name, source)
|
|
666
|
-
else:
|
|
667
|
-
exec(source, globals())
|
|
668
|
-
|
|
669
|
-
return globals().get("output")
|
|
604
|
+
|
|
605
|
+
istr.type=type(istr(0))
|
|
670
606
|
|
|
671
607
|
|
|
672
608
|
def main():
|
|
673
609
|
...
|
|
674
610
|
|
|
611
|
+
class istrModule(types.ModuleType):
|
|
612
|
+
def __call__(self, *args, **kwargs):
|
|
613
|
+
return istr.__call__(*args, **kwargs)
|
|
614
|
+
def __setattr__(self, item, value):
|
|
615
|
+
setattr(istr,item,value)
|
|
616
|
+
def __getattr__(self, item,):
|
|
617
|
+
return getattr(istr,item)
|
|
618
|
+
|
|
619
|
+
sys.modules[__name__].__class__ = istrModule
|
|
675
620
|
|
|
676
621
|
if __name__ == "__main__":
|
|
677
622
|
main()
|
|
623
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
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
|
|
@@ -29,7 +29,7 @@ M O N E Y
|
|
|
29
29
|
can be nicely, albeit not very efficient, coded as:
|
|
30
30
|
```
|
|
31
31
|
import itertools
|
|
32
|
-
|
|
32
|
+
import istr
|
|
33
33
|
|
|
34
34
|
for s, e, n, d, m, o, r, y in istr(itertools.permutations(range(10), 8)):
|
|
35
35
|
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y)):
|
|
@@ -66,7 +66,7 @@ No dependencies!
|
|
|
66
66
|
Just start with
|
|
67
67
|
|
|
68
68
|
```
|
|
69
|
-
|
|
69
|
+
import istr
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
#### Use istr as int
|
|
@@ -558,7 +558,7 @@ When a class is derived from istr, all methods will return that newly derived cl
|
|
|
558
558
|
|
|
559
559
|
E.g.
|
|
560
560
|
```
|
|
561
|
-
class jstr(istr):
|
|
561
|
+
class jstr(istr.type):
|
|
562
562
|
...
|
|
563
563
|
|
|
564
564
|
print(repr(jstr(4) * jstr(5)))
|
|
@@ -6,15 +6,13 @@ import re
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
8
|
if __name__ == "__main__": # to make the tests run without the pytest cli
|
|
9
|
-
file_folder =
|
|
10
|
-
top_folder = (file_folder / ".." / "istr").resolve()
|
|
11
|
-
sys.path.insert(0, str(top_folder))
|
|
9
|
+
file_folder = os.path.dirname(__file__)
|
|
12
10
|
os.chdir(file_folder)
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
sys.path.insert(0, file_folder + "/../istr")
|
|
12
|
+
|
|
15
13
|
import pytest
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
import istr
|
|
18
16
|
|
|
19
17
|
istr.equals = lambda self, other: type(self) == type(other) and (str(self) == str(other))
|
|
20
18
|
# this method tests whether self and other are exactly the same
|
|
@@ -360,17 +358,17 @@ def test_join():
|
|
|
360
358
|
s = istr("").join(("4", "5", "6"))
|
|
361
359
|
assert s == "456"
|
|
362
360
|
assert s == 456
|
|
363
|
-
assert type(s) == istr
|
|
361
|
+
assert type(s) == istr.type
|
|
364
362
|
|
|
365
363
|
s = istr("").join(istr(("4", "5", "6")))
|
|
366
364
|
assert s == "456"
|
|
367
365
|
assert s == 456
|
|
368
|
-
assert type(s) == istr
|
|
366
|
+
assert type(s) == istr.type
|
|
369
367
|
|
|
370
368
|
s = istr("").join(istr(("", "", "6")))
|
|
371
369
|
assert s == "6"
|
|
372
370
|
assert s == 6
|
|
373
|
-
assert type(s) == istr
|
|
371
|
+
assert type(s) == istr.type
|
|
374
372
|
|
|
375
373
|
|
|
376
374
|
def test_or():
|
|
@@ -679,7 +677,7 @@ def test_all_distinct():
|
|
|
679
677
|
|
|
680
678
|
|
|
681
679
|
def test_subclassing():
|
|
682
|
-
class jstr(istr): ...
|
|
680
|
+
class jstr(istr.type): ...
|
|
683
681
|
|
|
684
682
|
assert jstr(5).equals(jstr(5))
|
|
685
683
|
assert repr(jstr(*range(3))) == "(jstr('0'), jstr('1'), jstr('2'))"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|