Skip to content

Commit 5aaa464

Browse files
authored
Add support for Python 3.13 (#77)
2 parents eade5a7 + a633bc7 commit 5aaa464

20 files changed

+99
-49
lines changed

.coveragerc

+1-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22

33
[report]
44
# Regexes for lines to exclude from consideration
5-
exclude_lines =
6-
# Have to re-enable the standard pragma:
7-
pragma: no cover
8-
5+
exclude_also =
96
# Don't complain if non-runnable code isn't run:
107
if __name__ == .__main__.:
118
def main

.flake8

-2
This file was deleted.

.github/workflows/deploy.yml

+7-4
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ jobs:
3030
# Upload to Test PyPI on every commit on main.
3131
release-test-pypi:
3232
name: Publish in-dev package to test.pypi.org
33-
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
33+
if: |
34+
github.repository_owner == 'hugovk'
35+
&& github.event_name == 'push'
36+
&& github.ref == 'refs/heads/main'
3437
runs-on: ubuntu-latest
3538
needs: build-package
3639

3740
permissions:
38-
# IMPORTANT: this permission is mandatory for trusted publishing
3941
id-token: write
4042

4143
steps:
@@ -53,12 +55,13 @@ jobs:
5355
# Upload to real PyPI on GitHub Releases.
5456
release-pypi:
5557
name: Publish released package to pypi.org
56-
if: github.event.action == 'published'
58+
if: |
59+
github.repository_owner == 'hugovk'
60+
&& github.event.action == 'published'
5761
runs-on: ubuntu-latest
5862
needs: build-package
5963

6064
permissions:
61-
# IMPORTANT: this permission is mandatory for trusted publishing
6265
id-token: write
6366

6467
steps:

.github/workflows/labels.yml

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
name: Sync labels
22

3+
permissions:
4+
pull-requests: write
5+
36
on:
47
push:
58
branches:

.github/workflows/lint.yml

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ name: Lint
22

33
on: [push, pull_request, workflow_dispatch]
44

5+
env:
6+
FORCE_COLOR: 1
7+
58
permissions:
69
contents: read
710

.github/workflows/require-pr-label.yml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ jobs:
1010

1111
permissions:
1212
issues: write
13+
pull-requests: write
1314

1415
steps:
1516
- uses: mheap/github-action-required-labels@v5

.github/workflows/test.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
python-version: ["pypy3.10", "3.8", "3.9", "3.10", "3.11", "3.12"]
14+
python-version: ["pypy3.10", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
1515
os: [macos-latest, ubuntu-latest]
1616

1717
steps:
@@ -24,7 +24,6 @@ jobs:
2424
allow-prereleases: true
2525
cache: pip
2626

27-
2827
- name: Install dependencies
2928
run: |
3029
python -m pip install -U pip

.pre-commit-config.yaml

+14-25
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,16 @@
11
repos:
2-
- repo: https://github.com/asottile/pyupgrade
3-
rev: v3.15.0
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.2.0
44
hooks:
5-
- id: pyupgrade
6-
args: [--py38-plus]
5+
- id: ruff
6+
args: [--fix, --exit-non-zero-on-fix]
77

88
- repo: https://github.com/psf/black-pre-commit-mirror
9-
rev: 23.12.1
9+
rev: 24.1.1
1010
hooks:
1111
- id: black
1212
exclude: ^html/
1313

14-
- repo: https://github.com/PyCQA/isort
15-
rev: 5.13.2
16-
hooks:
17-
- id: isort
18-
19-
- repo: https://github.com/PyCQA/flake8
20-
rev: 6.1.0
21-
hooks:
22-
- id: flake8
23-
additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
24-
exclude: ^html/
25-
26-
- repo: https://github.com/pre-commit/pygrep-hooks
27-
rev: v1.10.0
28-
hooks:
29-
- id: python-check-blanket-noqa
30-
- id: python-no-log-warn
31-
3214
- repo: https://github.com/pre-commit/pre-commit-hooks
3315
rev: v4.5.0
3416
hooks:
@@ -37,16 +19,18 @@ repos:
3719
- id: check-json
3820
- id: check-toml
3921
- id: check-yaml
22+
- id: debug-statements
4023
- id: end-of-file-fixer
4124
- id: trailing-whitespace
4225

4326
- repo: https://github.com/tox-dev/pyproject-fmt
44-
rev: 1.5.3
27+
rev: 1.7.0
4528
hooks:
4629
- id: pyproject-fmt
30+
additional_dependencies: [tox]
4731

4832
- repo: https://github.com/abravalheri/validate-pyproject
49-
rev: v0.15
33+
rev: v0.16
5034
hooks:
5135
- id: validate-pyproject
5236

@@ -55,5 +39,10 @@ repos:
5539
hooks:
5640
- id: tox-ini-fmt
5741

42+
- repo: meta
43+
hooks:
44+
- id: check-hooks-apply
45+
- id: check-useless-excludes
46+
5847
ci:
5948
autoupdate_schedule: quarterly

examples/custom_animations.py

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
on the map.
66
"""
77

8+
from __future__ import annotations
9+
810
import pygame
911

1012
from osmviz.animation import Simulation, SimViz, TrackingViz

examples/multiple_trackvizs.py

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
on a map using TrackingViz objects.
44
"""
55

6+
from __future__ import annotations
7+
68
from osmviz.animation import Simulation, TrackingViz
79

810
# The goal is to show 10 trains racing eastward across the US.

examples/pil_example.py

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
of OSM tiles patched together.
44
"""
55

6+
from __future__ import annotations
7+
68
from PIL import Image
79

810
from osmviz.manager import OSMManager, PILImageManager

pyproject.toml

+27
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ classifiers = [
2525
"Programming Language :: Python :: 3.10",
2626
"Programming Language :: Python :: 3.11",
2727
"Programming Language :: Python :: 3.12",
28+
"Programming Language :: Python :: 3.13",
2829
"Programming Language :: Python :: Implementation :: CPython",
2930
"Programming Language :: Python :: Implementation :: PyPy",
3031
"Topic :: Software Development :: Documentation",
@@ -51,5 +52,31 @@ version.source = "vcs"
5152
[tool.hatch.version.raw-options]
5253
local_scheme = "no-local-version"
5354

55+
[tool.ruff.lint]
56+
select = [
57+
"C4", # flake8-comprehensions
58+
"E", # pycodestyle errors
59+
"EM", # flake8-errmsg
60+
"F", # pyflakes errors
61+
"I", # isort
62+
"ISC", # flake8-implicit-str-concat
63+
"LOG", # flake8-logging
64+
"PGH", # pygrep-hooks
65+
"RUF100", # unused noqa (yesqa)
66+
"UP", # pyupgrade
67+
"W", # pycodestyle warnings
68+
"YTT", # flake8-2020
69+
]
70+
extend-ignore = [
71+
"E203", # Whitespace before ':'
72+
"E221", # Multiple spaces before operator
73+
"E226", # Missing whitespace around arithmetic operator
74+
"E241", # Multiple spaces after ','
75+
]
76+
77+
[tool.ruff.lint.isort]
78+
known-first-party = ["osmviz"]
79+
required-imports = ["from __future__ import annotations"]
80+
5481
[tool.pytest.ini_options]
5582
addopts = "-W error::DeprecationWarning"

src/osmviz/animation.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
3030
Keyboard input is accepted to control the speed of the simulation.
3131
"""
32+
3233
# Copyright (c) 2010 Colin Bick, Robert Damphousse
3334

3435
# Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -48,7 +49,7 @@
4849
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4950
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5051
# THE SOFTWARE.
51-
52+
from __future__ import annotations
5253

5354
import time
5455
from functools import reduce

src/osmviz/manager.py

+19-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3434
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3535
# THE SOFTWARE.
36+
from __future__ import annotations
3637

3738
import hashlib
3839
import math
@@ -88,7 +89,8 @@ def prepare_image(self, width, height):
8889
are those specified by width and height.
8990
"""
9091
if self.image:
91-
raise Exception("Image already prepared.")
92+
msg = "Image already prepared."
93+
raise Exception(msg)
9294
self.image = self.create_image(width, height)
9395

9496
def destroy_image(self):
@@ -107,12 +109,14 @@ def paste_image_file(self, image_file, xy):
107109
of that image, pastes the image into this object's internal image.
108110
"""
109111
if not self.image:
110-
raise Exception("Image not prepared")
112+
msg = "Image not prepared"
113+
raise Exception(msg)
111114

112115
try:
113116
img = self.load_image_file(image_file)
114117
except Exception as e:
115-
raise Exception(f"Could not load image {image_file}\n{e}")
118+
msg = f"Could not load image {image_file}\n{e}"
119+
raise Exception(msg)
116120

117121
self.paste_image(img, xy)
118122
del img
@@ -135,7 +139,8 @@ def __init__(self):
135139
try:
136140
import pygame
137141
except ImportError:
138-
raise Exception("Pygame could not be imported!")
142+
msg = "Pygame could not be imported!"
143+
raise Exception(msg)
139144
self.pygame = pygame
140145

141146
def create_image(self, width, height):
@@ -164,7 +169,8 @@ def __init__(self, mode):
164169
try:
165170
import PIL.Image
166171
except ImportError:
167-
raise Exception("PIL could not be imported!")
172+
msg = "PIL could not be imported!"
173+
raise Exception(msg)
168174
self.PILImage = PIL.Image
169175

170176
def create_image(self, width, height):
@@ -243,7 +249,8 @@ def __init__(self, **kwargs):
243249
print(f"WARNING: Using {self.cache} to cache map tiles.")
244250
if not os.access(self.cache, os.R_OK | os.W_OK):
245251
print(f" ERROR: Insufficient access to {self.cache}.")
246-
raise Exception("Unable to find/create/use map tile cache directory.")
252+
msg = "Unable to find/create/use map tile cache directory."
253+
raise Exception(msg)
247254

248255
# Get URL template, which supports the following fields:
249256
# * {z}: tile zoom level
@@ -279,7 +286,8 @@ def __init__(self, **kwargs):
279286
if mgr: # Assume it's a valid manager
280287
self.manager = mgr
281288
else:
282-
raise Exception("OSMManager.__init__ requires argument image_manager")
289+
msg = "OSMManager.__init__ requires argument image_manager"
290+
raise Exception(msg)
283291

284292
def get_tile_coord(self, lon_deg, lat_deg, zoom):
285293
"""
@@ -327,7 +335,8 @@ def retrieve_tile_image(self, tile_coord, zoom):
327335
try:
328336
urlretrieve(url, filename=filename)
329337
except Exception as e:
330-
raise Exception(f"Unable to retrieve URL: {url}\n{e}")
338+
msg = f"Unable to retrieve URL: {url}\n{e}"
339+
raise Exception(msg)
331340
return filename
332341

333342
def tile_nw_lat_lon(self, tile_coord, zoom):
@@ -354,7 +363,8 @@ def create_osm_image(self, bounds, zoom):
354363
"""
355364
(min_lat, max_lat, min_lon, max_lon) = bounds
356365
if not self.manager:
357-
raise Exception("No ImageManager was specified, cannot create image.")
366+
msg = "No ImageManager was specified, cannot create image."
367+
raise Exception(msg)
358368

359369
topleft = min_x, min_y = self.get_tile_coord(min_lon, max_lat, zoom)
360370
max_x, max_y = self.get_tile_coord(max_lon, min_lat, zoom)

test/functional/test_animation.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
from osmviz.animation import Simulation, TrackingViz
24

35
Inf = float("inf")

test/functional/test_manager.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import PIL.Image as Image
24

35
from osmviz.manager import OSMManager, PILImageManager

test/unit/test_image_manager.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
"""
22
Unit tests for ImageManager
33
"""
4+
5+
from __future__ import annotations
6+
47
import pytest
58

69
from osmviz.manager import ImageManager

test/unit/test_osm_manager.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
"""
22
Unit tests PILImageManager
33
"""
4+
5+
from __future__ import annotations
6+
47
import pytest
58

69
from osmviz.manager import OSMManager, PILImageManager

test/unit/test_pil_image_manager.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
"""
22
Unit tests for PILImageManager
33
"""
4+
5+
from __future__ import annotations
6+
47
import pytest
58

69
from osmviz.manager import PILImageManager

0 commit comments

Comments
 (0)