partis-pyproj 0.1.8__py3-none-any.whl → 0.2.0__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.
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/backend.py +2 -2
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/builder.py +19 -1
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/download.py +31 -6
- partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_copy.py +187 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/norms.py +5 -3
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pep.py +78 -36
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pkginfo.py +2 -1
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pptoml.py +47 -2
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pyproj.py +3 -3
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/validate.py +49 -31
- {partis_pyproj-0.1.8.dist-info → partis_pyproj-0.2.0.dist-info}/METADATA +17 -11
- partis_pyproj-0.2.0.dist-info/RECORD +38 -0
- partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_copy.py +0 -138
- partis_pyproj-0.1.8.dist-info/RECORD +0 -38
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/__init__.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/_legacy_setup.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/_nonprintable.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/__init__.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/cargo.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/cmake.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/meson.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/process.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/__init__.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_base.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_binary.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_source.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_targz.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_zip.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/file.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/legacy.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/load_module.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/__init__.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/match.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/pattern.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/utils.py +0 -0
- {partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/template.py +0 -0
- {partis_pyproj-0.1.8.dist-info → partis_pyproj-0.2.0.dist-info}/LICENSE.txt +0 -0
- {partis_pyproj-0.1.8.dist-info → partis_pyproj-0.2.0.dist-info}/WHEEL +0 -0
- {partis_pyproj-0.1.8.dist-info → partis_pyproj-0.2.0.dist-info}/entry_points.txt +0 -0
- {partis_pyproj-0.1.8.dist-info → partis_pyproj-0.2.0.dist-info}/top_level.txt +0 -0
@@ -53,7 +53,7 @@ def backend_init(
|
|
53
53
|
|
54
54
|
if not root_logger.handlers:
|
55
55
|
basicConfig(
|
56
|
-
level =
|
56
|
+
level = os.environ.get('PARTIS_PYPROJ_LOGLEVEL', 'INFO').upper(),
|
57
57
|
format = "{message}",
|
58
58
|
style = "{" )
|
59
59
|
|
@@ -232,7 +232,7 @@ def build_wheel(
|
|
232
232
|
|
233
233
|
except ValidationError as e:
|
234
234
|
known_exception_type = copy(e)
|
235
|
-
raise known_exception_type from
|
235
|
+
raise known_exception_type from e.__cause__
|
236
236
|
|
237
237
|
return dist.outname
|
238
238
|
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/builder.py
RENAMED
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
import os
|
3
3
|
import os.path as osp
|
4
|
+
import sys
|
4
5
|
import tempfile
|
5
6
|
import sysconfig
|
6
7
|
import re
|
@@ -30,6 +31,23 @@ from ..pptoml import pyproj_targets
|
|
30
31
|
|
31
32
|
ERROR_REC = re.compile(r"error:", re.I)
|
32
33
|
|
34
|
+
pyexe = sys.executable
|
35
|
+
|
36
|
+
try:
|
37
|
+
pyexe = osp.realpath(pyexe)
|
38
|
+
except Exception:
|
39
|
+
...
|
40
|
+
|
41
|
+
# fallback for commonly needed config. variables, but sometimes are not set
|
42
|
+
_sysconfig_vars_alt = {
|
43
|
+
'LIBDEST': sysconfig.get_path('stdlib'),
|
44
|
+
'BINLIBDEST': sysconfig.get_path('platstdlib'),
|
45
|
+
'INCLUDEPY': sysconfig.get_path('include'),
|
46
|
+
'EXENAME': pyexe,
|
47
|
+
'BINDIR': osp.dirname(pyexe)}
|
48
|
+
|
49
|
+
_sysconfig_vars = _sysconfig_vars_alt|sysconfig.get_config_vars()
|
50
|
+
|
33
51
|
#===============================================================================
|
34
52
|
class BuildCommandError(ValidationError):
|
35
53
|
pass
|
@@ -71,7 +89,7 @@ class Builder:
|
|
71
89
|
'targets': targets,
|
72
90
|
'env': os.environ,
|
73
91
|
'tmpdir': self.tmpdir,
|
74
|
-
'config_vars':
|
92
|
+
'config_vars': _sysconfig_vars},
|
75
93
|
root=root,
|
76
94
|
# better way for builders to whitelist templated directories?
|
77
95
|
dirs=[self.tmpdir, Path(tempfile.gettempdir())/'partis-pyproj-downloads'])
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/download.py
RENAMED
@@ -20,6 +20,18 @@ from ..norms import b64_nopad, nonempty_str
|
|
20
20
|
# replace runs of non-alphanumeric, dot, dash, or underscore
|
21
21
|
_filename_subs = re.compile(r'[^a-z0-9\.\-\_]+', re.I)
|
22
22
|
|
23
|
+
try:
|
24
|
+
# prefer user home directory to avoid clashing in global "tmp" directory
|
25
|
+
CACHE_DIR = Path.home()/'.cache'/'partis-pyproj'
|
26
|
+
|
27
|
+
except RuntimeError:
|
28
|
+
# use global temporary directory, suffixed by username to try to avoid conficts
|
29
|
+
# between users
|
30
|
+
import getpass
|
31
|
+
username = getpass.getuser()
|
32
|
+
tmp_dir = tempfile.gettempdir()
|
33
|
+
CACHE_DIR = Path(tmp_dir)/f'.cache-partis-pyproj-{username}'
|
34
|
+
|
23
35
|
#===============================================================================
|
24
36
|
def download(
|
25
37
|
pyproj,
|
@@ -94,7 +106,12 @@ def download(
|
|
94
106
|
try:
|
95
107
|
logger.info(f"- downloading: {url} -> {tmp_file}")
|
96
108
|
|
97
|
-
|
109
|
+
req = requests.get(url, stream=True)
|
110
|
+
|
111
|
+
if not req.ok:
|
112
|
+
req.raise_for_status()
|
113
|
+
|
114
|
+
with req, tmp_file.open('wb') as fp:
|
98
115
|
for chunk in req.iter_content(chunk_size=chunk_size):
|
99
116
|
if chunk:
|
100
117
|
fp.write(chunk)
|
@@ -107,6 +124,9 @@ def download(
|
|
107
124
|
logger.info(f"- {size/1e6:,.1f} MB")
|
108
125
|
last_size = size
|
109
126
|
|
127
|
+
if size == 0:
|
128
|
+
raise ValidationError(f"Downloaded file had zero size: {url}")
|
129
|
+
|
110
130
|
logger.info(f"- complete {size/1e6:,.1f} MB")
|
111
131
|
|
112
132
|
if hash:
|
@@ -137,18 +157,24 @@ def download(
|
|
137
157
|
out_file.symlink_to(cache_file)
|
138
158
|
|
139
159
|
if extract:
|
140
|
-
|
160
|
+
out_dir = build_dir
|
161
|
+
|
162
|
+
if isinstance(extract, (str,Path)):
|
163
|
+
out_dir = extract
|
164
|
+
|
165
|
+
logger.info(f"- extracting: {cache_file} -> {out_dir}")
|
166
|
+
|
141
167
|
with tarfile.open(cache_file, 'r:*') as fp:
|
142
168
|
if sys.version_info >= (3, 12):
|
143
169
|
# 'filter' argument added, controls behavior of extract
|
144
170
|
fp.extractall(
|
145
|
-
path=
|
171
|
+
path=out_dir,
|
146
172
|
members=None,
|
147
173
|
numeric_owner=False,
|
148
174
|
filter='tar')
|
149
175
|
else:
|
150
176
|
fp.extractall(
|
151
|
-
path=
|
177
|
+
path=out_dir,
|
152
178
|
members=None,
|
153
179
|
numeric_owner=False)
|
154
180
|
|
@@ -161,7 +187,6 @@ def _cached_download(url: str, checksum: str) -> Path:
|
|
161
187
|
if not checksum:
|
162
188
|
checksum = '0'
|
163
189
|
|
164
|
-
cache_dir = Path(tempfile.gettempdir())/'partis-pyproj-downloads'
|
165
190
|
name = url.split('/')[-1]
|
166
191
|
_url = url
|
167
192
|
|
@@ -178,7 +203,7 @@ def _cached_download(url: str, checksum: str) -> Path:
|
|
178
203
|
url_dirname = _filename_subs.sub('_', _url)
|
179
204
|
url_filename = f"{short}-" + _filename_subs.sub('_', name)
|
180
205
|
|
181
|
-
url_dir =
|
206
|
+
url_dir = CACHE_DIR/url_dirname
|
182
207
|
url_dir.mkdir(exist_ok=True, parents=True)
|
183
208
|
|
184
209
|
file = url_dir/url_filename
|
@@ -0,0 +1,187 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import os
|
3
|
+
import glob
|
4
|
+
from pathlib import (
|
5
|
+
Path)
|
6
|
+
import logging
|
7
|
+
from ..validate import (
|
8
|
+
FileOutsideRootError,
|
9
|
+
ValidationError,
|
10
|
+
validating )
|
11
|
+
from ..path import (
|
12
|
+
PathFilter,
|
13
|
+
subdir,
|
14
|
+
combine_ignore_patterns,
|
15
|
+
resolve)
|
16
|
+
from ..pptoml import (
|
17
|
+
pyproj_dist_copy)
|
18
|
+
|
19
|
+
#===============================================================================
|
20
|
+
def _rglob(pattern: str, *, root_dir: Path) -> list[Path]:
|
21
|
+
# detect if glob will be recursive by finding '**' in the pattern
|
22
|
+
recursive = '**' in pattern
|
23
|
+
|
24
|
+
# NOTE: root_dir added in Python 3.10
|
25
|
+
cwd = Path.cwd()
|
26
|
+
|
27
|
+
try:
|
28
|
+
os.chdir(root_dir)
|
29
|
+
matches = glob.glob(pattern, recursive = recursive)
|
30
|
+
|
31
|
+
matches = [Path(m) for m in matches]
|
32
|
+
|
33
|
+
if recursive:
|
34
|
+
# don't match directories in recursive mode, since copying a parent
|
35
|
+
# directory negates the need to recurse
|
36
|
+
matches = [m for m in matches if not m.is_dir()]
|
37
|
+
|
38
|
+
finally:
|
39
|
+
os.chdir(cwd)
|
40
|
+
|
41
|
+
return matches
|
42
|
+
|
43
|
+
#===============================================================================
|
44
|
+
def dist_iter(*,
|
45
|
+
copy_items: list[pyproj_dist_copy],
|
46
|
+
ignore: list[str],
|
47
|
+
root: Path,
|
48
|
+
logger: logging.Logger):
|
49
|
+
|
50
|
+
patterns = PathFilter(
|
51
|
+
patterns = ignore )
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
for i, incl in enumerate(copy_items):
|
56
|
+
src = incl.src
|
57
|
+
dst = incl.dst
|
58
|
+
_ignore = incl.ignore
|
59
|
+
|
60
|
+
_ignore_patterns = combine_ignore_patterns(
|
61
|
+
patterns,
|
62
|
+
PathFilter(
|
63
|
+
patterns = _ignore,
|
64
|
+
start = src ) )
|
65
|
+
|
66
|
+
if not incl.include:
|
67
|
+
# each copy specifies a single path
|
68
|
+
# logger.debug(f" - from: {src}\n - to: {dst}")
|
69
|
+
yield ( i, src, dst, _ignore_patterns, True )
|
70
|
+
|
71
|
+
else:
|
72
|
+
# each copy can result in many paths
|
73
|
+
for incl_pattern in incl.include:
|
74
|
+
# produce list of possible copies by glob pattern, relative to 'src'
|
75
|
+
matches = _rglob(incl_pattern.glob, root_dir=src)
|
76
|
+
# logger.debug(f"- glob: {len(matches)} matches with pattern {incl_pattern.glob!r} in {str(src)!r}")
|
77
|
+
|
78
|
+
if not matches:
|
79
|
+
logger.warning(f"Copy pattern did not yield any files: {incl_pattern.glob!r}")
|
80
|
+
continue
|
81
|
+
|
82
|
+
for i, match in enumerate(matches):
|
83
|
+
parent = match.parent
|
84
|
+
src_filename = match.name
|
85
|
+
|
86
|
+
if _ignore_patterns(src/parent, [src_filename]):
|
87
|
+
# Only filter by ignore pattern if this path was part of a glob
|
88
|
+
# logger.debug(f" - ignored: {match}")
|
89
|
+
continue
|
90
|
+
|
91
|
+
# logger.debug(f" - match: {match}")
|
92
|
+
|
93
|
+
if incl_pattern.strip:
|
94
|
+
# remove leading path components
|
95
|
+
dst_parent = type(parent)(*parent.parts[incl_pattern.strip:])
|
96
|
+
# logger.debug(f" - stripped: {parent.parts[:incl_pattern.strip]}")
|
97
|
+
else:
|
98
|
+
dst_parent = parent
|
99
|
+
|
100
|
+
# match to regular expression
|
101
|
+
m = incl_pattern.rematch.fullmatch(src_filename)
|
102
|
+
|
103
|
+
if not m:
|
104
|
+
# logger.debug(f" - !rematch: {src_filename!r} (pattern = {incl_pattern.rematch})")
|
105
|
+
continue
|
106
|
+
|
107
|
+
# apply replacement
|
108
|
+
if incl_pattern.replace == '{0}':
|
109
|
+
dst_filename = src_filename
|
110
|
+
|
111
|
+
else:
|
112
|
+
args = (m.group(0), *m.groups())
|
113
|
+
kwargs = m.groupdict()
|
114
|
+
|
115
|
+
try:
|
116
|
+
dst_filename = incl_pattern.replace.format(*args, **kwargs)
|
117
|
+
# logger.debug(f" - renamed: {dst_filename!r} (template = {incl_pattern.replace!r})")
|
118
|
+
|
119
|
+
except (IndexError, KeyError) as e:
|
120
|
+
raise ValidationError(
|
121
|
+
f"Replacement '{incl_pattern.replace}' failed for"
|
122
|
+
f" '{incl_pattern.rematch.pattern}':"
|
123
|
+
f" {args}, {kwargs}") from None
|
124
|
+
|
125
|
+
_src = src/parent/src_filename
|
126
|
+
# re-base the dst path, (path relative to src) == (path relative to dst)
|
127
|
+
_dst = dst/dst_parent/dst_filename
|
128
|
+
|
129
|
+
# logger.debug(f" - from: {str(_src)!r}\n - to: {str(_dst)!r}")
|
130
|
+
|
131
|
+
yield (i, _src, _dst, _ignore_patterns, False)
|
132
|
+
|
133
|
+
|
134
|
+
#===============================================================================
|
135
|
+
def dist_copy(*,
|
136
|
+
base_path: Path,
|
137
|
+
copy_items: list[pyproj_dist_copy],
|
138
|
+
ignore,
|
139
|
+
dist,
|
140
|
+
root = None,
|
141
|
+
logger = None ):
|
142
|
+
|
143
|
+
if len(copy_items) == 0:
|
144
|
+
return
|
145
|
+
|
146
|
+
logger = logger or logging.getLogger( __name__ )
|
147
|
+
|
148
|
+
history: dict[Path, Path] = {}
|
149
|
+
|
150
|
+
with validating(key = 'copy'):
|
151
|
+
|
152
|
+
for i, src, dst, ignore_patterns, individual in dist_iter(
|
153
|
+
copy_items = copy_items,
|
154
|
+
ignore = ignore,
|
155
|
+
root = root,
|
156
|
+
logger = logger):
|
157
|
+
|
158
|
+
with validating(key = i):
|
159
|
+
|
160
|
+
dst = base_path.joinpath(dst)
|
161
|
+
src_abs = resolve(src)
|
162
|
+
|
163
|
+
if root and not subdir(root, src_abs, check = False):
|
164
|
+
raise FileOutsideRootError(
|
165
|
+
f"Must have common path with root:\n file = \"{src_abs}\"\n root = \"{root}\"")
|
166
|
+
|
167
|
+
_src = history.get(dst)
|
168
|
+
|
169
|
+
if _src == src:
|
170
|
+
continue
|
171
|
+
|
172
|
+
if _src is not None:
|
173
|
+
raise ValidationError(
|
174
|
+
f"Overwriting destination {str(dst)!r} from {str(_src)!r} with {str(src)!r}")
|
175
|
+
|
176
|
+
history[dst] = src
|
177
|
+
|
178
|
+
if src.is_dir():
|
179
|
+
dist.copytree(
|
180
|
+
src = src,
|
181
|
+
dst = dst,
|
182
|
+
ignore = ignore_patterns )
|
183
|
+
|
184
|
+
else:
|
185
|
+
dist.copyfile(
|
186
|
+
src = src,
|
187
|
+
dst = dst )
|
@@ -391,12 +391,14 @@ class TimeEncode:
|
|
391
391
|
Parameters
|
392
392
|
----------
|
393
393
|
resolution : int
|
394
|
-
Number of seconds that are resolved
|
394
|
+
Number of seconds that are resolved.
|
395
|
+
The default resolution is 1 minute
|
395
396
|
rollover : int
|
396
397
|
Number of seconds upper bound before wrapping.
|
397
|
-
The number of distinct values is ``rollover // resolution
|
398
|
+
The number of distinct values is ``rollover // resolution``.
|
399
|
+
The default rollover is 324 days
|
398
400
|
width : int
|
399
|
-
Minimal
|
401
|
+
Minimal width of encoded number
|
400
402
|
base : int
|
401
403
|
Numeric base used to encode number
|
402
404
|
"""
|
@@ -1,41 +1,18 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
import sys
|
3
|
-
import os
|
4
|
-
import os.path as osp
|
5
|
-
import io
|
6
|
-
import warnings
|
7
|
-
import stat
|
8
3
|
import re
|
9
|
-
import pathlib
|
10
4
|
import inspect
|
11
|
-
from copy import copy
|
12
|
-
from collections.abc import (
|
13
|
-
Mapping,
|
14
|
-
Sequence,
|
15
|
-
Iterable )
|
16
5
|
|
17
6
|
from collections import namedtuple
|
18
|
-
import hashlib
|
19
|
-
from base64 import urlsafe_b64encode
|
20
|
-
from email.message import Message
|
21
|
-
from email.generator import BytesGenerator
|
22
7
|
from email.utils import parseaddr, formataddr
|
23
8
|
from urllib.parse import urlparse
|
24
9
|
import keyword
|
25
10
|
|
26
11
|
from packaging.tags import sys_tags
|
27
|
-
from packaging.requirements import Requirement
|
28
|
-
from packaging.specifiers import SpecifierSet
|
29
12
|
|
30
13
|
from .validate import (
|
31
14
|
ValidationError,
|
32
|
-
validating
|
33
|
-
valid_type,
|
34
|
-
valid_keys,
|
35
|
-
valid_dict,
|
36
|
-
valid_list,
|
37
|
-
mapget,
|
38
|
-
as_list)
|
15
|
+
validating)
|
39
16
|
|
40
17
|
#===============================================================================
|
41
18
|
CompatibilityTags = namedtuple('CompatibilityTags', ['py_tag', 'abi_tag', 'plat_tag'])
|
@@ -151,7 +128,7 @@ def norm_dist_name( name ):
|
|
151
128
|
|
152
129
|
# > The name should be lowercased with all runs of the
|
153
130
|
# > characters ., -, or _ replaced with a single - character.
|
154
|
-
name =
|
131
|
+
name = pep_503_name_norm.sub('-', name)
|
155
132
|
|
156
133
|
return name
|
157
134
|
|
@@ -164,12 +141,14 @@ def norm_dist_filename( name ):
|
|
164
141
|
Each component of the filename is escaped by replacing runs of
|
165
142
|
non-alphanumeric characters with an underscore '_'
|
166
143
|
|
144
|
+
Addendum - It seems that "local" versions require '+'
|
145
|
+
|
167
146
|
See Also
|
168
147
|
--------
|
169
148
|
* https://www.python.org/dev/peps/pep-0427/#file-name-convention
|
170
149
|
"""
|
171
150
|
|
172
|
-
return re.sub( r"[^\w\d
|
151
|
+
return re.sub( r"[^\w\d\.\+]+", "_", name )
|
173
152
|
|
174
153
|
#===============================================================================
|
175
154
|
def join_dist_filename( parts ):
|
@@ -194,6 +173,12 @@ def join_dist_filename( parts ):
|
|
194
173
|
def norm_dist_version( version ):
|
195
174
|
"""Checks for valid distribution version (:pep:`440`)
|
196
175
|
|
176
|
+
.. versionchanged:: 0.1.9
|
177
|
+
|
178
|
+
Allow local version identifiers ``<public version identifier>[+<local version label>]``,
|
179
|
+
in addition to public versions.
|
180
|
+
Version pattern now uses :ref:`~packaging.version.VERSION_PATTERN`.
|
181
|
+
|
197
182
|
See Also
|
198
183
|
--------
|
199
184
|
* https://www.python.org/dev/peps/pep-0440/#version-scheme
|
@@ -390,16 +375,30 @@ def norm_dist_url( label, url ):
|
|
390
375
|
def norm_dist_extra( extra ):
|
391
376
|
"""Normalize distribution 'extra' requirement
|
392
377
|
|
378
|
+
.. versionchanged:: 0.2.0
|
379
|
+
|
380
|
+
Extra names are normalized according to PEP-685 and validated according to
|
381
|
+
Core Metadata 2.3.
|
382
|
+
Previously, extra names "must be a valid Python identifier" (Core Metadata 2.1)
|
383
|
+
|
384
|
+
|
393
385
|
Note
|
394
386
|
----
|
395
|
-
*
|
387
|
+
* MUST write out extra names in their normalized form.
|
388
|
+
* This applies to the Provides-Extra field and the extra marker when used
|
389
|
+
in the Requires-Dist field.
|
390
|
+
|
391
|
+
See Also
|
392
|
+
--------
|
393
|
+
* https://peps.python.org/pep-0685/#specification
|
396
394
|
"""
|
397
395
|
|
398
|
-
extra = norm_printable(
|
396
|
+
extra = norm_printable(extra).lower()
|
397
|
+
extra = pep_503_name_norm.sub('-', extra)
|
399
398
|
|
400
|
-
if not
|
399
|
+
if not pep_685_extra.fullmatch(extra):
|
401
400
|
raise PEPValidationError(
|
402
|
-
pep =
|
401
|
+
pep = 685,
|
403
402
|
msg = "Invalid extra",
|
404
403
|
val = extra )
|
405
404
|
|
@@ -590,6 +589,8 @@ def norm_entry_point_name( name ):
|
|
590
589
|
See Also
|
591
590
|
--------
|
592
591
|
* https://packaging.python.org/en/latest/specifications/entry-points/
|
592
|
+
* The name may contain any characters except =, but it cannot start or end with
|
593
|
+
any whitespace character, or start with [
|
593
594
|
"""
|
594
595
|
|
595
596
|
name = norm_printable( name )
|
@@ -635,14 +636,49 @@ def norm_entry_point_ref( ref ):
|
|
635
636
|
or 'importable.module:object.attr': {ref}""") from e
|
636
637
|
|
637
638
|
#===============================================================================
|
639
|
+
# https://packaging.python.org/en/latest/specifications/name-normalization/#name-format
|
638
640
|
pep426_dist_name = re.compile(
|
639
641
|
r'^([A-Z0-9]|[A-Z0-9][A-Z0-9._\-]*[A-Z0-9])$',
|
640
642
|
re.IGNORECASE )
|
641
643
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
644
|
+
# https://packaging.python.org/en/latest/specifications/name-normalization/#name-normalization
|
645
|
+
# > runs of characters ., -, or _ replaced with a single - character.
|
646
|
+
pep_503_name_norm = re.compile(r'[\-\_\.]+', re.IGNORECASE)
|
647
|
+
|
648
|
+
# value of packaging.version.VERSION_PATTERN, as of 'packaging == 25.0'
|
649
|
+
# just in case the variable is ever deprecated
|
650
|
+
VERSION_PATTERN = r"""
|
651
|
+
v?
|
652
|
+
(?:
|
653
|
+
(?:(?P<epoch>[0-9]+)!)? # epoch
|
654
|
+
(?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
|
655
|
+
(?P<pre> # pre-release
|
656
|
+
[-_\.]?
|
657
|
+
(?P<pre_l>alpha|a|beta|b|preview|pre|c|rc)
|
658
|
+
[-_\.]?
|
659
|
+
(?P<pre_n>[0-9]+)?
|
660
|
+
)?
|
661
|
+
(?P<post> # post release
|
662
|
+
(?:-(?P<post_n1>[0-9]+))
|
663
|
+
|
|
664
|
+
(?:
|
665
|
+
[-_\.]?
|
666
|
+
(?P<post_l>post|rev|r)
|
667
|
+
[-_\.]?
|
668
|
+
(?P<post_n2>[0-9]+)?
|
669
|
+
)
|
670
|
+
)?
|
671
|
+
(?P<dev> # dev release
|
672
|
+
[-_\.]?
|
673
|
+
(?P<dev_l>dev)
|
674
|
+
[-_\.]?
|
675
|
+
(?P<dev_n>[0-9]+)?
|
676
|
+
)?
|
677
|
+
)
|
678
|
+
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
|
679
|
+
"""
|
680
|
+
|
681
|
+
pep440_version = re.compile(VERSION_PATTERN, re.VERBOSE | re.IGNORECASE)
|
646
682
|
|
647
683
|
# NOTE: PEP 427 does not specify any constraints on the string following the
|
648
684
|
# digits, but given the form it is used in the filenames it really cannot
|
@@ -716,16 +752,22 @@ pep_301_classifier = re.compile(
|
|
716
752
|
pep_621_keyword = re.compile( r'^[^\s\,]+$' )
|
717
753
|
|
718
754
|
#===============================================================================
|
719
|
-
|
755
|
+
# https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata-provides-extra
|
756
|
+
pep_685_extra = re.compile( r'^[a-z0-9]+(-[a-z0-9]+)*$', re.IGNORECASE)
|
757
|
+
|
720
758
|
|
721
759
|
#===============================================================================
|
722
760
|
# https://packaging.python.org/en/latest/specifications/entry-points/
|
723
761
|
# Group names must be one or more groups of letters, numbers and underscores,
|
724
762
|
# separated by dots
|
725
763
|
entry_point_group = re.compile( r'^[A-Z0-9_]+(\.[A-Z0-9_]+)*$', re.IGNORECASE )
|
764
|
+
|
765
|
+
# The name may contain any characters except =, but it cannot start or end with
|
766
|
+
# any whitespace character, or start with [
|
726
767
|
# For new entry points (names), it is recommended to use only letters, numbers,
|
727
768
|
# underscores, dots and dashes
|
728
|
-
entry_point_name = re.compile(
|
769
|
+
# entry_point_name = re.compile(r'^([A-Z0-9_\.\-]+)?$', re.IGNORECASE)
|
770
|
+
entry_point_name = re.compile(r'^([^\[\]\=\s]+)?$', re.IGNORECASE)
|
729
771
|
|
730
772
|
#===============================================================================
|
731
773
|
py_keyword = re.compile( '^(' + '|'.join(keyword.kwlist) + ')$' )
|
@@ -121,9 +121,10 @@ class PkgInfoReq:
|
|
121
121
|
self.req = Requirement( norm_printable(req) )
|
122
122
|
|
123
123
|
marker = str( self.req.marker ) if self.req.marker else ''
|
124
|
-
extra = norm_dist_extra(extra)
|
125
124
|
|
126
125
|
if extra:
|
126
|
+
extra = norm_dist_extra(extra)
|
127
|
+
|
127
128
|
if marker:
|
128
129
|
self.req.marker = Marker(f'extra == "{extra}" and ( {marker} )')
|
129
130
|
else:
|
@@ -130,6 +130,49 @@ class optional_dependencies(valid_dict):
|
|
130
130
|
key_valid = valid(norm_dist_extra)
|
131
131
|
value_valid = valid(optional_dependency_group)
|
132
132
|
|
133
|
+
#===============================================================================
|
134
|
+
class dependency_group_include(valid_dict):
|
135
|
+
allow_keys = list()
|
136
|
+
default = {
|
137
|
+
'include-group': valid(norm_dist_extra)}
|
138
|
+
|
139
|
+
#===============================================================================
|
140
|
+
class dependency_group(valid_list):
|
141
|
+
value_valid = union(dependency_group_include, valid(norm_printable, Requirement, str))
|
142
|
+
|
143
|
+
#===============================================================================
|
144
|
+
def _check_dependency_groups(groups):
|
145
|
+
for group,v in groups.items():
|
146
|
+
for dep in v:
|
147
|
+
if isinstance(dep, Mapping):
|
148
|
+
_group = dep.get('include-group')
|
149
|
+
|
150
|
+
if _group not in groups:
|
151
|
+
raise ValidationError(f"'include-group' must be one of {set(groups)}: got {_group!r}")
|
152
|
+
|
153
|
+
elif _group == group:
|
154
|
+
raise ValidationError(f"'include-group' cannot be recursive: {_group!r}")
|
155
|
+
|
156
|
+
return groups
|
157
|
+
|
158
|
+
#===============================================================================
|
159
|
+
class dependency_groups(valid_dict):
|
160
|
+
r"""Dependency Groups
|
161
|
+
|
162
|
+
* https://packaging.python.org/en/latest/specifications/dependency-groups/
|
163
|
+
|
164
|
+
.. code-block:: toml
|
165
|
+
:caption: Example Dependency Groups
|
166
|
+
|
167
|
+
[dependency-groups]
|
168
|
+
coverage = ["coverage[toml]"]
|
169
|
+
test = ["pytest>7", {include-group = "coverage"}]
|
170
|
+
|
171
|
+
"""
|
172
|
+
key_valid = valid(norm_dist_extra)
|
173
|
+
value_valid = valid(dependency_group)
|
174
|
+
validator = valid(_check_dependency_groups)
|
175
|
+
|
133
176
|
#===============================================================================
|
134
177
|
class entry_point_group(valid_dict):
|
135
178
|
key_valid = valid(norm_entry_point_name)
|
@@ -317,9 +360,10 @@ class include(valid_dict):
|
|
317
360
|
proxy_key = 'glob'
|
318
361
|
# TODO: how to normalize patterns?
|
319
362
|
default = {
|
320
|
-
'glob': valid(nonempty_str),
|
363
|
+
'glob': valid(r'**', nonempty_str),
|
321
364
|
'rematch': valid(r'.*', nonempty_str, re.compile),
|
322
|
-
'replace': valid('{0}', nonempty_str)
|
365
|
+
'replace': valid('{0}', nonempty_str),
|
366
|
+
'strip': valid(int)}
|
323
367
|
|
324
368
|
#===============================================================================
|
325
369
|
class include_list(valid_list):
|
@@ -420,4 +464,5 @@ class pptoml(valid_dict):
|
|
420
464
|
default = {
|
421
465
|
'project': valid(REQUIRED, project),
|
422
466
|
'build-system': valid(REQUIRED, build_system),
|
467
|
+
'dependency-groups': valid(OPTIONAL, dependency_groups),
|
423
468
|
'tool': valid(OPTIONAL, tool) }
|
@@ -364,7 +364,7 @@ class PyProjBase:
|
|
364
364
|
with validating( key = 'tool.pyproj.dist.source'):
|
365
365
|
dist_copy(
|
366
366
|
base_path = dist.named_dirs['root'],
|
367
|
-
|
367
|
+
copy_items = self.source.copy,
|
368
368
|
ignore = self.dist.ignore + self.source.ignore,
|
369
369
|
dist = dist,
|
370
370
|
root = self.root,
|
@@ -413,7 +413,7 @@ class PyProjBase:
|
|
413
413
|
|
414
414
|
dist_copy(
|
415
415
|
base_path = dist.named_dirs['root'],
|
416
|
-
|
416
|
+
copy_items = self.binary.copy,
|
417
417
|
ignore = ignore,
|
418
418
|
dist = dist,
|
419
419
|
root = self.root,
|
@@ -437,7 +437,7 @@ class PyProjBase:
|
|
437
437
|
with validating( key = k ):
|
438
438
|
dist_copy(
|
439
439
|
base_path = dist.named_dirs[k],
|
440
|
-
|
440
|
+
copy_items = _include,
|
441
441
|
ignore = _ignore,
|
442
442
|
dist = dist,
|
443
443
|
root = self.root,
|
@@ -276,6 +276,10 @@ def validate(val, default, validators):
|
|
276
276
|
if not isinstance(validators, Sequence):
|
277
277
|
validators = [validators]
|
278
278
|
|
279
|
+
if not isinstance(validators, (list,tuple)):
|
280
|
+
raise ValidDefinitionError(
|
281
|
+
"Validators must be list or tuple")
|
282
|
+
|
279
283
|
for validator in validators:
|
280
284
|
if isinstance(validator, type):
|
281
285
|
# cast to valid type (if needed)
|
@@ -755,7 +759,8 @@ class _ValidDictMeta(ABCMeta):
|
|
755
759
|
'deprecate_keys',
|
756
760
|
'forbid_keys',
|
757
761
|
'default',
|
758
|
-
'proxy_keys'
|
762
|
+
'proxy_keys',
|
763
|
+
'validator')
|
759
764
|
|
760
765
|
schema = {}
|
761
766
|
|
@@ -820,21 +825,24 @@ class _ValidDictMeta(ABCMeta):
|
|
820
825
|
all_keys = tuple(all_keys)
|
821
826
|
|
822
827
|
# compose validator with parameterized valid_keys method
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
828
|
+
validators = [partial(valid_keys,
|
829
|
+
key_valid = key_valid,
|
830
|
+
value_valid = value_valid,
|
831
|
+
item_valid = item_valid,
|
832
|
+
allow_keys = allow_keys,
|
833
|
+
require_keys = require_keys,
|
834
|
+
min_keys = min_keys,
|
835
|
+
wedge_keys = wedge_keys,
|
836
|
+
mutex_keys = mutex_keys,
|
837
|
+
deprecate_keys = deprecate_keys,
|
838
|
+
forbid_keys = forbid_keys,
|
839
|
+
default = default,
|
840
|
+
proxy_keys = proxy_keys)]
|
841
|
+
|
842
|
+
if validator:
|
843
|
+
validators.append(validator)
|
844
|
+
|
845
|
+
validator = valid(*validators)
|
838
846
|
|
839
847
|
namespace['_all_keys'] = all_keys
|
840
848
|
namespace['_validator'] = validator
|
@@ -925,6 +933,9 @@ class valid_dict(Mapping, metaclass = _ValidDictMeta):
|
|
925
933
|
elif cls.proxy_key:
|
926
934
|
args = [{ cls.proxy_key : v }]
|
927
935
|
|
936
|
+
else:
|
937
|
+
raise ValidationError(f"Expected mapping: got {v!r}")
|
938
|
+
|
928
939
|
self._data = dict(*args, **kwargs)
|
929
940
|
self._validate()
|
930
941
|
|
@@ -1042,19 +1053,23 @@ class valid_list(list):
|
|
1042
1053
|
#---------------------------------------------------------------------------#
|
1043
1054
|
def __init__( self, vals = None ):
|
1044
1055
|
cls = type(self)
|
1045
|
-
self._as_list = cls._as_list or list
|
1046
|
-
self.value_valid = valid(
|
1047
|
-
cls.value_valid or (lambda v: v))
|
1048
1056
|
|
1049
1057
|
if vals is None:
|
1050
1058
|
vals = list()
|
1051
1059
|
|
1052
|
-
elif
|
1053
|
-
vals =
|
1060
|
+
elif cls._as_list:
|
1061
|
+
vals = cls._as_list(vals)
|
1062
|
+
|
1063
|
+
elif not isinstance(vals, Iterable) or isinstance(vals, (str,Mapping)):
|
1064
|
+
raise ValidationError(f"Excpected sequence: got {vals!r}")
|
1054
1065
|
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1066
|
+
else:
|
1067
|
+
vals = list(vals)
|
1068
|
+
|
1069
|
+
if cls.value_valid:
|
1070
|
+
for i,v in enumerate(vals):
|
1071
|
+
with validating(key = i):
|
1072
|
+
vals[i] = cls.value_valid(v)
|
1058
1073
|
|
1059
1074
|
super().__init__(vals)
|
1060
1075
|
self._validate()
|
@@ -1072,8 +1087,9 @@ class valid_list(list):
|
|
1072
1087
|
|
1073
1088
|
#---------------------------------------------------------------------------#
|
1074
1089
|
def append(self, val ):
|
1075
|
-
|
1076
|
-
|
1090
|
+
if self.value_valid:
|
1091
|
+
with validating(key = len(self)):
|
1092
|
+
val = self.value_valid(val)
|
1077
1093
|
|
1078
1094
|
super().append(val)
|
1079
1095
|
|
@@ -1081,16 +1097,18 @@ class valid_list(list):
|
|
1081
1097
|
def extend(self, vals ):
|
1082
1098
|
vals = list(vals)
|
1083
1099
|
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1100
|
+
if self.value_valid:
|
1101
|
+
for i,v in enumerate(vals):
|
1102
|
+
with validating(key = len(self) + i):
|
1103
|
+
vals[i] = self.value_valid(v)
|
1087
1104
|
|
1088
1105
|
super().extend(vals)
|
1089
1106
|
|
1090
1107
|
#-----------------------------------------------------------------------------
|
1091
1108
|
def __setitem__( self, key, val ):
|
1092
|
-
|
1093
|
-
|
1109
|
+
if self.value_valid:
|
1110
|
+
with validating(key = key):
|
1111
|
+
val = self.value_valid(val)
|
1094
1112
|
|
1095
1113
|
super().__setitem__(key, val)
|
1096
1114
|
|
@@ -1,28 +1,29 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: partis-pyproj
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Requires-Python: >=3.8
|
5
5
|
Author-email: "Nanohmics Inc." <software.support@nanohmics.com>
|
6
6
|
Maintainer-email: "Nanohmics Inc." <software.support@nanohmics.com>
|
7
7
|
Summary: Minimal set of Python project utilities (PEP-517/621)
|
8
8
|
License-File: LICENSE.txt
|
9
|
+
Project-URL: homepage, https://github.com/kcdodd/partis-pyproj/
|
9
10
|
Classifier: Programming Language :: Python
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
11
|
-
Classifier: Topic :: Software Development :: Build Tools
|
12
|
-
Classifier: License :: OSI Approved :: BSD License
|
13
11
|
Classifier: Programming Language :: Python :: 3
|
14
|
-
Classifier: Operating System :: POSIX :: Linux
|
15
12
|
Classifier: Operating System :: Microsoft :: Windows
|
13
|
+
Classifier: License :: OSI Approved :: BSD License
|
14
|
+
Classifier: Topic :: Software Development :: Build Tools
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
16
16
|
Classifier: Intended Audience :: Developers
|
17
|
+
Classifier: Development Status :: 4 - Beta
|
17
18
|
Provides-Extra: meson
|
18
19
|
Provides-Extra: cmake
|
20
|
+
Requires-Dist: requests>=2.32.3
|
19
21
|
Requires-Dist: packaging>=24.2
|
20
22
|
Requires-Dist: tomli>=2.0.1
|
21
|
-
Requires-Dist: requests>=2.32.3
|
22
|
-
Requires-Dist: ninja>=1.10.2.3; extra == "meson"
|
23
23
|
Requires-Dist: meson>=0.61.3; extra == "meson"
|
24
|
-
Requires-Dist:
|
24
|
+
Requires-Dist: ninja>=1.10.2.3; extra == "meson"
|
25
25
|
Requires-Dist: ninja>=1.10.2.3; extra == "cmake"
|
26
|
+
Requires-Dist: cmake>=3.24.3; extra == "cmake"
|
26
27
|
Description-Content-Type: text/markdown
|
27
28
|
|
28
29
|
[](https://github.com/kcdodd/partis-pyproj/actions/workflows/tests.yaml)
|
@@ -87,10 +88,15 @@ formats and behaviors.
|
|
87
88
|
|
88
89
|
* An `include` list is used to filter files or directories to be copied, expanded
|
89
90
|
to zero or more matches relative to `src`.
|
90
|
-
* `glob` follows the format of [Path.glob](https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob)
|
91
|
-
|
92
|
-
|
91
|
+
* `glob` follows the format of [Path.glob](https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob).
|
92
|
+
If recursive pattern `**` is used, the glob will *not* match directories,
|
93
|
+
since the resulting `copytree` would end up copying all files in the directory.
|
94
|
+
* `rematch` may further discriminate filenames (already matched by `glob`) using [Regular Expression Syntax](https://docs.python.org/3/library/re.html#regular-expression-syntax). Directories are *not* considered by `rematch`.
|
95
|
+
* `replace` can change destination *filenames* using
|
93
96
|
[Format String Syntax](https://docs.python.org/3/library/string.html#format-string-syntax), with values supplied by any groups defined in `rematch`.
|
97
|
+
This cannot rename directories.
|
98
|
+
* `strip` can remove (up to) the given number of path components from the relative
|
99
|
+
`src` path.
|
94
100
|
|
95
101
|
**Ignore patterns**
|
96
102
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/file.py,sha256=cU327vzXGfuMWlqY-LdfGqGs7LOhVd0MOUOIdAL5od4,1581
|
2
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/__init__.py,sha256=-CibR9jSfwRxNn4gHe-7_ZrQnH3FY4JYTi3Mz-Q66cU,1560
|
3
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/validate.py,sha256=FS-x15lErV6_y5WLOD2pv5j6jWsXXalA4xdYeazi140,32587
|
4
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/_legacy_setup.py,sha256=tAE0xlD9RVhhMn1kcUPSccbDFE1ReuH99jfrw8q8MiM,5301
|
5
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/norms.py,sha256=d6SkBBSST87smwD27YZ1lhicuw6rHdRQfXb_xnBsCGk,10990
|
6
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/cargo.py,sha256=z9yj7QNZqCV_hFRBOsBBWo1GgOWZF0Oqag0kLpfN-2I,1144
|
7
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/__init__.py,sha256=IRQk2gA5mK6BjewVHQ1IcVLVENV2vBMrwS4JO8wGPYc,164
|
8
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/meson.py,sha256=V39hN5bJ4kc9JBTXwT0XIc9uMtnKtrYczWC28jqu-GU,1939
|
9
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/process.py,sha256=8tUuFQrnks6Q-0G6Ow8G7LOycc2Z5olqLBzGhRCAulg,1002
|
10
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/download.py,sha256=m0F5lTC7AjPaZGPp6xkFCt8ziMjqrVMUZfzXo_XTwdw,5552
|
11
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/cmake.py,sha256=soKtbHkLttRq96NdLTD8dlD5SgzxrFYqJadC9V8HSjw,1915
|
12
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/builder/builder.py,sha256=iTU_GFWmyk0yNoFdG7nL76_SP0x-Y4Ej6h4RrkZuVjE,11909
|
13
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/pyproj.py,sha256=G8dbbqpBjfCyd9o9fpaP8Lflz9P207UeTQ-2D_APOnM,12767
|
14
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/pptoml.py,sha256=U3lJUJk9GPSmwvQsVb8lqtA8nxD5nXUeZLjd9jX3zIM,15111
|
15
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/legacy.py,sha256=JXSg-5Y65PUOtlEgkIgNj3vwZtJFi9CVsRvnpar2xKs,1749
|
16
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/template.py,sha256=1OmPPAEOLz0kquypFEb_c2aLysTGOwC2zqw1_eXYutY,6908
|
17
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/pkginfo.py,sha256=PtW1J6NSkjJ2en4l5sxo7FkpTaaWd_kLjtZU1NNybYo,15151
|
18
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/_nonprintable.py,sha256=2-JeNY6prFM4cfZKeFuv-aZW7ZvPI8FYO7dJ0CL3RD8,1893
|
19
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/pep.py,sha256=ukhfWr5Nd80L1VEOZkcVGzKstKt19UcoSqd1V3axYpo,34661
|
20
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/load_module.py,sha256=6y3oMqCvycS4EhcOn1NtuXWyix0smCnogEH6W0bWiPg,4396
|
21
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/backend.py,sha256=E4IxPkrNTvgJ3-RqFa40deXfjeeJrvCa_CGtPV3Uj5I,7055
|
22
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/path/__init__.py,sha256=458RSB1Lr63sY3CP_uqxaHkEUQMgeqZgNXFzpUIbsn4,236
|
23
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/path/utils.py,sha256=lJUyTGecZDMoTphSItr99_4b_yp_4zMRd8IAFiXgsI4,2364
|
24
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/path/match.py,sha256=zyeGJtVQ-gWLGx1NBlDhJ8cWa6mJyU0JBWFUdhz7yik,11812
|
25
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/path/pattern.py,sha256=d3SO_bencbojbf3zkvaR6bxzT83VFrMpI-wEfc26Qk0,16107
|
26
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/__init__.py,sha256=7SK7yeLehYJCbeHgnRFb4tPi2bEP2_ouA-qNxh_ofJI,379
|
27
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_targz.py,sha256=csb8NckhfScIUNY6LnQlUM31Jio69RwndBLuGD45Kls,3867
|
28
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_base.py,sha256=0LbWUitfuunpU0azUMD9xvapfn3_waUzZJVLwHxhD3E,11997
|
29
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_copy.py,sha256=gE0ZY68Th-Ym2609KN9ebsulhyQsYEflL3x2Pau4ZKU,5300
|
30
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_binary.py,sha256=COfEivLDvHk2ycX9xTSnNnIsc5EyXRTznaJPWOrx4Os,7749
|
31
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_source.py,sha256=_TzLbzLSn6TIwO98zwdvllkGCJgvr6BKnjNM-URKiCw,4362
|
32
|
+
partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_zip.py,sha256=ILAIz1myBgAR4xFRNgcJ1b2otcdUscyRViEbbArzL1M,3810
|
33
|
+
partis_pyproj-0.2.0.dist-info/METADATA,sha256=WG7rbmkjVNSGi2ewvctnGgXuaECl259CX4cHKhKECjM,22424
|
34
|
+
partis_pyproj-0.2.0.dist-info/LICENSE.txt,sha256=6LYtpan0H8F0reCrEa1ZUf_Nr9Vu93A3bqunX2J5Et0,3320
|
35
|
+
partis_pyproj-0.2.0.dist-info/top_level.txt,sha256=T72LF-bUK7nMDf1GQgbzvgZ2YrJElwwRd9h7HwVQBIQ,6
|
36
|
+
partis_pyproj-0.2.0.dist-info/entry_points.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
|
+
partis_pyproj-0.2.0.dist-info/WHEEL,sha256=4YeLUbbRU8D0xzIlG3rm8IFLwHKcY8YaY_wiNxswKJg,126
|
38
|
+
partis_pyproj-0.2.0.dist-info/RECORD,,
|
@@ -1,138 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
import os
|
3
|
-
import glob
|
4
|
-
from pathlib import (
|
5
|
-
Path)
|
6
|
-
import logging
|
7
|
-
from ..validate import (
|
8
|
-
FileOutsideRootError,
|
9
|
-
validating )
|
10
|
-
from ..path import (
|
11
|
-
PathFilter,
|
12
|
-
subdir,
|
13
|
-
combine_ignore_patterns,
|
14
|
-
resolve)
|
15
|
-
|
16
|
-
# #===============================================================================
|
17
|
-
# def rematch_replace(rematch, replace, name):
|
18
|
-
|
19
|
-
# m = rematch.fullmatch(path)
|
20
|
-
# if not m:
|
21
|
-
# continue
|
22
|
-
|
23
|
-
# args = (m.group(0), *m.groups())
|
24
|
-
# kwargs = m.groupdict()
|
25
|
-
# try:
|
26
|
-
# replace.format(*args, **kwargs))
|
27
|
-
# except (IndexError, KeyError) as e:
|
28
|
-
# raise ValueError(
|
29
|
-
# f"Replacement '{replace}' failed to format match '{m.group(0)}': "
|
30
|
-
# f"{args}, {kwargs}") from None
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
#===============================================================================
|
35
|
-
def dist_iter(*,
|
36
|
-
include,
|
37
|
-
ignore,
|
38
|
-
root ):
|
39
|
-
|
40
|
-
patterns = PathFilter(
|
41
|
-
patterns = ignore )
|
42
|
-
|
43
|
-
for i, incl in enumerate(include):
|
44
|
-
src = incl.src
|
45
|
-
dst = incl.dst
|
46
|
-
_ignore = incl.ignore
|
47
|
-
|
48
|
-
_ignore_patterns = combine_ignore_patterns(
|
49
|
-
patterns,
|
50
|
-
PathFilter(
|
51
|
-
patterns = _ignore,
|
52
|
-
start = src ) )
|
53
|
-
|
54
|
-
if not incl.include:
|
55
|
-
yield ( i, src, dst, _ignore_patterns, True )
|
56
|
-
else:
|
57
|
-
for incl_pattern in incl.include:
|
58
|
-
cwd = Path.cwd()
|
59
|
-
try:
|
60
|
-
# TODO: better way of globing *relative* to src directory
|
61
|
-
os.chdir(src)
|
62
|
-
matches = glob.glob(incl_pattern.glob, recursive = True)
|
63
|
-
finally:
|
64
|
-
os.chdir(cwd)
|
65
|
-
|
66
|
-
for match in matches:
|
67
|
-
match = Path(match)
|
68
|
-
basename = match.parent
|
69
|
-
src_filename = match.name
|
70
|
-
|
71
|
-
m = incl_pattern.rematch.fullmatch(src_filename)
|
72
|
-
if not m:
|
73
|
-
continue
|
74
|
-
|
75
|
-
args = (m.group(0), *m.groups())
|
76
|
-
kwargs = m.groupdict()
|
77
|
-
try:
|
78
|
-
dst_filename = incl_pattern.replace.format(*args, **kwargs)
|
79
|
-
except (IndexError, KeyError) as e:
|
80
|
-
raise ValueError(
|
81
|
-
f"Replacement '{incl_pattern.replace}' failed for"
|
82
|
-
f" '{incl_pattern.rematch.pattern}':"
|
83
|
-
f" {args}, {kwargs}") from None
|
84
|
-
|
85
|
-
_src = src/basename/src_filename
|
86
|
-
# re-base the dst path, path relative to src == path relative to dst
|
87
|
-
_dst = dst/basename/dst_filename
|
88
|
-
|
89
|
-
yield (i, _src, _dst, _ignore_patterns, False)
|
90
|
-
|
91
|
-
|
92
|
-
#===============================================================================
|
93
|
-
def dist_copy(*,
|
94
|
-
base_path,
|
95
|
-
include,
|
96
|
-
ignore,
|
97
|
-
dist,
|
98
|
-
root = None,
|
99
|
-
logger = None ):
|
100
|
-
|
101
|
-
if len(include) == 0:
|
102
|
-
return
|
103
|
-
|
104
|
-
logger = logger or logging.getLogger( __name__ )
|
105
|
-
|
106
|
-
with validating(key = 'copy'):
|
107
|
-
|
108
|
-
for i, src, dst, ignore_patterns, individual in dist_iter(
|
109
|
-
include = include,
|
110
|
-
ignore = ignore,
|
111
|
-
root = root ):
|
112
|
-
|
113
|
-
with validating(key = i):
|
114
|
-
|
115
|
-
dst = base_path.joinpath(dst)
|
116
|
-
|
117
|
-
if not individual and ignore_patterns( src.parent, [src.name]):
|
118
|
-
logger.debug( f'ignoring: {src}' )
|
119
|
-
continue
|
120
|
-
|
121
|
-
src_abs = resolve(src)
|
122
|
-
|
123
|
-
if root and not subdir(root, src_abs, check = False):
|
124
|
-
raise FileOutsideRootError(
|
125
|
-
f"Must have common path with root:\n file = \"{src_abs}\"\n root = \"{root}\"")
|
126
|
-
|
127
|
-
logger.debug(f"dist copy: {src} -> {dst}")
|
128
|
-
|
129
|
-
if src.is_dir():
|
130
|
-
dist.copytree(
|
131
|
-
src = src,
|
132
|
-
dst = dst,
|
133
|
-
ignore = ignore_patterns )
|
134
|
-
|
135
|
-
else:
|
136
|
-
dist.copyfile(
|
137
|
-
src = src,
|
138
|
-
dst = dst )
|
@@ -1,38 +0,0 @@
|
|
1
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/file.py,sha256=cU327vzXGfuMWlqY-LdfGqGs7LOhVd0MOUOIdAL5od4,1581
|
2
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/__init__.py,sha256=-CibR9jSfwRxNn4gHe-7_ZrQnH3FY4JYTi3Mz-Q66cU,1560
|
3
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/validate.py,sha256=ZYzaiHaWWkw9RLL-AgVfch-3gacNg5s1Vl0yy6gX4-U,32168
|
4
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/_legacy_setup.py,sha256=tAE0xlD9RVhhMn1kcUPSccbDFE1ReuH99jfrw8q8MiM,5301
|
5
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/norms.py,sha256=uyF3Pi9NbptleTabdZlMkaKJB5ymfDOSrcpD6bygQeM,10909
|
6
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/cargo.py,sha256=z9yj7QNZqCV_hFRBOsBBWo1GgOWZF0Oqag0kLpfN-2I,1144
|
7
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/__init__.py,sha256=IRQk2gA5mK6BjewVHQ1IcVLVENV2vBMrwS4JO8wGPYc,164
|
8
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/meson.py,sha256=V39hN5bJ4kc9JBTXwT0XIc9uMtnKtrYczWC28jqu-GU,1939
|
9
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/process.py,sha256=8tUuFQrnks6Q-0G6Ow8G7LOycc2Z5olqLBzGhRCAulg,1002
|
10
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/download.py,sha256=RfDeAsGXMCAYct5REXroF7QwncQdrliYhMzm8ePxE94,4981
|
11
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/cmake.py,sha256=soKtbHkLttRq96NdLTD8dlD5SgzxrFYqJadC9V8HSjw,1915
|
12
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/builder/builder.py,sha256=pOIBUG5iEVsjh9SglIky41kgWLcAyHdEDAWzym2CM2g,11467
|
13
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/pyproj.py,sha256=Ra7DOj2Pq5peC_pT82xQoAxCDX3sHukpbKgNSqNeI8c,12758
|
14
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/pptoml.py,sha256=uThSRs6EMA51nFo38XufFCVEWifC83prM85oCKqxliQ,13565
|
15
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/legacy.py,sha256=JXSg-5Y65PUOtlEgkIgNj3vwZtJFi9CVsRvnpar2xKs,1749
|
16
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/template.py,sha256=1OmPPAEOLz0kquypFEb_c2aLysTGOwC2zqw1_eXYutY,6908
|
17
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/pkginfo.py,sha256=6rz06s19MX7zQIWt2wE-HEg-1WA2LZogk9kdqKFFcVE,15148
|
18
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/_nonprintable.py,sha256=2-JeNY6prFM4cfZKeFuv-aZW7ZvPI8FYO7dJ0CL3RD8,1893
|
19
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/pep.py,sha256=XzZYnYKaB4V3wOXUsrGNav9H_ziMoaQb9wGEKlciOms,32694
|
20
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/load_module.py,sha256=6y3oMqCvycS4EhcOn1NtuXWyix0smCnogEH6W0bWiPg,4396
|
21
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/backend.py,sha256=sKubLkwD30n_nwFnIqQ-T4Dh5UFZUXf5r5yrl5oNiXs,7004
|
22
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/path/__init__.py,sha256=458RSB1Lr63sY3CP_uqxaHkEUQMgeqZgNXFzpUIbsn4,236
|
23
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/path/utils.py,sha256=lJUyTGecZDMoTphSItr99_4b_yp_4zMRd8IAFiXgsI4,2364
|
24
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/path/match.py,sha256=zyeGJtVQ-gWLGx1NBlDhJ8cWa6mJyU0JBWFUdhz7yik,11812
|
25
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/path/pattern.py,sha256=d3SO_bencbojbf3zkvaR6bxzT83VFrMpI-wEfc26Qk0,16107
|
26
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/__init__.py,sha256=7SK7yeLehYJCbeHgnRFb4tPi2bEP2_ouA-qNxh_ofJI,379
|
27
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_targz.py,sha256=csb8NckhfScIUNY6LnQlUM31Jio69RwndBLuGD45Kls,3867
|
28
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_base.py,sha256=0LbWUitfuunpU0azUMD9xvapfn3_waUzZJVLwHxhD3E,11997
|
29
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_copy.py,sha256=MXUfoOXhH2eTetgkkz-5linJkqzX7_q4gIvCLLlB-7c,3519
|
30
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_binary.py,sha256=COfEivLDvHk2ycX9xTSnNnIsc5EyXRTznaJPWOrx4Os,7749
|
31
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_source.py,sha256=_TzLbzLSn6TIwO98zwdvllkGCJgvr6BKnjNM-URKiCw,4362
|
32
|
-
partis_pyproj-0.1.8.data/purelib/partis/pyproj/dist_file/dist_zip.py,sha256=ILAIz1myBgAR4xFRNgcJ1b2otcdUscyRViEbbArzL1M,3810
|
33
|
-
partis_pyproj-0.1.8.dist-info/METADATA,sha256=5VkYF6-weoj2QFLR2MPHR8Quv6F4m2DCSUsSgW9nTy0,22034
|
34
|
-
partis_pyproj-0.1.8.dist-info/LICENSE.txt,sha256=6LYtpan0H8F0reCrEa1ZUf_Nr9Vu93A3bqunX2J5Et0,3320
|
35
|
-
partis_pyproj-0.1.8.dist-info/top_level.txt,sha256=T72LF-bUK7nMDf1GQgbzvgZ2YrJElwwRd9h7HwVQBIQ,6
|
36
|
-
partis_pyproj-0.1.8.dist-info/entry_points.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
|
-
partis_pyproj-0.1.8.dist-info/WHEEL,sha256=4YeLUbbRU8D0xzIlG3rm8IFLwHKcY8YaY_wiNxswKJg,126
|
38
|
-
partis_pyproj-0.1.8.dist-info/RECORD,,
|
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/_legacy_setup.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/_nonprintable.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/__init__.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/cargo.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/cmake.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/meson.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/process.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/__init__.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_base.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_binary.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_source.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_targz.py
RENAMED
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_zip.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{partis_pyproj-0.1.8.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|