Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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 and validate the _VERSION file using a limited version syntax.

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
30 changes: 30 additions & 0 deletions tests/unit/test_pyinstaller_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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")
setattr(pyinstaller, "__path__", [])
setattr(pyinstaller, "compat", compat)
setattr(compat, "is_darwin", False)
setattr(compat, "is_unix", True)
setattr(compat, "is_win", False)
monkeypatch.setitem(sys.modules, "PyInstaller", pyinstaller)
monkeypatch.setitem(sys.modules, "PyInstaller.compat", compat)

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