Skip to content

Commit f410468

Browse files
authored
Merge pull request #18 from dephell/fix-packaging
Support packaging 22.0
2 parents f18134a + 4d511e0 commit f410468

15 files changed

+231
-164
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ pip-wheel-metadata/
1212

1313
setup.py
1414
README.rst
15+
/.venvs/
16+
/.task/

.travis.yml

Lines changed: 0 additions & 37 deletions
This file was deleted.

Taskfile.yml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# https://taskfile.dev/
2+
version: "3"
3+
4+
vars:
5+
PYTHON: python3
6+
VENVS: .venvs
7+
TEST_ENV: .venvs/test
8+
LINT_ENV: .venvs/lint
9+
DOCS_ENV: .venvs/docs
10+
TEST_PYTHON: "{{.TEST_ENV}}/bin/python3"
11+
LINT_PYTHON: "{{.LINT_ENV}}/bin/python3"
12+
13+
env:
14+
FLIT_ROOT_INSTALL: "1"
15+
16+
tasks:
17+
install:flit:
18+
status:
19+
- which flit
20+
cmds:
21+
- python3 -m pip install flit
22+
venv:test:
23+
status:
24+
- test -d {{.TEST_ENV}}
25+
cmds:
26+
- "{{.PYTHON}} -m venv {{.TEST_ENV}}"
27+
venv:lint:
28+
status:
29+
- test -d {{.LINT_ENV}}
30+
cmds:
31+
- "{{.PYTHON}} -m venv {{.LINT_ENV}}"
32+
install:test:
33+
sources:
34+
- pyproject.toml
35+
deps:
36+
- install:flit
37+
- venv:test
38+
cmds:
39+
- >
40+
flit install
41+
--python {{.TEST_PYTHON}}
42+
--extras=test,integrations
43+
--deps=production
44+
--symlink
45+
install:lint:
46+
sources:
47+
- pyproject.toml
48+
deps:
49+
- install:flit
50+
- venv:lint
51+
cmds:
52+
- >
53+
flit install
54+
--python {{.LINT_PYTHON}}
55+
--extras=lint,integrations
56+
--deps=production
57+
--symlink
58+
59+
pytest:
60+
desc: "run Python tests"
61+
deps:
62+
- install:test
63+
cmds:
64+
- "{{.TEST_PYTHON}} -m pytest {{.CLI_ARGS}}"
65+
flake8:
66+
desc: "lint Python code"
67+
deps:
68+
- install:lint
69+
cmds:
70+
- "{{.LINT_PYTHON}} -m flake8 {{.CLI_ARGS}} ."
71+
mypy:
72+
desc: "check type annotations"
73+
deps:
74+
- install:lint
75+
cmds:
76+
- "{{.LINT_PYTHON}} -m mypy {{.CLI_ARGS}}"
77+
unify:
78+
desc: "convert double quotes to single ones"
79+
deps:
80+
- install:lint
81+
cmds:
82+
- "{{.LINT_PYTHON}} -m unify -r -i --quote=\\' {{.CLI_ARGS}} dephell_specifier tests"
83+
isort:
84+
desc: "sort imports"
85+
deps:
86+
- install:lint
87+
cmds:
88+
- "{{.LINT_PYTHON}} -m isort {{.CLI_ARGS}} ."
89+
isort:check:
90+
desc: "sort imports"
91+
deps:
92+
- install:lint
93+
cmds:
94+
- "{{.LINT_PYTHON}} -m isort --check {{.CLI_ARGS}} ."
95+
96+
# groups
97+
format:
98+
desc: "run all code formatters"
99+
cmds:
100+
- task: isort
101+
- task: unify
102+
lint:
103+
desc: "run all linters"
104+
cmds:
105+
- task: flake8
106+
- task: mypy
107+
- task: isort:check
108+
test:
109+
desc: "run all tests"
110+
cmds:
111+
- task: pytest
112+
all:
113+
desc: "run all code formatters, linters, and tests"
114+
cmds:
115+
- task: format
116+
- task: lint
117+
- task: test

dephell_specifier/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
"""A package to work with version specifiers.
2+
3+
Supports PEP-440, SemVer, Ruby, NPM, and Maven specifier formats.
4+
"""
5+
from __future__ import annotations
6+
17
from .git_specifier import GitSpecifier
28
from .range_specifier import RangeSpecifier
39
from .specifier import Specifier
410

511

12+
__version__ = '0.2.2'
613
__all__ = ['GitSpecifier', 'RangeSpecifier', 'Specifier']

dephell_specifier/constants.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# built-in
1+
from __future__ import annotations
2+
23
from enum import Enum, unique
34

45

dephell_specifier/git_specifier.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
from __future__ import annotations
2+
13

24
class GitSpecifier:
3-
def __contains__(self, release):
5+
def __contains__(self, release: object) -> bool:
46
# check that this is GitRelease without imports
57
return hasattr(release, 'commit')
68

dephell_specifier/range_specifier.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
from __future__ import annotations
2+
13
import re
2-
from typing import Set, List
4+
from typing import Iterable
35

4-
# external
56
from packaging.specifiers import InvalidSpecifier
6-
from packaging.version import LegacyVersion, parse, Version
7+
from packaging.version import Version, parse
78

8-
# app
9-
from .constants import PYTHONS, JoinTypes, OPERATOR_SYMBOLS
9+
from .constants import OPERATOR_SYMBOLS, PYTHONS, JoinTypes
1010
from .git_specifier import GitSpecifier
1111
from .specifier import Specifier
1212

@@ -16,8 +16,10 @@
1616

1717

1818
class RangeSpecifier:
19+
_specs: set
20+
join_type: JoinTypes
1921

20-
def __init__(self, spec=None):
22+
def __init__(self, spec: object | None = None) -> None:
2123
if not spec:
2224
self._specs = set()
2325
self.join_type = JoinTypes.AND
@@ -42,7 +44,7 @@ def __init__(self, spec=None):
4244
return
4345

4446
@classmethod
45-
def _parse(cls, spec) -> Set[Specifier]:
47+
def _parse(cls, spec: object) -> set[Specifier]:
4648
spec = cls._split_specifier(spec)
4749
result = set()
4850
for constr in spec:
@@ -74,7 +76,7 @@ def _parse(cls, spec) -> Set[Specifier]:
7476
return result
7577

7678
@staticmethod
77-
def _split_specifier(spec) -> List[str]:
79+
def _split_specifier(spec: object) -> list[str]:
7880
if isinstance(spec, (list, tuple)):
7981
return list(spec)
8082
spec = str(spec)
@@ -120,11 +122,11 @@ def _parse_star_and_operator(constr: str) -> Specifier:
120122
return Specifier(constr.replace('.*', '.0'))
121123

122124
version = parse(constr.lstrip(OPERATOR_SYMBOLS).rstrip('.*'))
123-
parts = version.release[:-1] + (version.release[-1] + 1, ) # type: ignore
125+
parts = version.release[:-1] + (version.release[-1] + 1, )
124126
return Specifier(constr[:2] + '.'.join(map(str, parts)))
125127

126128
@staticmethod
127-
def _parse_maven(constr: str) -> Set[Specifier]:
129+
def _parse_maven(constr: str) -> set[Specifier]:
128130
if constr in '[]()':
129131
return set()
130132
if constr[0] == '[' and constr[-1] == ']':
@@ -140,10 +142,8 @@ def _parse_maven(constr: str) -> Set[Specifier]:
140142
raise ValueError('non maven constraint: {}'.format(constr))
141143

142144
@staticmethod
143-
def _parse_npm(constr: str) -> Set[Specifier]:
145+
def _parse_npm(constr: str) -> set[Specifier]:
144146
version = parse(constr.lstrip(OPERATOR_SYMBOLS).replace('.*', '.0'))
145-
if isinstance(version, LegacyVersion):
146-
raise InvalidSpecifier(constr)
147147
parts = version.release + (0, 0)
148148
parts = tuple(map(str, parts))
149149

@@ -171,7 +171,7 @@ def _parse_npm(constr: str) -> Set[Specifier]:
171171
left += '.' + ''.join(map(str, version.pre))
172172
return {Specifier('>=' + left), Specifier('==' + right)}
173173

174-
def attach_time(self, releases) -> bool:
174+
def attach_time(self, releases: Iterable) -> bool:
175175
"""Attach time to all specifiers if possible
176176
"""
177177
ok = False
@@ -191,13 +191,13 @@ def to_marker(self, name: str, *, wrap: bool = False) -> str:
191191
marker = '(' + marker + ')'
192192
return marker
193193

194-
def copy(self) -> 'RangeSpecifier':
194+
def copy(self) -> RangeSpecifier:
195195
new = type(self)()
196196
new._specs = self._specs.copy()
197197
new.join_type = self.join_type
198198
return new
199199

200-
def peppify(self) -> 'RangeSpecifier':
200+
def peppify(self) -> RangeSpecifier:
201201
"""Returns python specifier without `||`
202202
"""
203203
if self.join_type == JoinTypes.AND:
@@ -220,7 +220,7 @@ def peppify(self) -> 'RangeSpecifier':
220220
elif left is None or python > left:
221221
excluded.append(python)
222222
if right is not None:
223-
right = (pythons + [None])[pythons.index(right) + 1] # type: ignore
223+
right = (pythons + [None])[pythons.index(right) + 1]
224224

225225
# get excluded intervals
226226
if right is not None:
@@ -249,27 +249,27 @@ def python_compat(self) -> bool:
249249

250250
# magic methods
251251

252-
def __add__(self, other):
252+
def __add__(self, other: object) -> RangeSpecifier:
253253
new = self.copy()
254254
attached = new._attach(other)
255255
if attached:
256256
return new
257257
return NotImplemented
258258

259-
def __radd__(self, other):
259+
def __radd__(self, other: object) -> RangeSpecifier:
260260
new = self.copy()
261261
attached = new._attach(other)
262262
if attached:
263263
return new
264264
return NotImplemented
265265

266-
def __iadd__(self, other):
266+
def __iadd__(self, other: object) -> RangeSpecifier:
267267
attached = self._attach(other)
268268
if attached:
269269
return self
270270
return NotImplemented
271271

272-
def _attach(self, other) -> bool:
272+
def _attach(self, other: object) -> bool:
273273
if isinstance(other, GitSpecifier):
274274
self._specs.add(other)
275275
return True
@@ -318,34 +318,34 @@ def _attach(self, other) -> bool:
318318
self._specs = new_specs
319319
return True
320320

321-
def __contains__(self, release) -> bool:
321+
def __contains__(self, release: object) -> bool:
322322
rule = all if self.join_type == JoinTypes.AND else any
323323
return rule((release in specifier) for specifier in self._specs)
324324

325-
def __str__(self):
325+
def __str__(self) -> str:
326326
if not self._specs:
327327
return ''
328328
sep = ',' if self.join_type == JoinTypes.AND else ' || '
329329
return sep.join(sorted(map(str, self._specs)))
330330

331-
def __repr__(self):
331+
def __repr__(self) -> str:
332332
return '{name}({spec})'.format(
333333
name=self.__class__.__name__,
334334
spec=str(self),
335335
)
336336

337-
def __bool__(self):
337+
def __bool__(self) -> bool:
338338
return bool(self._specs)
339339

340-
def __lt__(self, other):
340+
def __lt__(self, other: object) -> bool:
341341
if not isinstance(other, type(self)):
342342
return False
343343
return str(self) < str(other)
344344

345-
def __eq__(self, other):
345+
def __eq__(self, other: object) -> bool:
346346
if not isinstance(other, type(self)):
347347
return False
348348
return str(self) == str(other)
349349

350-
def __hash__(self):
350+
def __hash__(self) -> int:
351351
return hash(str(self))

0 commit comments

Comments
 (0)