simplibs-extractor-python 0.1.0__py3-none-any.whl

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 (71) hide show
  1. simplibs/extractor_python/__init__.py +67 -0
  2. simplibs/extractor_python/actions/PythonOutline.py +23 -0
  3. simplibs/extractor_python/actions/RemovePythonComments.py +22 -0
  4. simplibs/extractor_python/actions/RemovePythonDecorators.py +22 -0
  5. simplibs/extractor_python/actions/RemovePythonDocstrings.py +22 -0
  6. simplibs/extractor_python/actions/RemovePythonImports.py +22 -0
  7. simplibs/extractor_python/actions/__init__.py +45 -0
  8. simplibs/extractor_python/annotations/OnError.py +25 -0
  9. simplibs/extractor_python/annotations/__init__.py +18 -0
  10. simplibs/extractor_python/constants/PYTHON_CONFIG_NAMES.py +27 -0
  11. simplibs/extractor_python/constants/PYTHON_OUTPUT_DIR_NAMES.py +19 -0
  12. simplibs/extractor_python/constants/PYTHON_SUFFIXES.py +17 -0
  13. simplibs/extractor_python/constants/PYTHON_TEST_DIR_NAMES.py +18 -0
  14. simplibs/extractor_python/constants/PYTHON_VENV_DIR_NAMES.py +18 -0
  15. simplibs/extractor_python/constants/__init__.py +26 -0
  16. simplibs/extractor_python/file_rules/__init__.py +62 -0
  17. simplibs/extractor_python/file_rules/atomic/DOT_NAME.py +19 -0
  18. simplibs/extractor_python/file_rules/atomic/INIT_NAME.py +17 -0
  19. simplibs/extractor_python/file_rules/atomic/IN_DUNDER_DIR.py +16 -0
  20. simplibs/extractor_python/file_rules/atomic/MAIN_NAME.py +16 -0
  21. simplibs/extractor_python/file_rules/atomic/OUTPUT_DIRS.py +17 -0
  22. simplibs/extractor_python/file_rules/atomic/VCS_DIRS.py +26 -0
  23. simplibs/extractor_python/file_rules/atomic/VENV_DIRS.py +18 -0
  24. simplibs/extractor_python/file_rules/atomic/__init__.py +30 -0
  25. simplibs/extractor_python/file_rules/python/PYTHON_BASE.py +17 -0
  26. simplibs/extractor_python/file_rules/python/PYTHON_CONFIG.py +18 -0
  27. simplibs/extractor_python/file_rules/python/PYTHON_STRICT_EXCLUDE.py +24 -0
  28. simplibs/extractor_python/file_rules/python/PYTHON_TESTS.py +29 -0
  29. simplibs/extractor_python/file_rules/python/__init__.py +22 -0
  30. simplibs/extractor_python/file_rules/python/build_python_base.py +58 -0
  31. simplibs/extractor_python/logic/__init__.py +32 -0
  32. simplibs/extractor_python/logic/_helpers/SourceOffsets.py +82 -0
  33. simplibs/extractor_python/logic/_helpers/__init__.py +36 -0
  34. simplibs/extractor_python/logic/_helpers/collect_definitions.py +60 -0
  35. simplibs/extractor_python/logic/_helpers/cut_statements.py +126 -0
  36. simplibs/extractor_python/logic/_helpers/describe_source_failure.py +34 -0
  37. simplibs/extractor_python/logic/_helpers/find_decorator_spans.py +107 -0
  38. simplibs/extractor_python/logic/_helpers/find_docstrings.py +46 -0
  39. simplibs/extractor_python/logic/_helpers/find_imports.py +33 -0
  40. simplibs/extractor_python/logic/_helpers/first_doc_line.py +37 -0
  41. simplibs/extractor_python/logic/_helpers/format_type_params.py +29 -0
  42. simplibs/extractor_python/logic/_helpers/guarded_parse.py +64 -0
  43. simplibs/extractor_python/logic/_helpers/outline_node.py +72 -0
  44. simplibs/extractor_python/logic/_helpers/parse_python.py +32 -0
  45. simplibs/extractor_python/logic/_validations/__init__.py +14 -0
  46. simplibs/extractor_python/logic/_validations/raise_python_source_error.py +55 -0
  47. simplibs/extractor_python/logic/python_comment_spans.py +73 -0
  48. simplibs/extractor_python/logic/python_outline.py +63 -0
  49. simplibs/extractor_python/logic/remove_python_comments.py +44 -0
  50. simplibs/extractor_python/logic/remove_python_decorators.py +48 -0
  51. simplibs/extractor_python/logic/remove_python_docstrings.py +50 -0
  52. simplibs/extractor_python/logic/remove_python_imports.py +48 -0
  53. simplibs/extractor_python/plugin/__init__.py +14 -0
  54. simplibs/extractor_python/plugin/register_all.py +45 -0
  55. simplibs/extractor_python/presets/PYTHON_CLEAN.py +29 -0
  56. simplibs/extractor_python/presets/PYTHON_NO_IMPORTS.py +32 -0
  57. simplibs/extractor_python/presets/__init__.py +30 -0
  58. simplibs/extractor_python/profiles/PYTHON_CODE_CLEAN.py +29 -0
  59. simplibs/extractor_python/profiles/PYTHON_CODE_NO_IMPORTS.py +29 -0
  60. simplibs/extractor_python/profiles/PYTHON_DATA_ALL.py +26 -0
  61. simplibs/extractor_python/profiles/PYTHON_OUTLINE.py +30 -0
  62. simplibs/extractor_python/profiles/PYTHON_PROFILES.py +26 -0
  63. simplibs/extractor_python/profiles/PYTHON_SRC_CLEAN.py +30 -0
  64. simplibs/extractor_python/profiles/__init__.py +47 -0
  65. simplibs/extractor_python/py.typed +1 -0
  66. simplibs_extractor_python-0.1.0.dist-info/METADATA +457 -0
  67. simplibs_extractor_python-0.1.0.dist-info/RECORD +71 -0
  68. simplibs_extractor_python-0.1.0.dist-info/WHEEL +5 -0
  69. simplibs_extractor_python-0.1.0.dist-info/entry_points.txt +2 -0
  70. simplibs_extractor_python-0.1.0.dist-info/licenses/LICENSE +21 -0
  71. simplibs_extractor_python-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,67 @@
1
+ from .annotations import OnError
2
+ from .logic import (
3
+ python_comment_spans,
4
+ python_outline,
5
+ remove_python_comments,
6
+ remove_python_decorators,
7
+ remove_python_docstrings,
8
+ remove_python_imports,
9
+ )
10
+ from .plugin import register_all
11
+
12
+
13
+ __all__ = [
14
+ # steps
15
+ "python_comment_spans",
16
+ "python_outline",
17
+ "remove_python_comments",
18
+ "remove_python_decorators",
19
+ "remove_python_docstrings",
20
+ "remove_python_imports",
21
+ # add-on of the extractor
22
+ "register_all",
23
+ # types
24
+ "OnError",
25
+ ]
26
+
27
+
28
+ _DESIGN_NOTES = """
29
+ # simplibs-extractor-python — Package Root
30
+
31
+ ## Purpose
32
+ The add-on that teaches `simplibs-extractor` about Python: file rules for
33
+ Python projects, the steps that clean the source (comments, docstrings,
34
+ imports, decorators), an outline step and five ready profiles. Install it and
35
+ the profiles are there:
36
+
37
+ simplibs-extractor python src-clean my_project
38
+
39
+ ## What the Root Exports
40
+ The steps as plain functions (`str -> str`), `register_all` (the target of the
41
+ entry point `simplibs.extractor.plugins`) and the annotation meant for the
42
+ caller's own signatures:
43
+
44
+ from simplibs.extractor_python import remove_python_comments, python_outline, OnError
45
+
46
+ ## What the Root Deliberately Does NOT Export
47
+ Four domain folders with their own `__all__`, imported through their domain:
48
+
49
+ from simplibs.extractor_python.actions import RemovePythonComments
50
+ from simplibs.extractor_python.file_rules import PYTHON_BASE, build_python_base
51
+ from simplibs.extractor_python.presets import PYTHON_CLEAN
52
+ from simplibs.extractor_python.profiles import PYTHON_SRC_CLEAN
53
+
54
+ and the internals: `_helpers/` and `_validations/` inside the domains.
55
+
56
+ ## Spans
57
+ The steps find ranges of characters as `simplibs.text.Span`. The type is not
58
+ defined here, it is taken from `simplibs-text`.
59
+
60
+ ## Layering
61
+ `annotations` ← `constants` ← `file_rules` ← `logic` ← `actions` ← `presets` ← `profiles` ← `plugin`.
62
+ Each layer imports only from the layers on its left; the root imports from the ones it exports.
63
+
64
+ ## `__all__`
65
+ Defined here and in the domain folders (`actions`, `file_rules`, `presets`,
66
+ `profiles`) only; the layers inside them use plain imports.
67
+ """
@@ -0,0 +1,23 @@
1
+ from simplibs.actions import create_action
2
+ # Outers
3
+ from ..logic import python_outline
4
+
5
+
6
+ PythonOutline = create_action(
7
+ python_outline,
8
+ main_param="text",
9
+ class_name="PythonOutline",
10
+ )
11
+ """Action wrapping `python_outline` — turns the Python text flowing in into signatures without bodies."""
12
+
13
+
14
+ _DESIGN_NOTES = """
15
+ # PythonOutline — Action Over `python_outline`
16
+
17
+ ## Purpose
18
+ The overview step as a link of a pipeline: `PythonOutline(docstrings=False)`.
19
+
20
+ ## Shape
21
+ Main input: `text`. Options: `docstrings` (first docstring line as a comment, on by default), `on_error`.
22
+ Text in, text out (a valid Python outline).
23
+ """
@@ -0,0 +1,22 @@
1
+ from simplibs.actions import create_action
2
+ # Outers
3
+ from ..logic import remove_python_comments
4
+
5
+
6
+ RemovePythonComments = create_action(
7
+ remove_python_comments,
8
+ main_param="text",
9
+ class_name="RemovePythonComments",
10
+ )
11
+ """Action wrapping `remove_python_comments` — takes the comments out of the Python text flowing in."""
12
+
13
+
14
+ _DESIGN_NOTES = """
15
+ # RemovePythonComments — Action Over `remove_python_comments`
16
+
17
+ ## Purpose
18
+ `RemovePythonComments() >> RemovePythonDocstrings()`: the comment step as a link of a pipeline, a step of a profile.
19
+
20
+ ## Shape
21
+ Main input: `text`. Option: `on_error` (`"raise"` by default, `"keep"`). Text in, text out.
22
+ """
@@ -0,0 +1,22 @@
1
+ from simplibs.actions import create_action
2
+ # Outers
3
+ from ..logic import remove_python_decorators
4
+
5
+
6
+ RemovePythonDecorators = create_action(
7
+ remove_python_decorators,
8
+ main_param="text",
9
+ class_name="RemovePythonDecorators",
10
+ )
11
+ """Action wrapping `remove_python_decorators` — takes the decorators off the classes and functions of the Python text flowing in."""
12
+
13
+
14
+ _DESIGN_NOTES = """
15
+ # RemovePythonDecorators — Action Over `remove_python_decorators`
16
+
17
+ ## Purpose
18
+ The decorator step as a link of a pipeline.
19
+
20
+ ## Shape
21
+ Main input: `text`. Option: `on_error`. Text in, text out.
22
+ """
@@ -0,0 +1,22 @@
1
+ from simplibs.actions import create_action
2
+ # Outers
3
+ from ..logic import remove_python_docstrings
4
+
5
+
6
+ RemovePythonDocstrings = create_action(
7
+ remove_python_docstrings,
8
+ main_param="text",
9
+ class_name="RemovePythonDocstrings",
10
+ )
11
+ """Action wrapping `remove_python_docstrings` — takes the docstrings out of the Python text flowing in."""
12
+
13
+
14
+ _DESIGN_NOTES = """
15
+ # RemovePythonDocstrings — Action Over `remove_python_docstrings`
16
+
17
+ ## Purpose
18
+ The docstring step as a link of a pipeline.
19
+
20
+ ## Shape
21
+ Main input: `text`. Option: `on_error`. Text in, text out; a body left empty gets `pass`.
22
+ """
@@ -0,0 +1,22 @@
1
+ from simplibs.actions import create_action
2
+ # Outers
3
+ from ..logic import remove_python_imports
4
+
5
+
6
+ RemovePythonImports = create_action(
7
+ remove_python_imports,
8
+ main_param="text",
9
+ class_name="RemovePythonImports",
10
+ )
11
+ """Action wrapping `remove_python_imports` — takes the import statements out of the Python text flowing in."""
12
+
13
+
14
+ _DESIGN_NOTES = """
15
+ # RemovePythonImports — Action Over `remove_python_imports`
16
+
17
+ ## Purpose
18
+ The import step as a link of a pipeline.
19
+
20
+ ## Shape
21
+ Main input: `text`. Option: `on_error`. Text in, text out.
22
+ """
@@ -0,0 +1,45 @@
1
+ from .PythonOutline import PythonOutline
2
+ from .RemovePythonComments import RemovePythonComments
3
+ from .RemovePythonDecorators import RemovePythonDecorators
4
+ from .RemovePythonDocstrings import RemovePythonDocstrings
5
+ from .RemovePythonImports import RemovePythonImports
6
+
7
+
8
+ __all__ = [
9
+ "PythonOutline",
10
+ "RemovePythonComments",
11
+ "RemovePythonDecorators",
12
+ "RemovePythonDocstrings",
13
+ "RemovePythonImports",
14
+ ]
15
+
16
+
17
+ _DESIGN_NOTES = """
18
+ # simplibs.extractor_python.actions — The Steps as Pipeline Actions
19
+
20
+ ## Purpose
21
+ Every step of `logic/` as an `Action` of `simplibs-actions`, so it can be
22
+ chained with `>>` and used as the `steps` of an extractor profile.
23
+
24
+ from simplibs.extractor_python.actions import RemovePythonComments, RemovePythonImports
25
+ steps = RemovePythonComments() >> RemovePythonImports()
26
+
27
+ ## Domain Folder
28
+ `actions/` has its own `__all__` and is not re-exported from the package root:
29
+ a function and an action are different kinds of thing and stay visibly
30
+ different at the import line.
31
+
32
+ ## Thin Wrappers
33
+ Each action is `create_action(function, main_param="text", ...)`. The options
34
+ of the function (`on_error`, `docstrings`) are the options of the action.
35
+
36
+ ## Internal Components Registry
37
+
38
+ | Component | Type | Description |
39
+ | :----------------------- | :----- | :-------------------------------------------------- |
40
+ | `PythonOutline` | Action | Over `python_outline`. |
41
+ | `RemovePythonComments` | Action | Over `remove_python_comments`. |
42
+ | `RemovePythonDecorators` | Action | Over `remove_python_decorators`. |
43
+ | `RemovePythonDocstrings` | Action | Over `remove_python_docstrings`. |
44
+ | `RemovePythonImports` | Action | Over `remove_python_imports`. |
45
+ """
@@ -0,0 +1,25 @@
1
+ from typing import Literal
2
+
3
+
4
+ OnError = Literal["raise", "keep"]
5
+ """What a Python step does with a source it cannot read: raise a card, or return the text unchanged."""
6
+
7
+
8
+ _DESIGN_NOTES = """
9
+ # OnError — What to Do With a Source That Is Not Valid
10
+
11
+ ## Purpose
12
+ The type of the `on_error` option of the Python steps: a file that is not valid
13
+ Python (an old Python 2 file, a template with `{{ }}` in it, a half-written
14
+ module) cannot be read by `ast` or `tokenize`.
15
+
16
+ ## The Two Answers
17
+ * `"raise"` — the step raises a card. The extractor marks that file `error`,
18
+ names the reason in the report and goes on with the next file. The default:
19
+ nothing is hidden.
20
+ * `"keep"` — the text comes back unchanged and nothing is said. For your own
21
+ profile, when "not cleaned" is better than "not there".
22
+
23
+ ## Why a Literal
24
+ A typo (`"Raise"`, `"ignore"`) fails at the signature, not deep inside a step.
25
+ """
@@ -0,0 +1,18 @@
1
+ from .OnError import OnError
2
+
3
+
4
+ _DESIGN_NOTES = """
5
+ # annotations — Shared Types of simplibs-extractor-python
6
+
7
+ Plain imports, no `__all__` (the package root decides what is public).
8
+
9
+ ## Internal Components Registry
10
+
11
+ | Component | Type | Description |
12
+ | :-------- | :------ | :---------------------------------------------------------------------- |
13
+ | `OnError` | Literal | `"raise"` or `"keep"`: what a Python step does with an invalid source. |
14
+
15
+ ## Not Here
16
+ `Span` (a half-open range of characters) is a type of `simplibs-text`; the
17
+ steps import it from there.
18
+ """
@@ -0,0 +1,27 @@
1
+ from typing import Final
2
+
3
+
4
+ PYTHON_CONFIG_NAMES: Final[tuple[str, ...]] = (
5
+ "setup.py",
6
+ "setup.cfg",
7
+ "pyproject.toml",
8
+ "Pipfile",
9
+ "Pipfile.lock",
10
+ "requirements.txt",
11
+ "tox.ini",
12
+ "pytest.ini",
13
+ )
14
+ """File names of Python project configuration."""
15
+
16
+
17
+ _DESIGN_NOTES = """
18
+ # PYTHON_CONFIG_NAMES — Packaging, Not Logic
19
+
20
+ ## Purpose
21
+ Used by `PYTHON_CONFIG`. These files describe how the project is built and
22
+ tested; they are not what it does.
23
+
24
+ ## Case
25
+ Names are compared exactly. `Pipfile` is written with a capital letter by the
26
+ tool that owns it.
27
+ """
@@ -0,0 +1,19 @@
1
+ from typing import Final
2
+
3
+
4
+ PYTHON_OUTPUT_DIR_NAMES: Final[tuple[str, ...]] = ("build", "dist", "out")
5
+ """Names of folders that hold generated build output of a Python project."""
6
+
7
+
8
+ _DESIGN_NOTES = """
9
+ # PYTHON_OUTPUT_DIR_NAMES — Generated, Not Written
10
+
11
+ ## Purpose
12
+ The names behind `OUTPUT_DIRS`. Build output repeats the source in another
13
+ shape; reading it twice only costs tokens.
14
+
15
+ ## Own List
16
+ The library keeps its own list instead of borrowing one: what counts as
17
+ build output differs from language to language, and each add-on decides it
18
+ for its own language.
19
+ """
@@ -0,0 +1,17 @@
1
+ from typing import Final
2
+
3
+
4
+ PYTHON_SUFFIXES: Final[tuple[str, ...]] = (".py",)
5
+ """The suffixes of Python source files."""
6
+
7
+
8
+ _DESIGN_NOTES = """
9
+ # PYTHON_SUFFIXES — What Counts as Python Source
10
+
11
+ ## Purpose
12
+ One place for the suffixes the Python rules and profiles look for.
13
+
14
+ ## Only `.py`
15
+ Stub files (`.pyi`) and Windows scripts (`.pyw`) are not source to read: a
16
+ stub only repeats the signatures of a module that is in the output anyway.
17
+ """
@@ -0,0 +1,18 @@
1
+ from typing import Final
2
+
3
+
4
+ PYTHON_TEST_DIR_NAMES: Final[tuple[str, ...]] = ("tests", "test")
5
+ """Names of folders that hold Python tests."""
6
+
7
+
8
+ _DESIGN_NOTES = """
9
+ # PYTHON_TEST_DIR_NAMES — Where Python Tests Live
10
+
11
+ ## Purpose
12
+ Used by `PYTHON_TESTS`: every file in a folder with one of these names is a
13
+ test, whatever the file is called.
14
+
15
+ ## Whole Names Only
16
+ A folder is compared as a whole (`tests`), never as a part of a name, so
17
+ `contest` or `latest` are not tests.
18
+ """
@@ -0,0 +1,18 @@
1
+ from typing import Final
2
+
3
+
4
+ PYTHON_VENV_DIR_NAMES: Final[tuple[str, ...]] = ("venv", ".venv", "env", "virtualenv")
5
+ """Names under which a Python virtual environment usually lives."""
6
+
7
+
8
+ _DESIGN_NOTES = """
9
+ # PYTHON_VENV_DIR_NAMES — Where Installed Packages Hide
10
+
11
+ ## Purpose
12
+ The names behind `VENV_DIRS`. A virtual environment holds thousands of files
13
+ that are not the project.
14
+
15
+ ## Known Limit
16
+ A folder called `env` that is something else (a settings package, say) is
17
+ excluded by the strict rules. The base rules do not look at these names.
18
+ """
@@ -0,0 +1,26 @@
1
+ from .PYTHON_CONFIG_NAMES import PYTHON_CONFIG_NAMES
2
+ from .PYTHON_OUTPUT_DIR_NAMES import PYTHON_OUTPUT_DIR_NAMES
3
+ from .PYTHON_SUFFIXES import PYTHON_SUFFIXES
4
+ from .PYTHON_TEST_DIR_NAMES import PYTHON_TEST_DIR_NAMES
5
+ from .PYTHON_VENV_DIR_NAMES import PYTHON_VENV_DIR_NAMES
6
+
7
+
8
+ _DESIGN_NOTES = """
9
+ # constants — Fixed Values of simplibs-extractor-python
10
+
11
+ Plain imports, no `__all__` (the package root decides what is public).
12
+
13
+ ## Internal Components Registry
14
+
15
+ | Component | Type | Description |
16
+ | :------------------------ | :------- | :----------------------------------------------- |
17
+ | `PYTHON_CONFIG_NAMES` | Constant | File names of Python project configuration. |
18
+ | `PYTHON_OUTPUT_DIR_NAMES` | Constant | Folders of generated build output. |
19
+ | `PYTHON_SUFFIXES` | Constant | Suffixes of Python files. |
20
+ | `PYTHON_TEST_DIR_NAMES` | Constant | Folders that hold Python tests. |
21
+ | `PYTHON_VENV_DIR_NAMES` | Constant | Folders of Python virtual environments. |
22
+
23
+ ## Layering & Design
24
+ - Every value is a tuple of plain strings: the rules are built from them in `file_rules`.
25
+ - The names of version-control folders are not here: they come from `IGNORE_VCS` of `simplibs-path`.
26
+ """
@@ -0,0 +1,62 @@
1
+ from .atomic import (
2
+ DOT_NAME,
3
+ INIT_NAME,
4
+ IN_DUNDER_DIR,
5
+ MAIN_NAME,
6
+ OUTPUT_DIRS,
7
+ VCS_DIRS,
8
+ VENV_DIRS,
9
+ )
10
+ from .python import (
11
+ PYTHON_BASE,
12
+ PYTHON_CONFIG,
13
+ PYTHON_STRICT_EXCLUDE,
14
+ PYTHON_TESTS,
15
+ build_python_base,
16
+ )
17
+
18
+
19
+ __all__ = [
20
+ # atomic
21
+ "DOT_NAME",
22
+ "INIT_NAME",
23
+ "IN_DUNDER_DIR",
24
+ "MAIN_NAME",
25
+ "OUTPUT_DIRS",
26
+ "VCS_DIRS",
27
+ "VENV_DIRS",
28
+ # python
29
+ "PYTHON_BASE",
30
+ "PYTHON_CONFIG",
31
+ "PYTHON_STRICT_EXCLUDE",
32
+ "PYTHON_TESTS",
33
+ "build_python_base",
34
+ ]
35
+
36
+
37
+ _DESIGN_NOTES = """
38
+ # simplibs.extractor_python.file_rules — Which Files Are Worth Reading
39
+
40
+ ## Purpose
41
+ Rules on the path of a file, relative to the source folder. The profiles use
42
+ them as `include` and `exclude`; they compose with `&`, `|` and `~`, so a
43
+ program can build its own selection from them:
44
+
45
+ from simplibs.extractor_python.file_rules import PYTHON_BASE, PYTHON_TESTS
46
+ only_tests = PYTHON_BASE & PYTHON_TESTS
47
+
48
+ ## Domain Folder
49
+ `file_rules/` has its own `__all__` and is not re-exported from the package root.
50
+
51
+ ## Internal Components Registry
52
+
53
+ | Component | Type | Description |
54
+ | :-------- | :------ | :------------------------------------------------------------ |
55
+ | `atomic` | Package | The shared pieces: dot names, init, main, VCS folders... |
56
+ | `python` | Package | Rules for Python projects. |
57
+
58
+ ## Layering & Design
59
+ - `atomic` ← `python`.
60
+ - Every rule is built once, when the package is imported.
61
+ - A rule about the folders above a file is `AnyParentNameIs` of `simplibs-path`; a set of names is `IsIn` of `simplibs-rules`.
62
+ """
@@ -0,0 +1,19 @@
1
+ from typing import Final
2
+ from simplibs.path.rules import NameIs
3
+ from simplibs.rules import Rule, StartsWith
4
+
5
+
6
+ DOT_NAME: Final[Rule] = NameIs(StartsWith("."))
7
+ """The file name starts with a dot (`.env`, `.hidden.py`)."""
8
+
9
+
10
+ _DESIGN_NOTES = """
11
+ # DOT_NAME — Hidden by Convention
12
+
13
+ ## Purpose
14
+ Dot files are settings and tool state, not source. Used by both base rules.
15
+
16
+ ## Name Only
17
+ Only the name of the file is judged. A visible file inside a `.cache` folder
18
+ is not hidden by this rule (the strict exclusions look at folders).
19
+ """
@@ -0,0 +1,17 @@
1
+ from typing import Final
2
+ from simplibs.path.rules import NameIs
3
+ from simplibs.rules import Equals, Rule
4
+
5
+
6
+ INIT_NAME: Final[Rule] = NameIs(Equals("__init__.py"))
7
+ """The file is called `__init__.py`."""
8
+
9
+
10
+ _DESIGN_NOTES = """
11
+ # INIT_NAME — The Face of a Package
12
+
13
+ ## Purpose
14
+ `__init__.py` holds the public names and `__all__` of a package, so it is
15
+ usually the best single file for understanding one. `build_python_base()`
16
+ takes it unless `include_init=False`.
17
+ """
@@ -0,0 +1,16 @@
1
+ from typing import Final
2
+ from simplibs.path.rules import AnyParentNameIs
3
+ from simplibs.rules import Rule, StartsWith
4
+
5
+
6
+ IN_DUNDER_DIR: Final[Rule] = AnyParentNameIs(StartsWith("__"))
7
+ """Some folder above the file has a name that starts with two underscores (`__pycache__`)."""
8
+
9
+
10
+ _DESIGN_NOTES = """
11
+ # IN_DUNDER_DIR — Folders Python Makes by Itself
12
+
13
+ ## Purpose
14
+ `__pycache__` and `__pypackages__` hold what the interpreter produced, never
15
+ source. Used by `build_python_base()`.
16
+ """
@@ -0,0 +1,16 @@
1
+ from typing import Final
2
+ from simplibs.path.rules import NameIs
3
+ from simplibs.rules import Equals, Rule
4
+
5
+
6
+ MAIN_NAME: Final[Rule] = NameIs(Equals("__main__.py"))
7
+ """The file is called `__main__.py`."""
8
+
9
+
10
+ _DESIGN_NOTES = """
11
+ # MAIN_NAME — What Runs With `python -m`
12
+
13
+ ## Purpose
14
+ The entry point of a package. `build_python_base()` takes it unless
15
+ `include_main=False`.
16
+ """
@@ -0,0 +1,17 @@
1
+ from typing import Final
2
+ from simplibs.path.rules import AnyParentNameIs
3
+ from simplibs.rules import IsIn, Rule
4
+ # Outers
5
+ from ...constants import PYTHON_OUTPUT_DIR_NAMES
6
+
7
+
8
+ OUTPUT_DIRS: Final[Rule] = AnyParentNameIs(IsIn(PYTHON_OUTPUT_DIR_NAMES))
9
+ """The file lies inside a build-output folder."""
10
+
11
+
12
+ _DESIGN_NOTES = """
13
+ # OUTPUT_DIRS — Generated Files
14
+
15
+ ## Purpose
16
+ Part of the strict Python exclusion. See `PYTHON_OUTPUT_DIR_NAMES`.
17
+ """
@@ -0,0 +1,26 @@
1
+ from typing import Final
2
+ from simplibs.path import IGNORE_VCS
3
+ from simplibs.path.rules import AnyParentNameIs
4
+ from simplibs.rules import IsIn, Rule
5
+
6
+
7
+ VCS_DIRS: Final[Rule] = AnyParentNameIs(IsIn(IGNORE_VCS))
8
+ """The file lies inside a version-control folder (`.git`, `.svn`, `.hg`, `.bzr`)."""
9
+
10
+
11
+ _DESIGN_NOTES = """
12
+ # VCS_DIRS — Not the Project's Own Files
13
+
14
+ ## Purpose
15
+ Part of the strict Python exclusion. The names are `IGNORE_VCS` of
16
+ `simplibs-path`: version control is the same for every language, so the
17
+ library borrows the list instead of keeping its own.
18
+
19
+ ## What Changed From the Old Code
20
+ The old list `VCS_DIR_NAMES` held also `node_modules` and `tmp`. Neither is
21
+ version control: `node_modules` belongs to the JavaScript add-on, and `tmp`
22
+ is dropped.
23
+
24
+ ## Whole Names Only
25
+ `IsIn` compares a folder name as a whole, so `.github` is not `.git`.
26
+ """
@@ -0,0 +1,18 @@
1
+ from typing import Final
2
+ from simplibs.path.rules import AnyParentNameIs
3
+ from simplibs.rules import IsIn, Rule
4
+ # Outers
5
+ from ...constants import PYTHON_VENV_DIR_NAMES
6
+
7
+
8
+ VENV_DIRS: Final[Rule] = AnyParentNameIs(IsIn(PYTHON_VENV_DIR_NAMES))
9
+ """The file lies inside a Python virtual environment folder."""
10
+
11
+
12
+ _DESIGN_NOTES = """
13
+ # VENV_DIRS — The Interpreter's Own Packages
14
+
15
+ ## Purpose
16
+ Part of the strict Python exclusion. See `PYTHON_VENV_DIR_NAMES` for the names
17
+ and the known limit.
18
+ """
@@ -0,0 +1,30 @@
1
+ from .DOT_NAME import DOT_NAME
2
+ from .INIT_NAME import INIT_NAME
3
+ from .IN_DUNDER_DIR import IN_DUNDER_DIR
4
+ from .MAIN_NAME import MAIN_NAME
5
+ from .OUTPUT_DIRS import OUTPUT_DIRS
6
+ from .VCS_DIRS import VCS_DIRS
7
+ from .VENV_DIRS import VENV_DIRS
8
+
9
+
10
+ _DESIGN_NOTES = """
11
+ # atomic — The Shared Pieces of the File Rules
12
+
13
+ Plain imports, no `__all__` (the package root decides what is public).
14
+
15
+ ## Internal Components Registry
16
+
17
+ | Component | Type | Description |
18
+ | :-------------- | :--- | :----------------------------------------------------------- |
19
+ | `DOT_NAME` | Rule | The name starts with a dot. |
20
+ | `INIT_NAME` | Rule | The name is `__init__.py`. |
21
+ | `IN_DUNDER_DIR` | Rule | A folder above the file starts with two underscores. |
22
+ | `MAIN_NAME` | Rule | The name is `__main__.py`. |
23
+ | `OUTPUT_DIRS` | Rule | A folder above the file is a build-output folder. |
24
+ | `VCS_DIRS` | Rule | A folder above the file is a version-control folder. |
25
+ | `VENV_DIRS` | Rule | A folder above the file is a virtual environment. |
26
+
27
+ ## Layering & Design
28
+ - Every piece is one rule of one idea; the `python` folder only combines them.
29
+ - The rules about folders use `AnyParentNameIs` of `simplibs-path` and `IsIn` of `simplibs-rules`.
30
+ """
@@ -0,0 +1,17 @@
1
+ from typing import Final
2
+ from simplibs.rules import Rule
3
+ # Inners
4
+ from .build_python_base import build_python_base
5
+
6
+
7
+ PYTHON_BASE: Final[Rule] = build_python_base()
8
+ """The default rule for Python files worth reading: `__init__.py` and `__main__.py` included."""
9
+
10
+
11
+ _DESIGN_NOTES = """
12
+ # PYTHON_BASE — The Default Choice of Python Files
13
+
14
+ ## Purpose
15
+ `build_python_base()` with its defaults, built once. Every Python profile of
16
+ this library uses it as `include`.
17
+ """