polytope-databases 20170220.2__py3-none-any.whl
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.
- polytope_databases/__init__.py +249 -0
- polytope_databases/data/Full2d/zzdb.info +10 -0
- polytope_databases/data/Full2d/zzdb.v03 +0 -0
- polytope_databases/data/Full2d/zzdb.v04 +0 -0
- polytope_databases/data/Full2d/zzdb.v05 +1 -0
- polytope_databases/data/Full2d/zzdb.v06 +1 -0
- polytope_databases/data/Full3d/zzdb.info +22 -0
- polytope_databases/data/Full3d/zzdb.v04 +0 -0
- polytope_databases/data/Full3d/zzdb.v05 +0 -0
- polytope_databases/data/Full3d/zzdb.v06 +0 -0
- polytope_databases/data/Full3d/zzdb.v07 +0 -0
- polytope_databases/data/Full3d/zzdb.v08 +0 -0
- polytope_databases/data/Full3d/zzdb.v09 +0 -0
- polytope_databases/data/Full3d/zzdb.v10 +0 -0
- polytope_databases/data/Full3d/zzdb.v11 +1 -0
- polytope_databases/data/Full3d/zzdb.v12 +1 -0
- polytope_databases/data/Full3d/zzdb.v13 +1 -0
- polytope_databases/data/reflexive_polytopes_2d +80 -0
- polytope_databases/data/reflexive_polytopes_3d +37977 -0
- polytope_databases-20170220.2.dist-info/METADATA +111 -0
- polytope_databases-20170220.2.dist-info/RECORD +25 -0
- polytope_databases-20170220.2.dist-info/WHEEL +5 -0
- polytope_databases-20170220.2.dist-info/licenses/DATA_LICENSES.md +31 -0
- polytope_databases-20170220.2.dist-info/licenses/LICENSE +338 -0
- polytope_databases-20170220.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""Packaged SageMath databases of two- and three-dimensional polytopes.
|
|
2
|
+
|
|
3
|
+
The public helpers return :mod:`importlib.resources` ``Traversable`` objects or
|
|
4
|
+
context managers for real filesystem paths. The package performs no network
|
|
5
|
+
access and does not depend on SageMath.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import os
|
|
12
|
+
import operator
|
|
13
|
+
import shutil
|
|
14
|
+
from contextlib import contextmanager
|
|
15
|
+
from importlib import resources
|
|
16
|
+
from importlib.resources.abc import Traversable
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from tempfile import TemporaryDirectory
|
|
19
|
+
from typing import IO, Iterator, Mapping, Union
|
|
20
|
+
|
|
21
|
+
__version__ = "20170220.2"
|
|
22
|
+
|
|
23
|
+
DATA_FILES = (
|
|
24
|
+
"Full2d/zzdb.info",
|
|
25
|
+
"Full2d/zzdb.v03",
|
|
26
|
+
"Full2d/zzdb.v04",
|
|
27
|
+
"Full2d/zzdb.v05",
|
|
28
|
+
"Full2d/zzdb.v06",
|
|
29
|
+
"Full3d/zzdb.info",
|
|
30
|
+
"Full3d/zzdb.v04",
|
|
31
|
+
"Full3d/zzdb.v05",
|
|
32
|
+
"Full3d/zzdb.v06",
|
|
33
|
+
"Full3d/zzdb.v07",
|
|
34
|
+
"Full3d/zzdb.v08",
|
|
35
|
+
"Full3d/zzdb.v09",
|
|
36
|
+
"Full3d/zzdb.v10",
|
|
37
|
+
"Full3d/zzdb.v11",
|
|
38
|
+
"Full3d/zzdb.v12",
|
|
39
|
+
"Full3d/zzdb.v13",
|
|
40
|
+
"reflexive_polytopes_2d",
|
|
41
|
+
"reflexive_polytopes_3d",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
DATA_SHA256: Mapping[str, str] = {
|
|
45
|
+
"Full2d/zzdb.info": "719ff58ca68984379be5962772983de912a8d74037173ed5c965268c135adaac",
|
|
46
|
+
"Full2d/zzdb.v03": "dde5ff0e7fd5c109d0aca7c01d1e2660e5f31af1199e8584d37cf9b878354b2c",
|
|
47
|
+
"Full2d/zzdb.v04": "0e81c83a04f4eb45e4cc393b36923e55844ddc4d7a23c8e01fb0095d1b760371",
|
|
48
|
+
"Full2d/zzdb.v05": "b7f853e6fc6e10c3362a6e4c9eb63ddca72c1832481ce06bd6d4629bb58bcb35",
|
|
49
|
+
"Full2d/zzdb.v06": "1aef85f64ccf4318bc3f25c20a4f5f3f1c635bebc36772d89c95ac639340c575",
|
|
50
|
+
"Full3d/zzdb.info": "b76c164ca39e018c62a2387443ff7940edba86615c13409c92e82094cf12e241",
|
|
51
|
+
"Full3d/zzdb.v04": "15545d51cc41c1dc70e543e5471cb14eff480da792a520c9d6041efef699a591",
|
|
52
|
+
"Full3d/zzdb.v05": "a787c47c6db5077bf54110957bc1ceb9538170aa0cd1e50c399814ea86e61c5b",
|
|
53
|
+
"Full3d/zzdb.v06": "1f86ff7cb8478fdf768547f848179da4f73587d5bd77672498a241596a42abe9",
|
|
54
|
+
"Full3d/zzdb.v07": "5aa55925b1eb46309bb7c70ce8dd2da3c2ae137390375ba79eac003c4ca65dc9",
|
|
55
|
+
"Full3d/zzdb.v08": "97ff70bff251043cea9978112de9c604ed6a5624438c3ee47876fd2aab601a78",
|
|
56
|
+
"Full3d/zzdb.v09": "d770b9ee7b1be356c451e9e6d77249d9afd59329b52ff34d4dd1e0cff58d6995",
|
|
57
|
+
"Full3d/zzdb.v10": "44d193a4765baa0fe442301a5e1b65f909d76d2c6980b9f140214909a4cc734c",
|
|
58
|
+
"Full3d/zzdb.v11": "696051521ff2a732d3c0e401b77922362eef5475158c84c1bb31a7533fdecd7c",
|
|
59
|
+
"Full3d/zzdb.v12": "92a9a3bcbf31f415bd45b3e1ee5516e0e318d5d63d0538b83d1712f5889e410c",
|
|
60
|
+
"Full3d/zzdb.v13": "f36361bf277890f4c84559520e36022449c53280d363edd883cd4fabe0d71577",
|
|
61
|
+
"reflexive_polytopes_2d": "f0e47311eb365f700e2a03a6b061fee85d44f1d3937acff32876723f47ebedb4",
|
|
62
|
+
"reflexive_polytopes_3d": "1d590ab17bb166084d87467123c7c9ff189dd15b42e4bf4d5df6790ffd10fed3",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def data_root() -> Traversable:
|
|
67
|
+
"""Return the root of the packaged data as a Traversable resource."""
|
|
68
|
+
|
|
69
|
+
return resources.files(__package__).joinpath("data")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _resource_parts(parts: tuple[Union[str, os.PathLike[str]], ...]) -> tuple[str, ...]:
|
|
73
|
+
if not parts:
|
|
74
|
+
raise ValueError("at least one relative resource name is required")
|
|
75
|
+
result = []
|
|
76
|
+
for value in parts:
|
|
77
|
+
part = os.fspath(value)
|
|
78
|
+
if (
|
|
79
|
+
not part
|
|
80
|
+
or part in {".", ".."}
|
|
81
|
+
or os.path.isabs(part)
|
|
82
|
+
or "/" in part
|
|
83
|
+
or "\\" in part
|
|
84
|
+
):
|
|
85
|
+
raise ValueError(f"invalid resource path component: {part!r}")
|
|
86
|
+
result.append(part)
|
|
87
|
+
return tuple(result)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def resource(*parts: Union[str, os.PathLike[str]]) -> Traversable:
|
|
91
|
+
"""Return one packaged resource.
|
|
92
|
+
|
|
93
|
+
Each argument must be one relative path component. For example,
|
|
94
|
+
``resource("Full3d", "zzdb.info")`` returns the PALP metadata file.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
target = data_root().joinpath(*_resource_parts(parts))
|
|
98
|
+
if not (target.is_file() or target.is_dir()):
|
|
99
|
+
raise FileNotFoundError("/".join(os.fspath(part) for part in parts))
|
|
100
|
+
return target
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def open_resource(
|
|
104
|
+
*parts: Union[str, os.PathLike[str]],
|
|
105
|
+
mode: str = "rb",
|
|
106
|
+
encoding: str | None = None,
|
|
107
|
+
errors: str | None = None,
|
|
108
|
+
newline: str | None = None,
|
|
109
|
+
) -> IO:
|
|
110
|
+
"""Open a packaged resource for reading.
|
|
111
|
+
|
|
112
|
+
Text mode defaults to UTF-8. Write and update modes are rejected because
|
|
113
|
+
installed package resources are immutable.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
if any(flag in mode for flag in "wax+") or "r" not in mode:
|
|
117
|
+
raise ValueError("package resources can only be opened for reading")
|
|
118
|
+
target = resource(*parts)
|
|
119
|
+
if not target.is_file():
|
|
120
|
+
raise IsADirectoryError("/".join(os.fspath(part) for part in parts))
|
|
121
|
+
if "b" in mode:
|
|
122
|
+
if any(value is not None for value in (encoding, errors, newline)):
|
|
123
|
+
raise ValueError("encoding, errors, and newline require text mode")
|
|
124
|
+
return target.open(mode)
|
|
125
|
+
return target.open(
|
|
126
|
+
mode,
|
|
127
|
+
encoding=encoding or "utf-8",
|
|
128
|
+
errors=errors,
|
|
129
|
+
newline=newline,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _copy_directory(source: Traversable, destination: Path) -> None:
|
|
134
|
+
destination.mkdir()
|
|
135
|
+
for child in source.iterdir():
|
|
136
|
+
output = destination / child.name
|
|
137
|
+
if child.is_dir():
|
|
138
|
+
_copy_directory(child, output)
|
|
139
|
+
elif child.is_file():
|
|
140
|
+
with child.open("rb") as input_stream, output.open("wb") as output_stream:
|
|
141
|
+
shutil.copyfileobj(input_stream, output_stream)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@contextmanager
|
|
145
|
+
def resource_path(*parts: Union[str, os.PathLike[str]]) -> Iterator[Path]:
|
|
146
|
+
"""Yield a real filesystem path for a packaged file or directory.
|
|
147
|
+
|
|
148
|
+
Keep the context open while using the path. A temporary copy is created
|
|
149
|
+
when an import loader does not expose resources directly on the filesystem.
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
target = resource(*parts)
|
|
153
|
+
if isinstance(target, Path):
|
|
154
|
+
yield target
|
|
155
|
+
return
|
|
156
|
+
if target.is_file():
|
|
157
|
+
with resources.as_file(target) as path:
|
|
158
|
+
yield path
|
|
159
|
+
return
|
|
160
|
+
with TemporaryDirectory(prefix="polytope-databases-") as temporary:
|
|
161
|
+
path = Path(temporary) / target.name
|
|
162
|
+
_copy_directory(target, path)
|
|
163
|
+
yield path
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _dimension(value: object) -> int:
|
|
167
|
+
if isinstance(value, bool):
|
|
168
|
+
raise ValueError("dimension must be 2 or 3")
|
|
169
|
+
try:
|
|
170
|
+
dimension = operator.index(value) # type: ignore[arg-type]
|
|
171
|
+
except TypeError as error:
|
|
172
|
+
raise ValueError("dimension must be 2 or 3") from error
|
|
173
|
+
if dimension not in (2, 3):
|
|
174
|
+
raise ValueError("dimension must be 2 or 3")
|
|
175
|
+
return dimension
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def reflexive_polytopes(dim: object) -> Traversable:
|
|
179
|
+
"""Return the plain-text reflexive-polytope catalogue for dimension 2 or 3."""
|
|
180
|
+
|
|
181
|
+
return resource(f"reflexive_polytopes_{_dimension(dim)}d")
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def open_reflexive_polytopes(dim: object, *, encoding: str = "ascii") -> IO:
|
|
185
|
+
"""Open a reflexive-polytope catalogue as a text stream."""
|
|
186
|
+
|
|
187
|
+
return open_resource(
|
|
188
|
+
f"reflexive_polytopes_{_dimension(dim)}d", mode="r", encoding=encoding
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@contextmanager
|
|
193
|
+
def reflexive_polytopes_path(dim: object) -> Iterator[Path]:
|
|
194
|
+
"""Yield a real filesystem path to a plain-text polytope catalogue."""
|
|
195
|
+
|
|
196
|
+
with resource_path(f"reflexive_polytopes_{_dimension(dim)}d") as path:
|
|
197
|
+
yield path
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def palp_database(dim: object) -> Traversable:
|
|
201
|
+
"""Return the PALP database directory for dimension 2 or 3."""
|
|
202
|
+
|
|
203
|
+
return resource(f"Full{_dimension(dim)}d")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@contextmanager
|
|
207
|
+
def palp_database_path(dim: object) -> Iterator[Path]:
|
|
208
|
+
"""Yield a real filesystem path to a PALP database directory."""
|
|
209
|
+
|
|
210
|
+
with resource_path(f"Full{_dimension(dim)}d") as path:
|
|
211
|
+
yield path
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def verify_data() -> None:
|
|
215
|
+
"""Raise an exception unless all packaged data matches the release manifest."""
|
|
216
|
+
|
|
217
|
+
actual_files = []
|
|
218
|
+
for directory in ("Full2d", "Full3d"):
|
|
219
|
+
actual_files.extend(
|
|
220
|
+
f"{directory}/{item.name}"
|
|
221
|
+
for item in resource(directory).iterdir()
|
|
222
|
+
if item.is_file()
|
|
223
|
+
)
|
|
224
|
+
actual_files.extend(
|
|
225
|
+
name for name in ("reflexive_polytopes_2d", "reflexive_polytopes_3d")
|
|
226
|
+
if resource(name).is_file()
|
|
227
|
+
)
|
|
228
|
+
if tuple(sorted(actual_files)) != tuple(sorted(DATA_FILES)):
|
|
229
|
+
raise RuntimeError("packaged data file manifest does not match DATA_FILES")
|
|
230
|
+
for name, expected in DATA_SHA256.items():
|
|
231
|
+
digest = hashlib.sha256(resource(*name.split("/")).read_bytes()).hexdigest()
|
|
232
|
+
if digest != expected:
|
|
233
|
+
raise RuntimeError(f"checksum mismatch for {name}: {digest}")
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
__all__ = [
|
|
237
|
+
"DATA_FILES",
|
|
238
|
+
"DATA_SHA256",
|
|
239
|
+
"data_root",
|
|
240
|
+
"open_reflexive_polytopes",
|
|
241
|
+
"open_resource",
|
|
242
|
+
"palp_database",
|
|
243
|
+
"palp_database_path",
|
|
244
|
+
"reflexive_polytopes",
|
|
245
|
+
"reflexive_polytopes_path",
|
|
246
|
+
"resource",
|
|
247
|
+
"resource_path",
|
|
248
|
+
"verify_data",
|
|
249
|
+
]
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
\Na
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
3 10 13 10 43 2199 79 0 11549 0 0 0 0
|
|
2
|
+
|
|
3
|
+
4 4
|
|
4
|
+
2 8 3 5 4 11 5 3
|
|
5
|
+
5 5
|
|
6
|
+
2 1 3 82 4 43 5 34 6 2
|
|
7
|
+
6 6
|
|
8
|
+
3 45 4 149 5 142 6 45 7 3 8 1
|
|
9
|
+
7 6
|
|
10
|
+
3 14 4 129 5 310 6 85 7 22 8 5
|
|
11
|
+
8 5
|
|
12
|
+
4 34 5 163 6 269 7 48 8 18
|
|
13
|
+
9 5
|
|
14
|
+
5 48 6 215 7 63 8 26 9 1
|
|
15
|
+
10 6
|
|
16
|
+
5 50 6 58 7 4 8 13 9 7 10 1
|
|
17
|
+
11 3
|
|
18
|
+
6 22 7 12 8 1
|
|
19
|
+
12 2
|
|
20
|
+
6 4 7 1
|
|
21
|
+
13 1
|
|
22
|
+
7 2
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�aq����Ǝ�!���b������"\o�Q��ǐ�Ŀ��B�4�1���[����*��-�����ψ��e5��y��o�n6[�n,�.o��K����^}�|�에3=s�M�|e(��*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
O/�6�1���|%P��j{ywx`����Swx(}�
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
�D���8lP�e�
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
3 2
|
|
2
|
+
1 0
|
|
3
|
+
0 1
|
|
4
|
+
-1 -1
|
|
5
|
+
3 2
|
|
6
|
+
1 0
|
|
7
|
+
0 1
|
|
8
|
+
-2 -1
|
|
9
|
+
4 2
|
|
10
|
+
1 0
|
|
11
|
+
-1 0
|
|
12
|
+
0 1
|
|
13
|
+
1 -1
|
|
14
|
+
4 2
|
|
15
|
+
1 0
|
|
16
|
+
0 1
|
|
17
|
+
0 -1
|
|
18
|
+
-1 0
|
|
19
|
+
4 2
|
|
20
|
+
1 0
|
|
21
|
+
0 1
|
|
22
|
+
-1 -1
|
|
23
|
+
-1 1
|
|
24
|
+
5 2
|
|
25
|
+
1 0
|
|
26
|
+
0 1
|
|
27
|
+
0 -1
|
|
28
|
+
-1 0
|
|
29
|
+
1 1
|
|
30
|
+
3 2
|
|
31
|
+
1 0
|
|
32
|
+
0 1
|
|
33
|
+
-3 -2
|
|
34
|
+
4 2
|
|
35
|
+
1 0
|
|
36
|
+
0 1
|
|
37
|
+
0 -1
|
|
38
|
+
-2 1
|
|
39
|
+
5 2
|
|
40
|
+
1 0
|
|
41
|
+
0 1
|
|
42
|
+
0 -1
|
|
43
|
+
-1 1
|
|
44
|
+
-1 -1
|
|
45
|
+
6 2
|
|
46
|
+
1 0
|
|
47
|
+
0 1
|
|
48
|
+
1 -1
|
|
49
|
+
-1 1
|
|
50
|
+
0 -1
|
|
51
|
+
-1 0
|
|
52
|
+
4 2
|
|
53
|
+
1 0
|
|
54
|
+
0 1
|
|
55
|
+
-1 1
|
|
56
|
+
-1 -2
|
|
57
|
+
5 2
|
|
58
|
+
1 0
|
|
59
|
+
0 1
|
|
60
|
+
-1 1
|
|
61
|
+
1 -1
|
|
62
|
+
-1 -1
|
|
63
|
+
3 2
|
|
64
|
+
1 0
|
|
65
|
+
1 2
|
|
66
|
+
-3 -2
|
|
67
|
+
4 2
|
|
68
|
+
1 0
|
|
69
|
+
0 1
|
|
70
|
+
-2 1
|
|
71
|
+
1 -2
|
|
72
|
+
4 2
|
|
73
|
+
1 0
|
|
74
|
+
1 2
|
|
75
|
+
-1 -2
|
|
76
|
+
-1 0
|
|
77
|
+
3 2
|
|
78
|
+
1 0
|
|
79
|
+
1 3
|
|
80
|
+
-2 -3
|