partis-pyproj 0.1.7__tar.gz → 0.1.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/PKG-INFO +6 -5
  2. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/pyproject.toml +5 -1
  3. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/backend.py +22 -19
  4. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/cmake.py +2 -2
  5. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/dist_copy.py +1 -0
  6. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/norms.py +5 -3
  7. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/pep.py +9 -5
  8. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/pptoml.py +44 -1
  9. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/pyproj.py +1 -0
  10. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/validate.py +49 -31
  11. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/LICENSE.txt +0 -0
  12. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/README.md +0 -0
  13. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/__init__.py +0 -0
  14. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/_legacy_setup.py +0 -0
  15. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/_nonprintable.py +0 -0
  16. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/__init__.py +0 -0
  17. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/builder.py +0 -0
  18. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/cargo.py +0 -0
  19. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/download.py +0 -0
  20. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/meson.py +0 -0
  21. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/builder/process.py +0 -0
  22. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/__init__.py +0 -0
  23. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/dist_base.py +0 -0
  24. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/dist_binary.py +0 -0
  25. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/dist_source.py +0 -0
  26. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/dist_targz.py +0 -0
  27. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/dist_file/dist_zip.py +0 -0
  28. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/file.py +0 -0
  29. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/legacy.py +0 -0
  30. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/load_module.py +0 -0
  31. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/path/__init__.py +0 -0
  32. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/path/match.py +0 -0
  33. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/path/pattern.py +0 -0
  34. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/path/utils.py +0 -0
  35. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/pkginfo.py +0 -0
  36. {partis_pyproj-0.1.7 → partis_pyproj-0.1.9}/src/pyproj/template.py +0 -0
@@ -1,24 +1,25 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: partis-pyproj
3
- Version: 0.1.7
3
+ Version: 0.1.9
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
- Classifier: Development Status :: 4 - Beta
10
- Classifier: Operating System :: POSIX :: Linux
11
- Classifier: Topic :: Software Development :: Build Tools
9
+ Project-URL: homepage, https://github.com/kcdodd/partis-pyproj/
12
10
  Classifier: License :: OSI Approved :: BSD License
13
11
  Classifier: Operating System :: Microsoft :: Windows
14
12
  Classifier: Intended Audience :: Developers
15
13
  Classifier: Programming Language :: Python
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Topic :: Software Development :: Build Tools
16
16
  Classifier: Programming Language :: Python :: 3
17
+ Classifier: Operating System :: POSIX :: Linux
17
18
  Provides-Extra: meson
18
19
  Provides-Extra: cmake
19
20
  Requires-Dist: packaging>=24.2
20
- Requires-Dist: requests>=2.32.3
21
21
  Requires-Dist: tomli>=2.0.1
22
+ Requires-Dist: requests>=2.32.3
22
23
  Requires-Dist: meson>=0.61.3; extra == "meson"
23
24
  Requires-Dist: ninja>=1.10.2.3; extra == "meson"
24
25
  Requires-Dist: ninja>=1.10.2.3; extra == "cmake"
@@ -26,7 +26,7 @@
26
26
 
27
27
  [project]
28
28
  name = "partis-pyproj"
29
- version = "0.1.7"
29
+ version = "0.1.9"
30
30
  description = "Minimal set of Python project utilities (PEP-517/621)"
31
31
  maintainers = [
32
32
  { name = "Nanohmics Inc.", email = "software.support@nanohmics.com" } ]
@@ -64,6 +64,10 @@ cmake = [
64
64
  name = "Nanohmics Inc."
65
65
  email = "software.support@nanohmics.com"
66
66
 
67
+ #===============================================================================
68
+ [project.urls]
69
+ homepage = "https://github.com/kcdodd/partis-pyproj/"
70
+
67
71
  #===============================================================================
68
72
  # Build and distribution configuration
69
73
  #===============================================================================
@@ -1,8 +1,6 @@
1
1
  from __future__ import annotations
2
2
  import os
3
- import os.path as osp
4
- import sys
5
- import shutil
3
+ from copy import copy
6
4
  import logging
7
5
  from logging import (
8
6
  basicConfig,
@@ -22,6 +20,7 @@ from collections.abc import (
22
20
 
23
21
  from . import (
24
22
  valid_keys,
23
+ ValidationError,
25
24
  mapget,
26
25
  dist_build,
27
26
  PkgInfoReq,
@@ -34,7 +33,7 @@ def backend_init(
34
33
  root: str|Path = '',
35
34
  config_settings: dict|None = None,
36
35
  logger: Logger|None = None ):
37
- """Called to inialialize the backend upon a call to one of the hooks
36
+ """Called to initialize the backend upon a call to one of the hooks
38
37
 
39
38
  Parameters
40
39
  ----------
@@ -210,26 +209,30 @@ def build_wheel(
210
209
  * https://www.python.org/dev/peps/pep-0517/#build-wheel
211
210
  """
212
211
 
213
- pyproj = backend_init(config_settings = config_settings)
212
+ try:
213
+ pyproj = backend_init(config_settings = config_settings)
214
214
 
215
- pyproj.dist_prep()
215
+ pyproj.dist_prep()
216
+ pyproj.dist_binary_prep()
216
217
 
217
- pyproj.dist_binary_prep()
218
+ with dist_binary_wheel(
219
+ pkg_info = pyproj.pkg_info,
220
+ build = dist_build(
221
+ pyproj.binary.get('build_number', None),
222
+ pyproj.binary.get('build_suffix', None) ),
223
+ compat = pyproj.binary.compat_tags,
224
+ outdir = wheel_directory,
225
+ logger = pyproj.logger ) as dist:
218
226
 
219
- with dist_binary_wheel(
220
- pkg_info = pyproj.pkg_info,
221
- build = dist_build(
222
- pyproj.binary.get('build_number', None),
223
- pyproj.binary.get('build_suffix', None) ),
224
- compat = pyproj.binary.compat_tags,
225
- outdir = wheel_directory,
226
- logger = pyproj.logger ) as dist:
227
+ pyproj.dist_binary_copy(
228
+ dist = dist )
227
229
 
228
- pyproj.dist_binary_copy(
229
- dist = dist )
230
+ pyproj.logger.info(
231
+ f"Top level packages {dist.top_level}")
230
232
 
231
- pyproj.logger.info(
232
- f"Top level packages {dist.top_level}")
233
+ except ValidationError as e:
234
+ known_exception_type = copy(e)
235
+ raise known_exception_type from e.__cause__
233
236
 
234
237
  return dist.outname
235
238
 
@@ -70,9 +70,9 @@ def cmake(
70
70
 
71
71
  compile_args = [
72
72
  'cmake',
73
- *compile_args,
74
73
  '--build',
75
- str(build_dir) ]
74
+ str(build_dir),
75
+ *compile_args]
76
76
 
77
77
  install_args = [
78
78
  'cmake',
@@ -58,6 +58,7 @@ def dist_iter(*,
58
58
  cwd = Path.cwd()
59
59
  try:
60
60
  # TODO: better way of globing *relative* to src directory
61
+ # root_dir added in Python 3.10
61
62
  os.chdir(src)
62
63
  matches = glob.glob(incl_pattern.glob, recursive = True)
63
64
  finally:
@@ -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 witdth of encoded number
401
+ Minimal width of encoded number
400
402
  base : int
401
403
  Numeric base used to encode number
402
404
  """
@@ -26,6 +26,7 @@ import keyword
26
26
  from packaging.tags import sys_tags
27
27
  from packaging.requirements import Requirement
28
28
  from packaging.specifiers import SpecifierSet
29
+ from packaging.version import VERSION_PATTERN
29
30
 
30
31
  from .validate import (
31
32
  ValidationError,
@@ -164,12 +165,14 @@ def norm_dist_filename( name ):
164
165
  Each component of the filename is escaped by replacing runs of
165
166
  non-alphanumeric characters with an underscore '_'
166
167
 
168
+ Addendum - It seems that "local" versions require '+'
169
+
167
170
  See Also
168
171
  --------
169
172
  * https://www.python.org/dev/peps/pep-0427/#file-name-convention
170
173
  """
171
174
 
172
- return re.sub( r"[^\w\d\.]+", "_", name )
175
+ return re.sub( r"[^\w\d\.\+]+", "_", name )
173
176
 
174
177
  #===============================================================================
175
178
  def join_dist_filename( parts ):
@@ -639,10 +642,11 @@ pep426_dist_name = re.compile(
639
642
  r'^([A-Z0-9]|[A-Z0-9][A-Z0-9._\-]*[A-Z0-9])$',
640
643
  re.IGNORECASE )
641
644
 
642
- pep440_version = re.compile(
643
- r'^([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*'
644
- r'((a|b|rc)(0|[1-9][0-9]*))?'
645
- r'(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$' )
645
+ 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]*))?$' )
646
650
 
647
651
  # NOTE: PEP 427 does not specify any constraints on the string following the
648
652
  # digits, but given the form it is used in the filenames it really cannot
@@ -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,7 +360,7 @@ 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
365
  'replace': valid('{0}', nonempty_str)}
323
366
 
@@ -235,6 +235,7 @@ class PyProjBase:
235
235
  meson.pop('entry')
236
236
  meson.pop('work_dir')
237
237
  meson.pop('env')
238
+ meson.pop('exclusive')
238
239
  meson['compile'] = meson.pop('enabled')
239
240
  return pyproj_meson(meson)
240
241
 
@@ -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
- validator = valid(
824
- validator or (lambda v: v),
825
- partial(valid_keys,
826
- key_valid = key_valid,
827
- value_valid = value_valid,
828
- item_valid = item_valid,
829
- allow_keys = allow_keys,
830
- require_keys = require_keys,
831
- min_keys = min_keys,
832
- wedge_keys = wedge_keys,
833
- mutex_keys = mutex_keys,
834
- deprecate_keys = deprecate_keys,
835
- forbid_keys = forbid_keys,
836
- default = default,
837
- proxy_keys = proxy_keys))
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 self._as_list:
1053
- vals = self._as_list(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
- for i,v in enumerate(vals):
1056
- with validating(key = i):
1057
- vals[i] = self.value_valid(v)
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
- with validating(key = len(self)):
1076
- val = self.value_valid(val)
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
- for i,v in enumerate(vals):
1085
- with validating(key = len(self) + i):
1086
- vals[i] = self.value_valid(v)
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
- with validating(key = key):
1093
- val = self.value_valid(val)
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
 
File without changes
File without changes