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.
- simplibs/extractor_python/__init__.py +67 -0
- simplibs/extractor_python/actions/PythonOutline.py +23 -0
- simplibs/extractor_python/actions/RemovePythonComments.py +22 -0
- simplibs/extractor_python/actions/RemovePythonDecorators.py +22 -0
- simplibs/extractor_python/actions/RemovePythonDocstrings.py +22 -0
- simplibs/extractor_python/actions/RemovePythonImports.py +22 -0
- simplibs/extractor_python/actions/__init__.py +45 -0
- simplibs/extractor_python/annotations/OnError.py +25 -0
- simplibs/extractor_python/annotations/__init__.py +18 -0
- simplibs/extractor_python/constants/PYTHON_CONFIG_NAMES.py +27 -0
- simplibs/extractor_python/constants/PYTHON_OUTPUT_DIR_NAMES.py +19 -0
- simplibs/extractor_python/constants/PYTHON_SUFFIXES.py +17 -0
- simplibs/extractor_python/constants/PYTHON_TEST_DIR_NAMES.py +18 -0
- simplibs/extractor_python/constants/PYTHON_VENV_DIR_NAMES.py +18 -0
- simplibs/extractor_python/constants/__init__.py +26 -0
- simplibs/extractor_python/file_rules/__init__.py +62 -0
- simplibs/extractor_python/file_rules/atomic/DOT_NAME.py +19 -0
- simplibs/extractor_python/file_rules/atomic/INIT_NAME.py +17 -0
- simplibs/extractor_python/file_rules/atomic/IN_DUNDER_DIR.py +16 -0
- simplibs/extractor_python/file_rules/atomic/MAIN_NAME.py +16 -0
- simplibs/extractor_python/file_rules/atomic/OUTPUT_DIRS.py +17 -0
- simplibs/extractor_python/file_rules/atomic/VCS_DIRS.py +26 -0
- simplibs/extractor_python/file_rules/atomic/VENV_DIRS.py +18 -0
- simplibs/extractor_python/file_rules/atomic/__init__.py +30 -0
- simplibs/extractor_python/file_rules/python/PYTHON_BASE.py +17 -0
- simplibs/extractor_python/file_rules/python/PYTHON_CONFIG.py +18 -0
- simplibs/extractor_python/file_rules/python/PYTHON_STRICT_EXCLUDE.py +24 -0
- simplibs/extractor_python/file_rules/python/PYTHON_TESTS.py +29 -0
- simplibs/extractor_python/file_rules/python/__init__.py +22 -0
- simplibs/extractor_python/file_rules/python/build_python_base.py +58 -0
- simplibs/extractor_python/logic/__init__.py +32 -0
- simplibs/extractor_python/logic/_helpers/SourceOffsets.py +82 -0
- simplibs/extractor_python/logic/_helpers/__init__.py +36 -0
- simplibs/extractor_python/logic/_helpers/collect_definitions.py +60 -0
- simplibs/extractor_python/logic/_helpers/cut_statements.py +126 -0
- simplibs/extractor_python/logic/_helpers/describe_source_failure.py +34 -0
- simplibs/extractor_python/logic/_helpers/find_decorator_spans.py +107 -0
- simplibs/extractor_python/logic/_helpers/find_docstrings.py +46 -0
- simplibs/extractor_python/logic/_helpers/find_imports.py +33 -0
- simplibs/extractor_python/logic/_helpers/first_doc_line.py +37 -0
- simplibs/extractor_python/logic/_helpers/format_type_params.py +29 -0
- simplibs/extractor_python/logic/_helpers/guarded_parse.py +64 -0
- simplibs/extractor_python/logic/_helpers/outline_node.py +72 -0
- simplibs/extractor_python/logic/_helpers/parse_python.py +32 -0
- simplibs/extractor_python/logic/_validations/__init__.py +14 -0
- simplibs/extractor_python/logic/_validations/raise_python_source_error.py +55 -0
- simplibs/extractor_python/logic/python_comment_spans.py +73 -0
- simplibs/extractor_python/logic/python_outline.py +63 -0
- simplibs/extractor_python/logic/remove_python_comments.py +44 -0
- simplibs/extractor_python/logic/remove_python_decorators.py +48 -0
- simplibs/extractor_python/logic/remove_python_docstrings.py +50 -0
- simplibs/extractor_python/logic/remove_python_imports.py +48 -0
- simplibs/extractor_python/plugin/__init__.py +14 -0
- simplibs/extractor_python/plugin/register_all.py +45 -0
- simplibs/extractor_python/presets/PYTHON_CLEAN.py +29 -0
- simplibs/extractor_python/presets/PYTHON_NO_IMPORTS.py +32 -0
- simplibs/extractor_python/presets/__init__.py +30 -0
- simplibs/extractor_python/profiles/PYTHON_CODE_CLEAN.py +29 -0
- simplibs/extractor_python/profiles/PYTHON_CODE_NO_IMPORTS.py +29 -0
- simplibs/extractor_python/profiles/PYTHON_DATA_ALL.py +26 -0
- simplibs/extractor_python/profiles/PYTHON_OUTLINE.py +30 -0
- simplibs/extractor_python/profiles/PYTHON_PROFILES.py +26 -0
- simplibs/extractor_python/profiles/PYTHON_SRC_CLEAN.py +30 -0
- simplibs/extractor_python/profiles/__init__.py +47 -0
- simplibs/extractor_python/py.typed +1 -0
- simplibs_extractor_python-0.1.0.dist-info/METADATA +457 -0
- simplibs_extractor_python-0.1.0.dist-info/RECORD +71 -0
- simplibs_extractor_python-0.1.0.dist-info/WHEEL +5 -0
- simplibs_extractor_python-0.1.0.dist-info/entry_points.txt +2 -0
- simplibs_extractor_python-0.1.0.dist-info/licenses/LICENSE +21 -0
- 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
|
+
"""
|