partis-pyproj 0.1.9__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.
Files changed (40) hide show
  1. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/backend.py +1 -1
  2. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/builder.py +19 -1
  3. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/download.py +31 -6
  4. partis_pyproj-0.2.0.data/purelib/partis/pyproj/dist_file/dist_copy.py +187 -0
  5. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pep.py +74 -36
  6. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pkginfo.py +2 -1
  7. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pptoml.py +3 -1
  8. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/pyproj.py +3 -3
  9. {partis_pyproj-0.1.9.dist-info → partis_pyproj-0.2.0.dist-info}/METADATA +16 -11
  10. partis_pyproj-0.2.0.dist-info/RECORD +38 -0
  11. partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_copy.py +0 -139
  12. partis_pyproj-0.1.9.dist-info/RECORD +0 -38
  13. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/__init__.py +0 -0
  14. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/_legacy_setup.py +0 -0
  15. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/_nonprintable.py +0 -0
  16. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/__init__.py +0 -0
  17. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/cargo.py +0 -0
  18. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/cmake.py +0 -0
  19. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/meson.py +0 -0
  20. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/builder/process.py +0 -0
  21. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/__init__.py +0 -0
  22. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_base.py +0 -0
  23. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_binary.py +0 -0
  24. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_source.py +0 -0
  25. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_targz.py +0 -0
  26. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/dist_file/dist_zip.py +0 -0
  27. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/file.py +0 -0
  28. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/legacy.py +0 -0
  29. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/load_module.py +0 -0
  30. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/norms.py +0 -0
  31. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/__init__.py +0 -0
  32. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/match.py +0 -0
  33. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/pattern.py +0 -0
  34. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/path/utils.py +0 -0
  35. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/template.py +0 -0
  36. {partis_pyproj-0.1.9.data → partis_pyproj-0.2.0.data}/purelib/partis/pyproj/validate.py +0 -0
  37. {partis_pyproj-0.1.9.dist-info → partis_pyproj-0.2.0.dist-info}/LICENSE.txt +0 -0
  38. {partis_pyproj-0.1.9.dist-info → partis_pyproj-0.2.0.dist-info}/WHEEL +0 -0
  39. {partis_pyproj-0.1.9.dist-info → partis_pyproj-0.2.0.dist-info}/entry_points.txt +0 -0
  40. {partis_pyproj-0.1.9.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 = logging.INFO,
56
+ level = os.environ.get('PARTIS_PYPROJ_LOGLEVEL', 'INFO').upper(),
57
57
  format = "{message}",
58
58
  style = "{" )
59
59
 
@@ -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': sysconfig.get_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'])
@@ -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
- with requests.get(url, stream=True) as req, tmp_file.open('wb') as fp:
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
- logger.info(f"- extracting: {cache_file} -> {build_dir}")
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=build_dir,
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=build_dir,
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 = cache_dir/url_dirname
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 )
@@ -1,42 +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
- from packaging.version import VERSION_PATTERN
30
12
 
31
13
  from .validate import (
32
14
  ValidationError,
33
- validating,
34
- valid_type,
35
- valid_keys,
36
- valid_dict,
37
- valid_list,
38
- mapget,
39
- as_list)
15
+ validating)
40
16
 
41
17
  #===============================================================================
42
18
  CompatibilityTags = namedtuple('CompatibilityTags', ['py_tag', 'abi_tag', 'plat_tag'])
@@ -152,7 +128,7 @@ def norm_dist_name( name ):
152
128
 
153
129
  # > The name should be lowercased with all runs of the
154
130
  # > characters ., -, or _ replaced with a single - character.
155
- name = re.sub( r'[\-\_\.]+', "-", name )
131
+ name = pep_503_name_norm.sub('-', name)
156
132
 
157
133
  return name
158
134
 
@@ -197,6 +173,12 @@ def join_dist_filename( parts ):
197
173
  def norm_dist_version( version ):
198
174
  """Checks for valid distribution version (:pep:`440`)
199
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
+
200
182
  See Also
201
183
  --------
202
184
  * https://www.python.org/dev/peps/pep-0440/#version-scheme
@@ -393,16 +375,30 @@ def norm_dist_url( label, url ):
393
375
  def norm_dist_extra( extra ):
394
376
  """Normalize distribution 'extra' requirement
395
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
+
396
385
  Note
397
386
  ----
398
- * No known PEP specifies this format, but is treated as
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
399
394
  """
400
395
 
401
- extra = norm_printable( extra )
396
+ extra = norm_printable(extra).lower()
397
+ extra = pep_503_name_norm.sub('-', extra)
402
398
 
403
- if not pep_621_extra.fullmatch( extra ):
399
+ if not pep_685_extra.fullmatch(extra):
404
400
  raise PEPValidationError(
405
- pep = 621,
401
+ pep = 685,
406
402
  msg = "Invalid extra",
407
403
  val = extra )
408
404
 
@@ -593,6 +589,8 @@ def norm_entry_point_name( name ):
593
589
  See Also
594
590
  --------
595
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 [
596
594
  """
597
595
 
598
596
  name = norm_printable( name )
@@ -638,15 +636,49 @@ def norm_entry_point_ref( ref ):
638
636
  or 'importable.module:object.attr': {ref}""") from e
639
637
 
640
638
  #===============================================================================
639
+ # https://packaging.python.org/en/latest/specifications/name-normalization/#name-format
641
640
  pep426_dist_name = re.compile(
642
641
  r'^([A-Z0-9]|[A-Z0-9][A-Z0-9._\-]*[A-Z0-9])$',
643
642
  re.IGNORECASE )
644
643
 
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
+
645
681
  pep440_version = re.compile(VERSION_PATTERN, re.VERBOSE | re.IGNORECASE)
646
- # pep440_version = re.compile(
647
- # r'^([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*'
648
- # r'((a|b|rc)(0|[1-9][0-9]*))?'
649
- # r'(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$' )
650
682
 
651
683
  # NOTE: PEP 427 does not specify any constraints on the string following the
652
684
  # digits, but given the form it is used in the filenames it really cannot
@@ -720,16 +752,22 @@ pep_301_classifier = re.compile(
720
752
  pep_621_keyword = re.compile( r'^[^\s\,]+$' )
721
753
 
722
754
  #===============================================================================
723
- pep_621_extra = re.compile( r'^([A-Z0-9_]+)?$', re.IGNORECASE )
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
+
724
758
 
725
759
  #===============================================================================
726
760
  # https://packaging.python.org/en/latest/specifications/entry-points/
727
761
  # Group names must be one or more groups of letters, numbers and underscores,
728
762
  # separated by dots
729
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 [
730
767
  # For new entry points (names), it is recommended to use only letters, numbers,
731
768
  # underscores, dots and dashes
732
- entry_point_name = re.compile( r'^([A-Z0-9_\.\-]+)?$', re.IGNORECASE )
769
+ # entry_point_name = re.compile(r'^([A-Z0-9_\.\-]+)?$', re.IGNORECASE)
770
+ entry_point_name = re.compile(r'^([^\[\]\=\s]+)?$', re.IGNORECASE)
733
771
 
734
772
  #===============================================================================
735
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:
@@ -362,7 +362,8 @@ class include(valid_dict):
362
362
  default = {
363
363
  'glob': valid(r'**', nonempty_str),
364
364
  'rematch': valid(r'.*', nonempty_str, re.compile),
365
- 'replace': valid('{0}', nonempty_str)}
365
+ 'replace': valid('{0}', nonempty_str),
366
+ 'strip': valid(int)}
366
367
 
367
368
  #===============================================================================
368
369
  class include_list(valid_list):
@@ -463,4 +464,5 @@ class pptoml(valid_dict):
463
464
  default = {
464
465
  'project': valid(REQUIRED, project),
465
466
  'build-system': valid(REQUIRED, build_system),
467
+ 'dependency-groups': valid(OPTIONAL, dependency_groups),
466
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
- include = self.source.copy,
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
- include = self.binary.copy,
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
- include = _include,
440
+ copy_items = _include,
441
441
  ignore = _ignore,
442
442
  dist = dist,
443
443
  root = self.root,
@@ -1,25 +1,25 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: partis-pyproj
3
- Version: 0.1.9
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
9
  Project-URL: homepage, https://github.com/kcdodd/partis-pyproj/
10
+ Classifier: Programming Language :: Python
11
+ Classifier: Programming Language :: Python :: 3
10
12
  Classifier: Operating System :: Microsoft :: Windows
11
- Classifier: Development Status :: 4 - Beta
12
- Classifier: Operating System :: POSIX :: Linux
13
- Classifier: Intended Audience :: Developers
14
13
  Classifier: License :: OSI Approved :: BSD License
15
- Classifier: Programming Language :: Python
16
14
  Classifier: Topic :: Software Development :: Build Tools
17
- Classifier: Programming Language :: Python :: 3
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Development Status :: 4 - Beta
18
18
  Provides-Extra: meson
19
19
  Provides-Extra: cmake
20
- Requires-Dist: tomli>=2.0.1
21
- Requires-Dist: packaging>=24.2
22
20
  Requires-Dist: requests>=2.32.3
21
+ Requires-Dist: packaging>=24.2
22
+ Requires-Dist: tomli>=2.0.1
23
23
  Requires-Dist: meson>=0.61.3; extra == "meson"
24
24
  Requires-Dist: ninja>=1.10.2.3; extra == "meson"
25
25
  Requires-Dist: ninja>=1.10.2.3; extra == "cmake"
@@ -88,10 +88,15 @@ formats and behaviors.
88
88
 
89
89
  * An `include` list is used to filter files or directories to be copied, expanded
90
90
  to zero or more matches relative to `src`.
91
- * `glob` follows the format of [Path.glob](https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob), with recursion.
92
- * `rematch` may further discriminate files (already matched by `glob`) using [Regular Expression Syntax](https://docs.python.org/3/library/re.html#regular-expression-syntax).
93
- * `replace` can change destination filenames using
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
94
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.
95
100
 
96
101
  **Ignore patterns**
97
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,139 +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
- # root_dir added in Python 3.10
62
- os.chdir(src)
63
- matches = glob.glob(incl_pattern.glob, recursive = True)
64
- finally:
65
- os.chdir(cwd)
66
-
67
- for match in matches:
68
- match = Path(match)
69
- basename = match.parent
70
- src_filename = match.name
71
-
72
- m = incl_pattern.rematch.fullmatch(src_filename)
73
- if not m:
74
- continue
75
-
76
- args = (m.group(0), *m.groups())
77
- kwargs = m.groupdict()
78
- try:
79
- dst_filename = incl_pattern.replace.format(*args, **kwargs)
80
- except (IndexError, KeyError) as e:
81
- raise ValueError(
82
- f"Replacement '{incl_pattern.replace}' failed for"
83
- f" '{incl_pattern.rematch.pattern}':"
84
- f" {args}, {kwargs}") from None
85
-
86
- _src = src/basename/src_filename
87
- # re-base the dst path, path relative to src == path relative to dst
88
- _dst = dst/basename/dst_filename
89
-
90
- yield (i, _src, _dst, _ignore_patterns, False)
91
-
92
-
93
- #===============================================================================
94
- def dist_copy(*,
95
- base_path,
96
- include,
97
- ignore,
98
- dist,
99
- root = None,
100
- logger = None ):
101
-
102
- if len(include) == 0:
103
- return
104
-
105
- logger = logger or logging.getLogger( __name__ )
106
-
107
- with validating(key = 'copy'):
108
-
109
- for i, src, dst, ignore_patterns, individual in dist_iter(
110
- include = include,
111
- ignore = ignore,
112
- root = root ):
113
-
114
- with validating(key = i):
115
-
116
- dst = base_path.joinpath(dst)
117
-
118
- if not individual and ignore_patterns( src.parent, [src.name]):
119
- logger.debug( f'ignoring: {src}' )
120
- continue
121
-
122
- src_abs = resolve(src)
123
-
124
- if root and not subdir(root, src_abs, check = False):
125
- raise FileOutsideRootError(
126
- f"Must have common path with root:\n file = \"{src_abs}\"\n root = \"{root}\"")
127
-
128
- logger.debug(f"dist copy: {src} -> {dst}")
129
-
130
- if src.is_dir():
131
- dist.copytree(
132
- src = src,
133
- dst = dst,
134
- ignore = ignore_patterns )
135
-
136
- else:
137
- dist.copyfile(
138
- src = src,
139
- dst = dst )
@@ -1,38 +0,0 @@
1
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/file.py,sha256=cU327vzXGfuMWlqY-LdfGqGs7LOhVd0MOUOIdAL5od4,1581
2
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/__init__.py,sha256=-CibR9jSfwRxNn4gHe-7_ZrQnH3FY4JYTi3Mz-Q66cU,1560
3
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/validate.py,sha256=FS-x15lErV6_y5WLOD2pv5j6jWsXXalA4xdYeazi140,32587
4
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/_legacy_setup.py,sha256=tAE0xlD9RVhhMn1kcUPSccbDFE1ReuH99jfrw8q8MiM,5301
5
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/norms.py,sha256=d6SkBBSST87smwD27YZ1lhicuw6rHdRQfXb_xnBsCGk,10990
6
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/cargo.py,sha256=z9yj7QNZqCV_hFRBOsBBWo1GgOWZF0Oqag0kLpfN-2I,1144
7
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/__init__.py,sha256=IRQk2gA5mK6BjewVHQ1IcVLVENV2vBMrwS4JO8wGPYc,164
8
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/meson.py,sha256=V39hN5bJ4kc9JBTXwT0XIc9uMtnKtrYczWC28jqu-GU,1939
9
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/process.py,sha256=8tUuFQrnks6Q-0G6Ow8G7LOycc2Z5olqLBzGhRCAulg,1002
10
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/download.py,sha256=RfDeAsGXMCAYct5REXroF7QwncQdrliYhMzm8ePxE94,4981
11
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/cmake.py,sha256=soKtbHkLttRq96NdLTD8dlD5SgzxrFYqJadC9V8HSjw,1915
12
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/builder/builder.py,sha256=pOIBUG5iEVsjh9SglIky41kgWLcAyHdEDAWzym2CM2g,11467
13
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/pyproj.py,sha256=Ra7DOj2Pq5peC_pT82xQoAxCDX3sHukpbKgNSqNeI8c,12758
14
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/pptoml.py,sha256=SCDMrpWAxJu0LSHVblsVfHW-htp-yUKdcUoWTbOkx3w,15025
15
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/legacy.py,sha256=JXSg-5Y65PUOtlEgkIgNj3vwZtJFi9CVsRvnpar2xKs,1749
16
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/template.py,sha256=1OmPPAEOLz0kquypFEb_c2aLysTGOwC2zqw1_eXYutY,6908
17
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/pkginfo.py,sha256=6rz06s19MX7zQIWt2wE-HEg-1WA2LZogk9kdqKFFcVE,15148
18
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/_nonprintable.py,sha256=2-JeNY6prFM4cfZKeFuv-aZW7ZvPI8FYO7dJ0CL3RD8,1893
19
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/pep.py,sha256=w00yyMmUr3JAhAUEDBZulNKpfOW2PiKDVmXKPlKcyGU,32880
20
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/load_module.py,sha256=6y3oMqCvycS4EhcOn1NtuXWyix0smCnogEH6W0bWiPg,4396
21
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/backend.py,sha256=BdbymqNlmxh-dr3bCCRpIB_T1JsSbfkHwSAcsfoHcPw,7011
22
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/path/__init__.py,sha256=458RSB1Lr63sY3CP_uqxaHkEUQMgeqZgNXFzpUIbsn4,236
23
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/path/utils.py,sha256=lJUyTGecZDMoTphSItr99_4b_yp_4zMRd8IAFiXgsI4,2364
24
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/path/match.py,sha256=zyeGJtVQ-gWLGx1NBlDhJ8cWa6mJyU0JBWFUdhz7yik,11812
25
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/path/pattern.py,sha256=d3SO_bencbojbf3zkvaR6bxzT83VFrMpI-wEfc26Qk0,16107
26
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/__init__.py,sha256=7SK7yeLehYJCbeHgnRFb4tPi2bEP2_ouA-qNxh_ofJI,379
27
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_targz.py,sha256=csb8NckhfScIUNY6LnQlUM31Jio69RwndBLuGD45Kls,3867
28
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_base.py,sha256=0LbWUitfuunpU0azUMD9xvapfn3_waUzZJVLwHxhD3E,11997
29
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_copy.py,sha256=G6_aBhn4bOmc4JbQdyGfIhXzGovxSIPnEfb0Y6PqS1o,3561
30
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_binary.py,sha256=COfEivLDvHk2ycX9xTSnNnIsc5EyXRTznaJPWOrx4Os,7749
31
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_source.py,sha256=_TzLbzLSn6TIwO98zwdvllkGCJgvr6BKnjNM-URKiCw,4362
32
- partis_pyproj-0.1.9.data/purelib/partis/pyproj/dist_file/dist_zip.py,sha256=ILAIz1myBgAR4xFRNgcJ1b2otcdUscyRViEbbArzL1M,3810
33
- partis_pyproj-0.1.9.dist-info/METADATA,sha256=GUtBY352NKQqKRYcbJhlpF0_Db52CvM91DAGJfb20Mc,22098
34
- partis_pyproj-0.1.9.dist-info/LICENSE.txt,sha256=6LYtpan0H8F0reCrEa1ZUf_Nr9Vu93A3bqunX2J5Et0,3320
35
- partis_pyproj-0.1.9.dist-info/top_level.txt,sha256=T72LF-bUK7nMDf1GQgbzvgZ2YrJElwwRd9h7HwVQBIQ,6
36
- partis_pyproj-0.1.9.dist-info/entry_points.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- partis_pyproj-0.1.9.dist-info/WHEEL,sha256=4YeLUbbRU8D0xzIlG3rm8IFLwHKcY8YaY_wiNxswKJg,126
38
- partis_pyproj-0.1.9.dist-info/RECORD,,