Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page.

### Fixes

- Fixed PyInstaller builds on case-insensitive file systems by preventing the bundled
version data file from colliding with the `arcade.version` module. See
[#2837](https://github.com/pythonarcade/arcade/issues/2837)
- Fixed an issue where pixel scaling for high-dpi displays did not work correctly in web browsers via Pyodide. See [#2846](https://github.com/pythonarcade/arcade/pull/2846)
- Fixed issues with update/draw rate handling that changes with Pyglet 3, rates are now handled properly between desktop and browser. See [#2845](https://github.com/pythonarcade/arcade/pull/2845)
- Fixed caret behavior not responding appropriately when activating an input field. See [#2850](https://github.com/pythonarcade/arcade/pull/2850)
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# one-liner to get extensions in package: set([l.split(",")[0].split('.')[-1] for l in open('files.txt').readlines()])

recursive-exclude arcade *.pyc
recursive-include arcade VERSION
recursive-include arcade _VERSION
recursive-include arcade *.typed
recursive-include arcade/resources *.txt *.md *.url
recursive-include arcade/resources *.mp3 *.wav *.ogg
Expand Down
2 changes: 1 addition & 1 deletion RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
6. Run `tests/test_examples/run_all_examples.py`
7. Make sure `arcade/examples/asteroid_smasher.py` is playable.
8. Make sure `arcade/examples/platform_tutorial/17_views.py` is playable.
9. Update version number in `arcade/version.py`
9. Update version number in `arcade/_VERSION`
10. Update :ref:`release_notes` with release dates and any additional
info needed.
11. Make sure last check-in ran clean on GitHub actions, viewable on Discord
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions arcade/__pyinstaller/hook-arcade.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
"./arcade/resources/system",
),
(
arcade_path / "VERSION",
"./arcade/VERSION",
arcade_path / "_VERSION",
"./arcade",
),
]
)
Expand Down
8 changes: 4 additions & 4 deletions arcade/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ def _parse_python_friendly_version(


def _parse_py_version_from_file(
version_path: str | Path = _HERE / "VERSION", write_errors_to=sys.stderr
version_path: str | Path = _HERE / "_VERSION", write_errors_to=sys.stderr
) -> str:
"""Read & validate the VERSION file as from a limited subset.
"""Read & validate the _VERSION file as from a limited subset.
Comment thread
yxshee marked this conversation as resolved.
Outdated

On failure, it will:

Expand All @@ -114,7 +114,7 @@ def _parse_py_version_from_file(

Args:
version_path:
The VERSION file's path, defaulting to the same directory as
The _VERSION file's path, defaulting to the same directory as
this file.
write_errors_to:
Makes CI simpler by allowing a stream mock to be passed easily.
Expand All @@ -137,6 +137,6 @@ def _parse_py_version_from_file(
VERSION: Final[str] = _parse_py_version_from_file()
"""A Python-friendly version string.

This value is converted from the GitHub-style ``VERSION`` file at the
This value is converted from the GitHub-style ``_VERSION`` file at the
top-level of the arcade module.
"""
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
for k, v in ENV.items():
log.info(f"Env variable {k:{col_width}} : {v!r}")

# _temp_version = (REPO_LOCAL_ROOT / "arcade" / "VERSION").read_text().replace("-",'')
# _temp_version = (REPO_LOCAL_ROOT / "arcade" / "_VERSION").read_text().replace("-",'')

# Don't change to
# from arcade.version import VERSION
Expand Down
28 changes: 28 additions & 0 deletions tests/unit/test_pyinstaller_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import runpy
import sys
from pathlib import Path
from types import ModuleType

import pytest

import arcade


def test_version_data_is_bundled_at_package_root(monkeypatch: pytest.MonkeyPatch):
pyinstaller = ModuleType("PyInstaller")
compat = ModuleType("PyInstaller.compat")
compat.is_darwin = False
compat.is_unix = True
compat.is_win = False
monkeypatch.setitem(sys.modules, "PyInstaller", pyinstaller)
monkeypatch.setitem(sys.modules, "PyInstaller.compat", compat)

Comment thread
yxshee marked this conversation as resolved.
package_dir = Path(arcade.__file__).parent
hook_globals = runpy.run_path(package_dir / "__pyinstaller" / "hook-arcade.py")
bundled_version_paths = [
Path(destination) / Path(source).name
for source, destination in hook_globals["datas"]
if Path(source).name == "_VERSION"
]

assert bundled_version_paths == [Path("arcade/_VERSION")]
32 changes: 31 additions & 1 deletion tests/unit/test_version.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,39 @@
import sys
import tempfile
from pathlib import Path
from unittest import mock

import pytest
from arcade.version import _parse_python_friendly_version, _parse_py_version_from_file

import arcade.version as version_module
from arcade.version import _parse_py_version_from_file, _parse_python_friendly_version


def test_default_version_file_is_loaded():
version_path = Path(version_module.__file__).with_name("_VERSION")

assert version_path.is_file()
assert _parse_py_version_from_file(version_path) == version_module.VERSION


def test_package_data_names_do_not_collide_with_modules_when_casefolded():
package_dir = Path(version_module.__file__).parent
importable_names = {
path.stem.casefold() for path in package_dir.iterdir() if path.suffix == ".py"
}
importable_names.update(
path.name.casefold()
for path in package_dir.iterdir()
if path.is_dir() and (path / "__init__.py").is_file()
)
data_names = {
path.name.casefold()
for path in package_dir.iterdir()
if path.is_file() and path.suffix != ".py"
}

collisions = importable_names & data_names
assert not collisions, f"Case-insensitive package path collisions: {sorted(collisions)}"


@pytest.mark.parametrize(
Expand Down
2 changes: 1 addition & 1 deletion webplayground/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
here = Path(__file__).parent.resolve()

path_arcade = here.parent
version_file_path = path_arcade / "arcade" / "VERSION"
version_file_path = path_arcade / "arcade" / "_VERSION"
VERSION = "unknown"
with open(version_file_path, "r") as version_file:
VERSION = version_file.read().rstrip()
Expand Down