phext 0.3.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.
- phext-0.3.0/.gitignore +4 -0
- phext-0.3.0/PKG-INFO +28 -0
- phext-0.3.0/README.md +5 -0
- phext-0.3.0/phext/__init__.py +1 -0
- phext-0.3.0/phext/coordinate.py +154 -0
- phext-0.3.0/phext/phext.py +546 -0
- phext-0.3.0/phext/positionedScroll.py +11 -0
- phext-0.3.0/phext/range.py +7 -0
- phext-0.3.0/pyproject.toml +33 -0
- phext-0.3.0/test/verify.py +8 -0
- phext-0.3.0/tests/test_coordinate.py +190 -0
- phext-0.3.0/tests/test_phext.py +920 -0
- phext-0.3.0/tests/test_positionedScroll.py +51 -0
- phext-0.3.0/tests/test_range.py +11 -0
phext-0.3.0/.gitignore
ADDED
phext-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phext
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Pythonic implementation of phext
|
|
5
|
+
Project-URL: Homepage, https://phext.io
|
|
6
|
+
Project-URL: Repository, https://github.com/wbic16/phext-py
|
|
7
|
+
Project-URL: Issues, https://github.com/wbic16/phext-py/issues
|
|
8
|
+
Author-email: Will Bickford <wbic16@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: xxhash
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
21
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Phext
|
|
25
|
+
|
|
26
|
+
Welcome to the Pythonic port of phext.
|
|
27
|
+
|
|
28
|
+
This port is a downstream artifact that tracks the Rust-based implementation of Phext. See https://github.com/wbic16/phext-rs for more details.
|
phext-0.3.0/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.0"
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from functools import total_ordering
|
|
3
|
+
|
|
4
|
+
@total_ordering
|
|
5
|
+
@dataclass
|
|
6
|
+
class Coordinate:
|
|
7
|
+
library: int
|
|
8
|
+
shelf: int
|
|
9
|
+
series: int
|
|
10
|
+
collection: int
|
|
11
|
+
volume: int
|
|
12
|
+
book: int
|
|
13
|
+
chapter: int
|
|
14
|
+
section: int
|
|
15
|
+
scroll: int
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def from_string(ignored, coord_str: str):
|
|
19
|
+
try:
|
|
20
|
+
parts = coord_str.strip().split("/")
|
|
21
|
+
if len(parts) != 3:
|
|
22
|
+
raise ValueError("Coordinate must conform to Phext Standard Addressing")
|
|
23
|
+
|
|
24
|
+
nums = []
|
|
25
|
+
for part in parts:
|
|
26
|
+
nums.extend(int(x) for x in part.split("."))
|
|
27
|
+
|
|
28
|
+
if len(nums) != 9:
|
|
29
|
+
raise ValueError("Coordinate must have exactly 9 numeric parts")
|
|
30
|
+
|
|
31
|
+
if any(n < 1 or n > 999 for n in nums):
|
|
32
|
+
raise ValueError("All coordinate values must be between 1 and 999")
|
|
33
|
+
|
|
34
|
+
return Coordinate(nums[0], nums[1], nums[2], nums[3], nums[4], nums[5], nums[6], nums[7], nums[8])
|
|
35
|
+
|
|
36
|
+
except Exception as e:
|
|
37
|
+
raise ValueError(f"Invalid coordinate string: {coord_str} {e}") from e
|
|
38
|
+
|
|
39
|
+
def libraryBreak(self):
|
|
40
|
+
self.library += 1
|
|
41
|
+
self.shelf = 1
|
|
42
|
+
self.series = 1
|
|
43
|
+
self.collection = 1
|
|
44
|
+
self.volume = 1
|
|
45
|
+
self.book = 1
|
|
46
|
+
self.chapter = 1
|
|
47
|
+
self.section = 1
|
|
48
|
+
self.scroll = 1
|
|
49
|
+
|
|
50
|
+
def shelfBreak(self):
|
|
51
|
+
self.shelf += 1
|
|
52
|
+
self.series = 1
|
|
53
|
+
self.collection = 1
|
|
54
|
+
self.volume = 1
|
|
55
|
+
self.book = 1
|
|
56
|
+
self.chapter = 1
|
|
57
|
+
self.section = 1
|
|
58
|
+
self.scroll = 1
|
|
59
|
+
|
|
60
|
+
def seriesBreak(self):
|
|
61
|
+
self.series += 1
|
|
62
|
+
self.collection = 1
|
|
63
|
+
self.volume = 1
|
|
64
|
+
self.book = 1
|
|
65
|
+
self.chapter = 1
|
|
66
|
+
self.section = 1
|
|
67
|
+
self.scroll = 1
|
|
68
|
+
|
|
69
|
+
def collectionBreak(self):
|
|
70
|
+
self.collection += 1
|
|
71
|
+
self.volume = 1
|
|
72
|
+
self.book = 1
|
|
73
|
+
self.chapter = 1
|
|
74
|
+
self.section = 1
|
|
75
|
+
self.scroll = 1
|
|
76
|
+
|
|
77
|
+
def volumeBreak(self):
|
|
78
|
+
self.volume += 1
|
|
79
|
+
self.book = 1
|
|
80
|
+
self.chapter = 1
|
|
81
|
+
self.section = 1
|
|
82
|
+
self.scroll = 1
|
|
83
|
+
|
|
84
|
+
def bookBreak(self):
|
|
85
|
+
self.book += 1
|
|
86
|
+
self.chapter = 1
|
|
87
|
+
self.section = 1
|
|
88
|
+
self.scroll = 1
|
|
89
|
+
|
|
90
|
+
def chapterBreak(self):
|
|
91
|
+
self.chapter += 1
|
|
92
|
+
self.section = 1
|
|
93
|
+
self.scroll = 1
|
|
94
|
+
|
|
95
|
+
def sectionBreak(self):
|
|
96
|
+
self.section += 1
|
|
97
|
+
self.scroll = 1
|
|
98
|
+
|
|
99
|
+
def scrollBreak(self):
|
|
100
|
+
self.scroll += 1
|
|
101
|
+
|
|
102
|
+
def __init__(self, lb, sf, sr, cn, vm, bk, ch, sn, sc):
|
|
103
|
+
self.library = int(lb)
|
|
104
|
+
self.shelf = int(sf)
|
|
105
|
+
self.series = int(sr)
|
|
106
|
+
self.collection = int(cn)
|
|
107
|
+
self.volume = int(vm)
|
|
108
|
+
self.book = int(bk)
|
|
109
|
+
self.chapter = int(ch)
|
|
110
|
+
self.section = int(sn)
|
|
111
|
+
self.scroll = int(sc)
|
|
112
|
+
|
|
113
|
+
def copy_coordinate(self, other):
|
|
114
|
+
self.library = int(other.library)
|
|
115
|
+
self.shelf = int(other.shelf)
|
|
116
|
+
self.series = int(other.series)
|
|
117
|
+
self.collection = int(other.collection)
|
|
118
|
+
self.volume = int(other.volume)
|
|
119
|
+
self.book = int(other.book)
|
|
120
|
+
self.chapter = int(other.chapter)
|
|
121
|
+
self.section = int(other.section)
|
|
122
|
+
self.scroll = int(other.scroll)
|
|
123
|
+
|
|
124
|
+
def __str__(self) -> str:
|
|
125
|
+
return f"{self.library}.{self.shelf}.{self.series}/" \
|
|
126
|
+
f"{self.collection}.{self.volume}.{self.book}/" \
|
|
127
|
+
f"{self.chapter}.{self.section}.{self.scroll}"
|
|
128
|
+
|
|
129
|
+
def urlencoded(self) -> str:
|
|
130
|
+
return f"{self.library}.{self.shelf}.{self.series};" \
|
|
131
|
+
f"{self.collection}.{self.volume}.{self.book};" \
|
|
132
|
+
f"{self.chapter}.{self.section}.{self.scroll}"
|
|
133
|
+
|
|
134
|
+
def __eq__(self, other):
|
|
135
|
+
return isinstance(self, Coordinate) and isinstance(other, Coordinate) and self.library == other.library and self.shelf == other.shelf and self.series == other.series and self.collection == other.collection and self.volume == other.volume and self.book == other.book and self.chapter == other.chapter and self.section == other.section and self.scroll == other.scroll
|
|
136
|
+
|
|
137
|
+
def __lt__(self, other):
|
|
138
|
+
if not isinstance(other, Coordinate):
|
|
139
|
+
return NotImplemented
|
|
140
|
+
return self.as_tuple() < other.as_tuple()
|
|
141
|
+
|
|
142
|
+
def as_tuple(self) -> tuple:
|
|
143
|
+
return (
|
|
144
|
+
self.library, self.shelf, self.series,
|
|
145
|
+
self.collection, self.volume, self.book,
|
|
146
|
+
self.chapter, self.section, self.scroll
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
def __hash__(self):
|
|
150
|
+
return hash((
|
|
151
|
+
self.library, self.shelf, self.series,
|
|
152
|
+
self.collection, self.volume, self.book,
|
|
153
|
+
self.chapter, self.section, self.scroll
|
|
154
|
+
))
|