Skip to content

Commit

Permalink
Python 3.11 compatibility (#581)
Browse files Browse the repository at this point in the history
- Fixed entry point management to the newer way
- Updated deps
- Lots of mypy fixes
- Updated to PySide6 6.4.2, which introduces a known issue #603
  • Loading branch information
abey79 authored Mar 10, 2023
1 parent eddb681 commit b70ab77
Show file tree
Hide file tree
Showing 14 changed files with 1,377 additions and 1,273 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/python-lint-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: [3.8, 3.9, '3.10']
python-version: [3.9, '3.10', '3.11']
os: [ubuntu-latest, macos-latest, windows-latest]
defaults:
run:
Expand All @@ -36,7 +36,7 @@ jobs:
- name: Install project
run: poetry install -E all
- name: Lint and static analysis
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' # no need to run that 9x
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' # no need to run that 9x
run: |
poetry run isort --check --diff vpype vpype_cli vpype_viewer tests
poetry run black --check --diff vpype vpype_cli vpype_viewer tests
Expand All @@ -49,15 +49,15 @@ jobs:
sudo apt-get install -y -qq libegl1-mesa libegl1-mesa-dev
# PYTEST STRATEGY
# macOS is the only runner who has working ModernGL behaviour
# macOS + 3.10 is used for code coverage
# macOS + 3.11 is used for code coverage
- name: Pytest (code coverage)
run: |
poetry run pytest --cov=./ --cov-report=xml
if: matrix.os == 'macos-latest' && matrix.python-version == '3.10'
if: matrix.os == 'macos-latest' && matrix.python-version == '3.11'
- name: Pytest
run: |
poetry run pytest
if: matrix.os == 'macos-latest' && matrix.python-version != '3.10'
if: matrix.os == 'macos-latest' && matrix.python-version != '3.11'
- name: Pytest (no image similarity check)
run: |
poetry run pytest --skip-image-similarity
Expand All @@ -76,7 +76,7 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
if: matrix.os == 'macos-latest' && matrix.python-version == '3.10'
if: matrix.os == 'macos-latest' && matrix.python-version == '3.11'


# ----------------------------------------
Expand All @@ -93,7 +93,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'
cache: 'poetry'
- name: Install project
run: poetry install -E all
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'
# no caching!
- name: Install project
run: poetry install -E all
Expand Down Expand Up @@ -53,7 +53,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
python-version: '3.11'
- name: Build artifacts
run: poetry build
- name: Publish to PyPI
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Release date: UNRELEASED

### New features and improvements

* ...
* Added support for Python 3.11 and dropped support for Python 3.8 (#581)

### Bug fixes

Expand All @@ -16,10 +16,17 @@ Release date: UNRELEASED

* ...

### Known issue

* As of PySide 6.4.2, a refresh issue arises on macOS when the viewer window is resized by a window manager (#603)


## 1.12.1

Release date: 2022-11-12

**Note**: This is the last version of *vpype* to support Python 3.7.

### Bug fixes

* Pinned ModernGL to 5.7.0 or earlier to avoid an [issue](https://github.com/moderngl/moderngl/issues/525) introduced in 5.7.1 (2ce6aef780e8a280375cb230d732d092a0635ad3)
Expand Down
2,428 changes: 1,255 additions & 1,173 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ include = [
vpype = "vpype_cli.cli:cli"

[tool.poetry.dependencies]
python = ">=3.8, <3.11"
python = ">=3.9, <3.12"
cachetools = ">=4.2.2"
click = ">=8.0.1,<8.2.0"
multiprocess = ">=0.70.11"
Expand All @@ -51,7 +51,7 @@ matplotlib = { version = ">=3.3.2", optional = true }
glcontext = { version = ">=2.3.2", optional = true } # 2.3.2 needed to fix #200
moderngl = { version = ">=5.6.2,!=5.7.1,!=5.7.2", optional = true } # see moderngl/moderngl#525
Pillow = { version = ">=9.0.1", optional = true }
PySide6 = { version = ">=6.3.2,<6.4.0", optional = true } # 6.4.0 incompatible with matplotlib
PySide6 = { version = ">=6.4.0.1", optional = true }


[tool.poetry.group.dev.dependencies]
Expand All @@ -68,6 +68,7 @@ pytest-mpl = ">=0.12"
mypy = ">=0.901"
types-cachetools = ">=4.2.4"
types-setuptools = ">=57.4.17"
types-pillow = "^9.4.0.17"

[tool.poetry.group.docs]
optional = true
Expand Down
6 changes: 3 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ def pytest_addoption(parser):


def write_image_similarity_fail_report(
image: Image,
reference_image: Image,
image: Image.Image,
reference_image: Image.Image,
image_array: np.ndarray,
reference_image_array: np.ndarray,
test_id: str,
Expand Down Expand Up @@ -171,7 +171,7 @@ def assert_image_similarity(request) -> Callable:
test_id = test_id.replace("[", "-").replace("]", "-").replace("/", "_").rstrip("-")
path = REFERENCE_IMAGES_DIR + os.path.sep + test_id + ".png"

def _assert_image_similarity(img: Image) -> None:
def _assert_image_similarity(img: Image.Image) -> None:
nonlocal store_ref_image, test_id, path

if store_ref_image: # pragma: no cover
Expand Down
24 changes: 16 additions & 8 deletions vpype_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,21 @@ def cli(
logging.getLogger().setLevel(logging.DEBUG)

# Plug-in loading logic. This approach is preferred because:
# 1) Deferred plug-in loading avoid circular import between vpype and vpype_cli when plug-
# in uses deprecated APIs.
# 1) Deferred plugin loading avoid circular import between vpype and vpype_cli when plugin
# uses deprecated APIs.
# 2) Avoids the PyCharm type error with CliRunner.invoke()
global _PLUGINS_LOADED
if not _PLUGINS_LOADED:
_PLUGINS_LOADED = True
for entry_point in importlib.metadata.entry_points().get("vpype.plugins", []):

# since python 3.10, a new "selectable" API is used for entry points, see:
# https://docs.python.org/3/library/importlib.metadata.html#entry-points
# Not using it yields a deprecation warning in some circumstances.
if sys.version_info >= (3, 10):
entry_points = importlib.metadata.entry_points().select(group="vpype.plugins")
else: # pragma: no cover
entry_points = importlib.metadata.entry_points().get("vpype.plugins", [])
for entry_point in entry_points:
# noinspection PyBroadException
try:
cast(click.Group, ctx.command).add_command(entry_point.load())
Expand All @@ -210,8 +218,8 @@ def cli(
cast(click.Group, ctx.command).add_command(_BrokenCommand(entry_point.name))

# Manual handling of the help to work around circular import issues.
# Background: when importing plug-ins in the style of `click-plugin` (decorator, so plug-
# ins are loaded during the loading of `cli` itself), plug-in may not import things from
# Background: when importing plug-ins in the style of `click-plugin` (decorator, so plugins
# are loaded during the loading of `cli` itself), plug-in may not import things from
# `vpype_cli` since it is still partially loaded. Plug-ins are thus loaded when `cli` is
# actually executed (see previous lines). As a result, the Click's default behaviour for
# handling `--help` (i.e. print and exit *before* even executing `cli`) is unable to list
Expand Down Expand Up @@ -344,7 +352,7 @@ class BeginBlock:
def begin():
"""Marks the start of a block.
A `begin` command must be followed by a block processor command (eg. `grid` or `repeat`),
A `begin` command must be followed by a block processor command (e.g. `grid` or `repeat`),
which indicates how the block is processed. Blocks must be ended by a `end` command.
Blocks can be nested.
Expand Down Expand Up @@ -431,15 +439,15 @@ def execute(
This function serves as a Python API to vpype's pipeline. It can be used from a regular
Python script (as opposed to the ``vpype`` CLI which must be used from a console or via
:func:`os.system`.
:func:`os.system`).
If a :class:`vpype.Document` instance is provided, it will be preloaded in the pipeline
before the first command executes. The pipeline's content after the last command is
returned as a :class:`vpype.Document` instance.
Examples:
Read a SVG file, optimize it and return the result as a :class:`vpype.Document`
Read an SVG file, optimize it and return the result as a :class:`vpype.Document`
instance::
>>> doc = execute("read input.svg linemerge linesimplify linesort")
Expand Down
3 changes: 1 addition & 2 deletions vpype_cli/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def propset(
vpype [...] propset --global --type int my_prop 10 [...]
Set the layer property of type `float` (this is equivalent to using the `penwidth`
command:
command):
vpype [...] propset --layer 1 --type float vp_pen_width 0.5mm [...]
Expand Down Expand Up @@ -399,7 +399,6 @@ def name(layer: vp.LineCollection, name: str) -> vp.LineCollection:
@click.argument("pen_config", metavar="CONF", type=TextType())
@global_processor
def pens(document: vp.Document, pen_config: str) -> vp.Document:

# the CONF parameter must be checked explicitly (instead of using click.Choice()) because
# additional config file (potentially containing pen configs) may be added at runtime
config = vp.config_manager.config.get("pen_config", {})
Expand Down
Loading

0 comments on commit b70ab77

Please sign in to comment.