From 008d2a65e9013642427e62454bf433697fb07f29 Mon Sep 17 00:00:00 2001 From: Ivan Ogasawara Date: Wed, 29 Apr 2026 03:19:34 +0000 Subject: [PATCH] fix: Fix the config dependencies format --- docs/getting-started.md | 8 +++++++ packages/arx/src/arx/schema/arxproject.json | 3 +-- packages/arx/src/arx/settings.py | 19 ++++++++-------- packages/arx/tests/python/test_settings.py | 25 +++++++++++++++++++-- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index b3048a3..2c21cc6 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -249,6 +249,9 @@ Example project manifest: name = "geometry" version = "0.1.0" requires-arx = ">=1.0" +dependencies = [ + "sciarx>=0.0.3,<1", +] [environment] kind = "conda" @@ -269,6 +272,11 @@ for example `">=1.0,<2"`. `[build-system].dependencies` declares installable packages needed to build the project. If omitted, Arx defaults to `arxlang`; if `requires-arx` is present, the default build dependency uses that constraint. +Use `[project].dependencies` to declare runtime Arx package dependencies. +Entries use standard dependency requirement strings, so packages may be +unconstrained (`"sciarx"`), version constrained (`"sciarx>=0.0.3,<1"`), or +direct references (`"sciarx @ ../sciarx"`). + Use `__init__.x` as the package root. Arx uses `src/` as the default source root when `[build].src_dir` is omitted. Inside a nested module such as `geometry.shapes.area`, use relative `from` imports for nearby modules and diff --git a/packages/arx/src/arx/schema/arxproject.json b/packages/arx/src/arx/schema/arxproject.json index 3042919..33c0910 100644 --- a/packages/arx/src/arx/schema/arxproject.json +++ b/packages/arx/src/arx/schema/arxproject.json @@ -22,8 +22,7 @@ }, "dependency": { "type": "string", - "minLength": 1, - "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*( @ \\S+)?$" + "minLength": 1 }, "dependency_group_name": { "type": "string", diff --git a/packages/arx/src/arx/settings.py b/packages/arx/src/arx/settings.py index 7a5af1b..44db5fb 100644 --- a/packages/arx/src/arx/settings.py +++ b/packages/arx/src/arx/settings.py @@ -25,9 +25,6 @@ import tomli as tomllib DEFAULT_CONFIG_FILENAME = ".arxproject.toml" -_DEPENDENCY_PATTERN = re.compile( - r"^(?P[A-Za-z0-9][A-Za-z0-9._-]*)(?: @ (?P\S+))?$" -) _DEPENDENCY_GROUP_NAME_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]*$") _DEPENDENCY_GROUP_NORMALIZE_PATTERN = re.compile(r"[-_.]+") _DEFAULT_SRC_DIR = "src" @@ -501,7 +498,7 @@ def _reject_arxpm_sections(data: dict[str, Any]) -> None: raise ArxProjectError( ".arxproject.toml does not support [arxpm] sections. " "Declare dependencies in [project] using " - 'dependencies = ["name", "name @ ../path"].' + 'dependencies = ["name", "name>=1.0,<2", "name @ ../path"].' ) @@ -530,12 +527,14 @@ def _validate_dependency(value: str, location: str) -> None: location: type: str """ - if _DEPENDENCY_PATTERN.fullmatch(value) is not None: - return - raise ArxProjectError( - f".arxproject.toml {location} must be either a package name " - 'like "http" or a direct reference like "mylib @ ../mylib".' - ) + try: + Requirement(value) + except InvalidRequirement as err: + raise ArxProjectError( + f".arxproject.toml {location} must be a valid dependency " + 'requirement like "http", "sciarx>=0.0.3,<1", or ' + '"mylib @ ../mylib".' + ) from err def _validate_project(data: dict[str, Any]) -> None: diff --git a/packages/arx/tests/python/test_settings.py b/packages/arx/tests/python/test_settings.py index bbf98e6..d65a660 100644 --- a/packages/arx/tests/python/test_settings.py +++ b/packages/arx/tests/python/test_settings.py @@ -38,6 +38,7 @@ edition = "2026" dependencies = [ "http", + "sciarx-utils>=0.0.3,<1", "mylib @ ../mylib", ] authors = [ @@ -92,6 +93,7 @@ def test_load_settings_from_text_full_example() -> None: assert settings.project.edition == "2026" assert settings.project.dependencies == ( "http", + "sciarx-utils>=0.0.3,<1", "mylib @ ../mylib", ) assert settings.project.authors[0].name == "Ivan Ogasawara" @@ -278,10 +280,13 @@ def test_build_system_dependencies_reject_invalid_requirement() -> None: "dependency", [ "http", + "sciarx>=0.0.3", + "sciarx>=0.0.3,<1", + "sciarx==0.0.3", "mylib @ ../mylib", "utils @ git+https://example.com/utils.git", ], - ids=["registry", "path", "git"], + ids=["registry", "lower-bound", "bounded", "exact", "path", "git"], ) def test_project_dependencies_support_canonical_strings( dependency: str, @@ -299,6 +304,19 @@ def test_project_dependencies_support_canonical_strings( assert settings.dependency_groups == {} +def test_project_dependencies_reject_invalid_requirements() -> None: + """ + title: Reject invalid requirement strings in runtime dependencies. + """ + content = _project_toml('dependencies = ["bad dep @"]\n') + + with pytest.raises( + ArxProjectError, + match=r"project\.dependencies\[0\]", + ): + load_settings_from_text(content) + + def test_dependency_groups_with_plain_string_entries_parse() -> None: """ title: Parse non-runtime dependency groups from top-level settings. @@ -388,7 +406,10 @@ def test_dependency_group_entries_reuse_dependency_string_rules() -> None: """ ).lstrip() - with pytest.raises(ArxProjectError, match="schema validation"): + with pytest.raises( + ArxProjectError, + match=r"dependency-groups\.dev\[0\]", + ): load_settings_from_text(content)