Skip to content

Commit fcefd8c

Browse files
committed
Update docs and add coverage/coveralls upload
- Run coverage on tests and upload parallel builds to coveralls - Remove travis CI file - Add CHANGELOG.md - Add `ruff` rule to Makefile - Update some badges in README.md - Mention recent additions in README.md - Drop some outdated pylint comments - Add classifiers to setup.py
1 parent 723610e commit fcefd8c

File tree

7 files changed

+115
-39
lines changed

7 files changed

+115
-39
lines changed

.github/workflows/ci.yml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,18 @@ jobs:
4848
4949
- name: Run tests (unittest)
5050
run: |
51-
python -m unittest discover -v
51+
pip install coverage
52+
make coverage
53+
54+
- name: Coveralls upload
55+
uses: coverallsapp/github-action@v2
56+
if: "${{ success() }}"
57+
with:
58+
github-token: "${{ secrets.GITHUB_TOKEN }}"
59+
flag-name: "python-${{ matrix.python }}"
60+
parallel: true
61+
format: cobertura
62+
files: coverage.xml
5263

5364
test-legacy:
5465
name: Tests (Python 2.7 via container)
@@ -77,3 +88,10 @@ jobs:
7788
- name: Aggregate result
7889
run: |
7990
echo "Modern matrix + legacy (2.7) complete. Check job logs for details."
91+
92+
- name: Close parallel Coveralls build
93+
uses: coverallsapp/github-action@v2
94+
if: "${{ success() }}"
95+
with:
96+
github-token: "${{ secrets.GITHUB_TOKEN }}"
97+
parallel-finished: true

.travis.yml

Lines changed: 0 additions & 12 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
6+
and we adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Changed
11+
12+
- Implement true short-circuit for 'and'/'or' returning deciding operand
13+
- Make chained comparisons evaluate pairwise with short-circuit
14+
- Restrict function calls to direct names only (reject attribute/lambda)
15+
16+
### Fixed
17+
18+
- Add `visit_Constant` for Python 3.8+ unified literals support
19+
20+
## [0.0.5] - 2018-01-29
21+
22+
### Added
23+
24+
- Support simple (augmented) assignment operations like `variable = expression`
25+
and `variable += expression` via the `assignment` parameter and property,
26+
with a `modified_variables` property
27+
- Variable scope can be replaced
28+
- Add interactive interpreter script entry point
29+
30+
### Changed
31+
32+
- Interpreter keeps context of variable scope
33+
- Install script as `expression` instead of `expr` to avoid conflict
34+
- Show only the expression line in the traceback
35+
36+
## [0.0.4] - 2017-10-05
37+
38+
### Added
39+
40+
- Track which variables are used in expression with a `used_variables` property
41+
42+
## [0.0.3] - 2017-10-05
43+
44+
### Fixed
45+
46+
- Correct Python 3.6+ starred arguments detection
47+
- Disallow overriding predefined names `True`, `False` and `None`
48+
- Always use float division for `/`
49+
50+
## [0.0.1] - 2017-10-05
51+
52+
### Added
53+
54+
- Initial version of expression parser
55+
56+
[Unreleased]: https://github.com/lhelwerd/expression-parser/compare/v0.0.5...HEAD
57+
[0.0.5]: https://github.com/lhelwerd/expression-parser/releases/tag/v0.0.5
58+
[0.0.4]: https://github.com/lhelwerd/expression-parser/releases/tag/v0.0.4
59+
[0.0.3]: https://github.com/lhelwerd/expression-parser/releases/tag/v0.0.3
60+
[0.0.1]: https://github.com/lhelwerd/expression-parser/releases/tag/v0.0.1

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
SOURCES=*.py expression/*.py tests/*.py
12
COVERAGE=coverage
23
TEST=-m unittest discover -s tests -p '*.py'
34

@@ -18,7 +19,11 @@ get_version:
1819

1920
.PHONY: pylint
2021
pylint:
21-
pylint *.py expression/*.py tests/*.py
22+
pylint $(SOURCES)
23+
24+
.PHONY: ruff
25+
ruff:
26+
ruff check $(SOURCES)
2227

2328
.PHONY: tag
2429
tag: get_version
@@ -45,6 +50,7 @@ test:
4550
coverage:
4651
$(COVERAGE) run $(TEST)
4752
$(COVERAGE) report -m
53+
$(COVERAGE) xml -i -o coverage.xml
4854

4955
.PHONY: clean
5056
clean:

README.md

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
# Python sandboxed expression parser
22

33
[![PyPI](https://img.shields.io/pypi/v/expression-parser.svg)](https://pypi.python.org/pypi/expression-parser)
4-
[![Build
5-
Status](https://travis-ci.org/lhelwerd/expression-parser.svg?branch=master)](https://travis-ci.org/lhelwerd/expression-parser)
6-
[![Coverage
7-
Status](https://coveralls.io/repos/github/lhelwerd/expression-parser/badge.svg?branch=master)](https://coveralls.io/github/lhelwerd/expression-parser?branch=master)
4+
[![PyPI Versions](https://img.shields.io/pypi/pyversions/expression-parser.svg)](https://pypi.python.org/pypi/expression-parser/#files)
5+
[![CI Status](https://github.com/lhelwerd/expression-parser/actions/workflows/ci.yml/badge.svg)](https://github.com/lhelwerd/expression-parser/actions/workflows/ci.yml)
6+
[![Coverage Status](https://coveralls.io/repos/github/lhelwerd/expression-parser/badge.svg?branch=master)](https://coveralls.io/github/lhelwerd/expression-parser?branch=master)
87

9-
This parser can calculate the results of a single simple expression,
8+
This parser calculates the results of a single simple expression,
109
disallowing any complicated functions or control structures, with support for
1110
custom variable and function environment contexts.
1211

1312
## Features
1413

1514
- Support for all boolean, binary, unary, and comparative operators as in
16-
Python itself.
15+
Python itself, including short-circuiting and chained comparison logic.
1716
- Support for inline `if..else` expressions.
1817
- Support for assignments and augmented assignments like `+=`, only if enabled
1918
explicitly.
2019
- All other control structures and multiple expressions are disallowed.
2120
- Isolation from execution context using a restricted scope.
2221
- Separate scope for variables and functions to avoid abusing one or the other.
23-
- Function calls may use specific keyword arguments.
22+
- Function calls must use direct names (function attributes and lambda
23+
functions are rejected) and must not provide starred arguments.
2424
- Errors from parsing or evaluating the expression are raised as `SyntaxError`
2525
with appropriate context parameters to make error display easier (works with
2626
default traceback output).
2727
- A successful parse yields the result of the evaluated expression. Successful
2828
assignments of variables are stored in a property `modified_variables`.
2929
A separate property `used_variables` provides a set of variable names used in
3030
the evaluation of the expression excluding the assignment targets.
31-
- Supports both Python 2.7 and 3.6 AST syntax trees.
31+
- Supports Python 2.7 and 3.6-3.14 AST syntax trees.
3232
- Python 3+ conventions are used whenever possible: Specifically, the division
3333
operator `/` always returns floats instead of integers, and `True`, `False`
3434
and `None` are reserved named constants and cannot be overridden through the
@@ -47,14 +47,14 @@ Not supported (often by design):
4747

4848
## Requirements
4949

50-
The expression parser has been tested to work on Python 2.7 and 3.6. This
50+
The expression parser has been tested to work on Python 2.7 and 3.8+. This
5151
package has no other dependencies and works with only core Python modules.
5252

5353
## Installation
5454

5555
Install the latest version from PyPI using:
5656

57-
```
57+
```bash
5858
pip install expression-parser
5959
```
6060

@@ -92,8 +92,11 @@ arguments, such as `parser = expression.Expression_Parser()`, or by passing the
9292
scope along to it in dictionaries of values and functions, respectively:
9393

9494
```python
95-
parser = expression.Expression_Parser(variables=variables, functions=functions,
96-
assignment=bool(assignment))
95+
parser = expression.Expression_Parser(
96+
variables=variables,
97+
functions=functions,
98+
assignment=bool(assignment)
99+
)
97100
```
98101

99102
You can also set a new dictionary for `variables`, and enable or disable
@@ -103,22 +106,22 @@ via the properties of the created object.
103106
Now you can use this parser to evaluate any valid expression:
104107

105108
```python
106-
print(parser.parse('1+2'))
109+
>> print(parser.parse('1+2'))
107110
3
108-
print(parser.parse('pi > 3'))
111+
>> print(parser.parse('pi > 3'))
109112
True
110-
print(parser.parse('int(log(e))'))
113+
>> print(parser.parse('int(log(e))'))
111114
1
112115
```
113116

114117
## Development
115118

116-
- [Travis](https://travis-ci.org/lhelwerd/expression-parser) is used to run
117-
unit tests and report on coverage.
119+
- [GitHub Actions](https://github.com/lhelwerd/expression-parser/actions) is
120+
used to run unit tests and report on coverage.
118121
- [Coveralls](https://coveralls.io/github/lhelwerd/expression-parser) receives
119122
coverage reports and tracks them.
120-
- You can perform local lint checks, tests and coverage during development
121-
using `make pylint`, `make test` and `make coverage`, respectively.
123+
- You can perform local lint checks, tests or coverage during development using
124+
`make ruff`, `make pylint`, `make test` or `make coverage`, respectively.
122125
- We publish releases to [PyPI](https://pypi.python.org/pypi/expression-parser)
123126
using `make release` which performs lint and unit test checks.
124127

expression/parser.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,6 @@ def visit_Starred(self, node):
404404
Visit a starred function keyword argument node.
405405
"""
406406

407-
# pylint: disable=no-self-use
408-
409407
raise SyntaxError(
410408
"Star arguments are not supported", ("", node.lineno, node.col_offset, "")
411409
)
@@ -429,7 +427,6 @@ def visit_Num(self, node):
429427
Visit a literal number node.
430428
"""
431429

432-
# pylint: disable=no-self-use
433430
return node.n
434431

435432
def visit_Name(self, node):
@@ -453,10 +450,8 @@ def visit_NameConstant(self, node):
453450
Visit a named constant singleton node (Python 3).
454451
"""
455452

456-
# pylint: disable=no-self-use
457453
return node.value
458454

459455
def visit_Constant(self, node): # Python 3.8+ unified literal node
460456
"""Visit a constant literal node (numbers, strings, booleans, None, Ellipsis)."""
461-
# pylint: disable=no-self-use
462457
return node.value

setup.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@
4646
"Operating System :: OS Independent",
4747
"Programming Language :: Python",
4848
"Programming Language :: Python :: 2.7",
49-
"Programming Language :: Python :: 3.6",
49+
"Programming Language :: Python :: 3.8",
50+
"Programming Language :: Python :: 3.9",
51+
"Programming Language :: Python :: 3.10",
52+
"Programming Language :: Python :: 3.11",
53+
"Programming Language :: Python :: 3.12",
54+
"Programming Language :: Python :: 3.13",
55+
"Programming Language :: Python :: 3.14",
5056
"Topic :: Software Development :: Interpreters",
5157
],
5258
keywords=["expression", "parser", "sandbox"],

0 commit comments

Comments
 (0)