Skip to content

Commit 2f7c82d

Browse files
committed
fix: add format for import-name
Signed-off-by: Henry Schreiner <[email protected]>
1 parent 654b4f9 commit 2f7c82d

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/validate_pyproject/formats.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"""
99

1010
import builtins
11+
import keyword
1112
import logging
1213
import os
1314
import re
@@ -400,3 +401,27 @@ def SPDX(value: str) -> bool:
400401

401402
def SPDX(value: str) -> bool:
402403
return True
404+
405+
406+
VALID_IMPORT_NAME = re.compile(
407+
r"""
408+
^ # start of string
409+
[A-Za-z_][A-Za-z_0-9]+ # a valid Python identifier
410+
(?:\.[A-Za-z_][A-Za-z_0-9]*)* # optionally followed by .identifier's
411+
(?:\s*;\s*private)? # optionally followed by ; private
412+
$ # end of string
413+
""",
414+
re.VERBOSE,
415+
)
416+
417+
418+
def import_name(value: str) -> bool:
419+
"""This is a valid import name. It has to be series of python identifiers
420+
(not keywords), separated by dots, optionally followed by a semicolon and
421+
the keyword "private".
422+
"""
423+
if VALID_IMPORT_NAME.match(value) is None:
424+
return False
425+
426+
idents, _, _ = value.partition(";")
427+
return all(not keyword.iskeyword(ident) for ident in idents.rstrip().split("."))

src/validate_pyproject/project_metadata.schema.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,16 @@
237237
"description": "Lists import names which a project, when installed, would exclusively provide.",
238238
"type": "array",
239239
"items": {
240-
"type": "string"
240+
"type": "string",
241+
"format": "import-name"
241242
}
242243
},
243244
"import-namespaces": {
244245
"description": "Lists import names that, when installed, would be provided by the project, but not exclusively.",
245246
"type": "array",
246247
"items": {
247-
"type": "string"
248+
"type": "string",
249+
"format": "import-name"
248250
}
249251
},
250252
"dynamic": {

tests/test_formats.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,16 @@ def _failed_download():
455455
def test_private_classifier():
456456
assert formats.trove_classifier("private :: Keep Off PyPI") is True
457457
assert formats.trove_classifier("private:: Keep Off PyPI") is False
458+
459+
460+
def test_import_name():
461+
assert formats.import_name("simple")
462+
assert formats.import_name("some1; private")
463+
assert formats.import_name("other.thing ; private")
464+
assert formats.import_name("_other._thing ; private")
465+
466+
assert not formats.import_name("one two")
467+
assert not formats.import_name("one; two")
468+
assert not formats.import_name("1thing")
469+
assert not formats.import_name("for")
470+
assert not formats.import_name("thing.is.keyword")

0 commit comments

Comments
 (0)