oaknut-basic 12.16.0__tar.gz → 12.17.1__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 (43) hide show
  1. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/PKG-INFO +8 -7
  2. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/README.md +4 -4
  3. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/pyproject.toml +16 -10
  4. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/__init__.py +1 -1
  5. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut_basic.egg-info/PKG-INFO +8 -7
  6. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut_basic.egg-info/SOURCES.txt +1 -0
  7. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut_basic.egg-info/requires.txt +2 -2
  8. oaknut_basic-12.17.1/tests/test_packaging.py +58 -0
  9. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/LICENSE +0 -0
  10. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/setup.cfg +0 -0
  11. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/cli.py +0 -0
  12. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/datafile.py +0 -0
  13. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/detect.py +0 -0
  14. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/detokeniser.py +0 -0
  15. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/dialect.py +0 -0
  16. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/exceptions.py +0 -0
  17. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/float5.py +0 -0
  18. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/linenumber.py +0 -0
  19. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/numbering.py +0 -0
  20. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/scanner.py +0 -0
  21. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/tokeniser.py +0 -0
  22. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut/basic/tokens.py +0 -0
  23. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut_basic.egg-info/dependency_links.txt +0 -0
  24. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut_basic.egg-info/entry_points.txt +0 -0
  25. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/src/oaknut_basic.egg-info/top_level.txt +0 -0
  26. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_basic.py +0 -0
  27. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_basic_v.py +0 -0
  28. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_cli.py +0 -0
  29. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_crunch_rules.py +0 -0
  30. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_data_cli.py +0 -0
  31. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_datafile.py +0 -0
  32. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_detect.py +0 -0
  33. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_detokeniser.py +0 -0
  34. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_float5.py +0 -0
  35. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_greedy_crunch.py +0 -0
  36. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_keyword_coverage.py +0 -0
  37. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_linenumber.py +0 -0
  38. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_numbering.py +0 -0
  39. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_rom_golden.py +0 -0
  40. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_rom_golden_detokenise.py +0 -0
  41. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_scanner.py +0 -0
  42. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_tokeniser.py +0 -0
  43. {oaknut_basic-12.16.0 → oaknut_basic-12.17.1}/tests/test_tokens.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oaknut-basic
3
- Version: 12.16.0
3
+ Version: 12.17.1
4
4
  Summary: BBC BASIC tools: program tokeniser/de-tokeniser and PRINT#/INPUT# data-file reader/writer
5
5
  Author-email: Robert Smallshire <robert@smallshire.org.uk>
6
6
  License-Expression: MIT
@@ -17,8 +17,9 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: oaknut-exception>=10.0
19
19
  Requires-Dist: oaknut-codecs>=12.7
20
- Provides-Extra: cli
21
- Requires-Dist: oaknut-cli>=10.0; extra == "cli"
20
+ Requires-Dist: click>=8.1.7
21
+ Requires-Dist: asyoulikeit>=1.5.1
22
+ Requires-Dist: oaknut-cli>=10.0
22
23
  Dynamic: license-file
23
24
 
24
25
  <p align="center">
@@ -67,12 +68,12 @@ and a data file round-trips through Python values **byte-for-byte**.
67
68
 
68
69
  ## Installation
69
70
 
70
- Install with the `[cli]` extra for the `oaknut-basic` command, or bare for the
71
- library only:
71
+ Install as a tool for the `oaknut-basic` command, or add it to a project for
72
+ the library:
72
73
 
73
74
  ```
74
- uv tool install "oaknut-basic[cli]" # the command-line tool
75
- uv add oaknut-basic # the importable library
75
+ uv tool install oaknut-basic # the command-line tool
76
+ uv add oaknut-basic # the importable library
76
77
  ```
77
78
 
78
79
  `pip` works identically with the same names. `oaknut-basic` requires Python
@@ -44,12 +44,12 @@ and a data file round-trips through Python values **byte-for-byte**.
44
44
 
45
45
  ## Installation
46
46
 
47
- Install with the `[cli]` extra for the `oaknut-basic` command, or bare for the
48
- library only:
47
+ Install as a tool for the `oaknut-basic` command, or add it to a project for
48
+ the library:
49
49
 
50
50
  ```
51
- uv tool install "oaknut-basic[cli]" # the command-line tool
52
- uv add oaknut-basic # the importable library
51
+ uv tool install oaknut-basic # the command-line tool
52
+ uv add oaknut-basic # the importable library
53
53
  ```
54
54
 
55
55
  `pip` works identically with the same names. `oaknut-basic` requires Python
@@ -20,16 +20,22 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.12",
21
21
  "Programming Language :: Python :: 3.13",
22
22
  ]
23
- # The tokeniser and de-tokeniser raise categorised errors from the shared
24
- # oaknut-exception hierarchy, so the CLI boundary can render them without a
25
- # traceback. That is the package's only runtime dependency.
26
- dependencies = ["oaknut-exception>=10.0", "oaknut-codecs>=12.7"]
27
-
28
- # The `cli` extra pulls the shared CLI toolkit (Click, asyoulikeit, the
29
- # Acorn text codec and the categorised-error boundary) so this package
30
- # can offer the standalone `oaknut-basic` command.
31
- [project.optional-dependencies]
32
- cli = ["oaknut-cli>=10.0"]
23
+ # This package ships the standalone `oaknut-basic` console script (see
24
+ # [project.scripts] below), and that script's module imports Click,
25
+ # asyoulikeit and oaknut.cli at load time. A console script is installed
26
+ # unconditionally, so those must be unconditional dependencies too
27
+ # otherwise `pip install oaknut-basic` / `uvx oaknut-basic` yields an
28
+ # executable that dies with ModuleNotFoundError before it runs. The
29
+ # tokeniser and de-tokeniser also raise categorised errors from the
30
+ # shared oaknut-exception hierarchy so the CLI boundary can render them
31
+ # without a traceback.
32
+ dependencies = [
33
+ "oaknut-exception>=10.0",
34
+ "oaknut-codecs>=12.7",
35
+ "click>=8.1.7",
36
+ "asyoulikeit>=1.5.1",
37
+ "oaknut-cli>=10.0",
38
+ ]
33
39
 
34
40
  [project.scripts]
35
41
  oaknut-basic = "oaknut.basic.cli:cli"
@@ -81,7 +81,7 @@ from oaknut.basic.tokens import (
81
81
  TOKEN_TO_KEYWORD,
82
82
  )
83
83
 
84
- __version__ = "12.16.0"
84
+ __version__ = "12.17.1"
85
85
 
86
86
  # Canonical load addresses for BBC BASIC programs on each host.
87
87
  # Programs saved by *SAVE on a real machine use these by default.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oaknut-basic
3
- Version: 12.16.0
3
+ Version: 12.17.1
4
4
  Summary: BBC BASIC tools: program tokeniser/de-tokeniser and PRINT#/INPUT# data-file reader/writer
5
5
  Author-email: Robert Smallshire <robert@smallshire.org.uk>
6
6
  License-Expression: MIT
@@ -17,8 +17,9 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: oaknut-exception>=10.0
19
19
  Requires-Dist: oaknut-codecs>=12.7
20
- Provides-Extra: cli
21
- Requires-Dist: oaknut-cli>=10.0; extra == "cli"
20
+ Requires-Dist: click>=8.1.7
21
+ Requires-Dist: asyoulikeit>=1.5.1
22
+ Requires-Dist: oaknut-cli>=10.0
22
23
  Dynamic: license-file
23
24
 
24
25
  <p align="center">
@@ -67,12 +68,12 @@ and a data file round-trips through Python values **byte-for-byte**.
67
68
 
68
69
  ## Installation
69
70
 
70
- Install with the `[cli]` extra for the `oaknut-basic` command, or bare for the
71
- library only:
71
+ Install as a tool for the `oaknut-basic` command, or add it to a project for
72
+ the library:
72
73
 
73
74
  ```
74
- uv tool install "oaknut-basic[cli]" # the command-line tool
75
- uv add oaknut-basic # the importable library
75
+ uv tool install oaknut-basic # the command-line tool
76
+ uv add oaknut-basic # the importable library
76
77
  ```
77
78
 
78
79
  `pip` works identically with the same names. `oaknut-basic` requires Python
@@ -33,6 +33,7 @@ tests/test_greedy_crunch.py
33
33
  tests/test_keyword_coverage.py
34
34
  tests/test_linenumber.py
35
35
  tests/test_numbering.py
36
+ tests/test_packaging.py
36
37
  tests/test_rom_golden.py
37
38
  tests/test_rom_golden_detokenise.py
38
39
  tests/test_scanner.py
@@ -1,5 +1,5 @@
1
1
  oaknut-exception>=10.0
2
2
  oaknut-codecs>=12.7
3
-
4
- [cli]
3
+ click>=8.1.7
4
+ asyoulikeit>=1.5.1
5
5
  oaknut-cli>=10.0
@@ -0,0 +1,58 @@
1
+ """Packaging-metadata guards for the standalone ``oaknut-basic`` command.
2
+
3
+ Unlike the filesystem plugin packages (``oaknut-dfs``/``oaknut-adfs`` …),
4
+ which only contribute ``disc`` subcommands via entry points and ship no
5
+ console script of their own, ``oaknut-basic`` declares its own
6
+ ``[project.scripts]`` entry point. A console script that is always
7
+ installed must have everything it imports as an *unconditional* runtime
8
+ dependency, otherwise ``pip install oaknut-basic`` / ``uvx oaknut-basic``
9
+ produces an executable that dies with ``ModuleNotFoundError`` at import
10
+ (see issue #49).
11
+ """
12
+
13
+ from importlib.metadata import entry_points, requires
14
+
15
+ _DISTRIBUTION = "oaknut-basic"
16
+
17
+ # Everything oaknut/basic/cli.py imports at module load, mapped to the
18
+ # distribution that supplies it.
19
+ _CLI_REQUIREMENTS = ("oaknut-cli", "click", "asyoulikeit")
20
+
21
+
22
+ def _unconditional_requirements():
23
+ """Distribution names required without an ``extra ==`` marker."""
24
+ names = set()
25
+ for requirement in requires(_DISTRIBUTION) or []:
26
+ # "oaknut-cli>=10.0; extra == 'cli'" -> skip; extras are optional.
27
+ spec, _, marker = requirement.partition(";")
28
+ if "extra" in marker:
29
+ continue
30
+ name = (
31
+ spec.strip()
32
+ .split("[")[0]
33
+ .split("<")[0]
34
+ .split(">")[0]
35
+ .split("=")[0]
36
+ .split("!")[0]
37
+ .split("~")[0]
38
+ .strip()
39
+ )
40
+ names.add(name.lower())
41
+ return names
42
+
43
+
44
+ def test_console_script_is_declared():
45
+ scripts = entry_points(group="console_scripts")
46
+ assert any(ep.name == "oaknut-basic" for ep in scripts)
47
+
48
+
49
+ def test_cli_dependencies_are_unconditional():
50
+ unconditional = _unconditional_requirements()
51
+ missing = [
52
+ name for name in _CLI_REQUIREMENTS if name.lower() not in unconditional
53
+ ]
54
+ assert not missing, (
55
+ f"{_DISTRIBUTION} ships a console script but these imports of "
56
+ f"oaknut.basic.cli are not unconditional dependencies: {missing}. "
57
+ "Promote them out of the [cli] extra into [project.dependencies]."
58
+ )
File without changes
File without changes