File: PKG-INFO

package info (click to toggle)
python-parse-stages 0.1.9-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 260 kB
  • sloc: python: 505; sh: 42; makefile: 4
file content (147 lines) | stat: -rw-r--r-- 6,026 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Metadata-Version: 2.3
Name: parse_stages
Version: 0.1.9
Summary: Parse an expression for selecting stages and tags
Project-URL: Homepage, https://devel.ringlet.net/devel/parse-stages/
Project-URL: Changes, https://devel.ringlet.net/devel/parse-stages/changes/
Project-URL: Issue Tracker, https://gitlab.com/ppentchev/parse-stages/-/issues
Project-URL: Source Code, https://gitlab.com/ppentchev/parse-stages
Author-email: Peter Pentchev <roam@ringlet.net>
License: BSD-2-Clause
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: DFSG approved
Classifier: License :: Freely Distributable
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: Testing :: Unit
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: pyparsing<4,>=3
Description-Content-Type: text/markdown

<!--
SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
SPDX-License-Identifier: BSD-2-Clause
-->

# Parse a mini-language for selecting objects by tag or name

\[[Home][ringlet-parse-stages] | [GitLab][gitlab] | [PyPI][pypi] | [ReadTheDocs][readthedocs]\]

This library is mostly useful for command-line parsing by other tools like
`tox-stages` and `nox-stages`. It may be used to parse e.g. a command-line
specification like `@check and not pylint` or `@tests or ruff` and then
match it against a list of objects that have names and lists of tags.

## Parse stage specifications

The `parse_spec()` function parses a string specification into
a `BoolExpr` object that may later be used to select matching objects
(e.g. test environments).

The specification mini-language may roughly be described as:

    expr ::= and_expr ["or" and_expr...]
    and_expr ::= not_expr ["and" not_expr...]
    not_expr ::= ["not"] atom
    atom ::= tag | keyword
    tag ::= "@" characters
    keyword ::= characters
    characters ::= [A-Za-z0-9_-]+

Thus, all of the following:

- `@check`
- `@check and @quick`
- `@tests and not examples`
- `not @tests`
- `pep8 or not @quick and @check`

...are valid expressions,
with the "not", "and", and "or" keywords having their usual precedence
(`pep8 or not @quick and @check` is parsed as
`pep8 or ((@not quick) and @check)`).

## Check whether an object matches a parsed specification

The `parse-stages` library provides two base dataclasses for objects that
may be matched against parsed expressions: `TaggedFrozen` and `Tagged`.
Both classes have the same members:

- `name`: a string
- `tags`: a list of strings
- `get_keyword_haystacks()`: a method that returns a list of strings,
  `[self.name]` unless overridden

When a `BoolExpr` object's `evaluate()` method is called for a specific
`TaggedFrozen` or `Tagged` object, it checks whether the specification
matches the tags and keywords defined for this object. Tags are matched
exactly, while a keyword is considered to match if it is contained in
the checked string; e.g. `pep` would match both `pep8` and `exp_pep563`,
while `@black` would not match a `black-reformat` tag.

The `get_keyword_haystacks()` method returns the strings to look in for
matching keywords. By default, it only returns the `name` field;
however, it may be extended, e.g. for Nox sessions it may also return
the name of the Python function that implements the session, for test
classes with methods it may return the class name and the method name, etc.

## Examples

Parse a list of stage specifications into expressions that may later be
matched against test environment definitions:

    e_check = parse_stages.parse_spec("@check")
    e_check_quick = parse_stages.parse_spec("@check and @quick")
    e_check_no_ruff = parse_stages.parse_spec("@check and not ruff")
    
    specs = [(spec, parse_stages.parse_spec(spec)) for spec in args.stage_specs]

Select the test environments that match the specification:

    # Obtain a list (okay, a dictionary) of test environments in some way
    tox_envs = get_tox_environments()  # {"ruff": {"tags": ["check", "quick"]}, ...}

    # Convert them to objects that the parsed expressions can match
    all_envs = [
        parse_stages.TaggedFrozen(name, env["tags"])
        for name, env in tox_envs.items()
    ]

    # Or define our own class that may hold additional information
    @dataclasses.dataclass(frozen=True)
    class TestEnv(parse_stages.TaggedFrozen):
        """A single test environment: name, tags, etc."""
        ...

    all_envs = [TestEnv(name, env["tags"], ...) for name, env in tox_envs.items()]

    # Select the ones that match the "@check" expression
    matched = [env for env in all_envs if e_check.evaluate(env)]

    # Or if we only care about the names...
    quick_names = [env.name for env in all_envs if e_check_quick.evaluate(env)]


## Contact

The `parse-stages` library was written by [Peter Pentchev][roam].
It is developed in [a GitLab repository][gitlab]. This documentation is
hosted at [Ringlet][ringlet-parse-stages] with a copy at [ReadTheDocs][readthedocs].

[roam]: mailto:roam@ringlet.net "Peter Pentchev"
[gitlab]: https://gitlab.com/ppentchev/parse-stages "The parse-stages GitLab repository"
[pypi]: https://pypi.org/project/parse-stages/ "The parse-stages Python Package Index page"
[readthedocs]: https://parse-stages.readthedocs.io/ "The parse-stages ReadTheDocs page"
[ringlet-parse-stages]: https://devel.ringlet.net/devel/parse-stages/ "The Ringlet parse-stages homepage"