From 15aea80714a8b22c5509ae8592dda38acb4f7ae1 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 10 Jun 2026 19:56:49 -0400 Subject: [PATCH 01/50] Python 3.15 Linux builds --- .github/workflows/lint-and-build.yml | 9 ++ pyproject.toml | 6 +- uv.lock | 162 ++++++++++++++++++++++----- 3 files changed, 149 insertions(+), 28 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index f51acb0c..23711e85 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -51,6 +51,9 @@ jobs: # arm runner slower as long as opencv doesn't provide arm64 wheels os: [windows-latest, ubuntu-latest] python-version: ["3.14"] + include: + - os: ubuntu-latest + python-version: "3.15" steps: - uses: actions/checkout@v6 - name: Set up uv for Python ${{ matrix.python-version }} @@ -86,6 +89,12 @@ jobs: python-version: ["3.14"] wine-compat: [""] include: + - os: ubuntu-22.04 + python-version: "3.15" + wine-compat: [""] + - os: ubuntu-22.04-arm] + python-version: "3.15" + wine-compat: [""] - os: windows-latest python-version: "3.14" wine-compat: "-WineCompat" diff --git a/pyproject.toml b/pyproject.toml index f889d835..e90f5210 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ "winrt-Windows.Graphics.Imaging >=3.2.1; sys_platform == 'win32'", # # Linux-only dependencies - "pillow>=12.2.0; sys_platform == 'linux'", # Security fix # Necessary for ImageGrab. + "pillow>=12.3.0.dev0; sys_platform == 'linux'", # Python 3.15 # Necessary for ImageGrab. "python-xlib >=0.33; sys_platform == 'linux'", ] [dependency-groups] @@ -79,11 +79,13 @@ dependency-metadata = [ exclude-newer = "1 week" [tool.uv.exclude-newer-package] # package = "3 days" # Reason +pillow = "" # Python 3.15 [tool.uv.sources] # Development channels beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config" } -# pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version == '3.15'" } +# pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version == '3.16'" } # numpy = { index = "scientific-python-nightly-wheels" } +pillow = { index = "scientific-python-nightly-wheels" } # Python 3.15 [[tool.uv.index]] # https://anaconda.org/scientific-python-nightly-wheels/ name = "scientific-python-nightly-wheels" diff --git a/uv.lock b/uv.lock index 2d4be776..dfa9cd0b 100644 --- a/uv.lock +++ b/uv.lock @@ -14,18 +14,6 @@ supported-markers = [ "sys_platform == 'win32'", ] -[options] -exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. -exclude-newer-span = "P1W" - -[manifest] - -[[manifest.dependency-metadata]] -name = "pyautogui" - -[[manifest.dependency-metadata]] -name = "types-pyautogui" - [[package]] name = "altgraph" version = "0.17.4" @@ -81,7 +69,7 @@ dependencies = [ { name = "numpy", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "opencv-contrib-python-headless", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pillow", marker = "sys_platform == 'linux'" }, + { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "sys_platform == 'linux'" }, { name = "pyautogui", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pygrabber", marker = "sys_platform == 'win32'" }, { name = "pyinstaller", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -128,7 +116,7 @@ requires-dist = [ { name = "numpy", specifier = ">=2.3.2" }, { name = "opencv-contrib-python-headless", specifier = ">=4.10" }, { name = "packaging", specifier = ">=20.0" }, - { name = "pillow", marker = "sys_platform == 'linux'", specifier = ">=12.2.0" }, + { name = "pillow", marker = "sys_platform == 'linux'", specifier = ">=12.3.0.dev0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, { name = "pyinstaller", specifier = ">=6.15.0" }, @@ -271,6 +259,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/62/b40b382fa0c66fee1478073eb8db352a4a6beda4a1adccf1df911d8c289c/librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253", size = 102572, upload-time = "2026-05-10T18:17:06.809Z" }, ] +[[package]] +name = "mouseinfo" +version = "0.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyperclip", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "python3-xlib", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850, upload-time = "2020-03-27T21:20:10.136Z" } + [[package]] name = "mypy" version = "2.1.0" @@ -397,31 +395,85 @@ wheels = [ name = "pillow" version = "12.2.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version < '3.15' and sys_platform == 'win32'", +] sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, - { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, - { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, - { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, - { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, - { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, - { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, - { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, - { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, - { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, - { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, - { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, - { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, + { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, + { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, +] + +[[package]] +name = "pillow" +version = "12.3.0.dev0" +source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", +] +wheels = [ + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-ios_13_0_arm64_iphoneos.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-musllinux_1_2_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-musllinux_1_2_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314t-musllinux_1_2_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314t-musllinux_1_2_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-ios_13_0_arm64_iphoneos.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-musllinux_1_2_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315-musllinux_1_2_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315t-musllinux_1_2_aarch64.whl" }, + { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp315-cp315t-musllinux_1_2_x86_64.whl" }, ] [[package]] name = "pyautogui" version = "0.9.54" source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mouseinfo", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pygetwindow", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pymsgbox", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pyscreeze", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "python3-xlib", marker = "sys_platform == 'linux'" }, + { name = "pytweening", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, +] sdist = { url = "https://files.pythonhosted.org/packages/65/ff/cdae0a8c2118a0de74b6cf4cbcdcaf8fd25857e6c3f205ce4b1794b27814/PyAutoGUI-0.9.54.tar.gz", hash = "sha256:dd1d29e8fd118941cb193f74df57e5c6ff8e9253b99c7b04f39cfc69f3ae04b2", size = 61236, upload-time = "2023-05-24T20:11:32.972Z" } +[[package]] +name = "pygetwindow" +version = "0.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyrect", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/70/c7a4f46dbf06048c6d57d9489b8e0f9c4c3d36b7479f03c5ca97eaa2541d/PyGetWindow-0.0.9.tar.gz", hash = "sha256:17894355e7d2b305cd832d717708384017c1698a90ce24f6f7fbf0242dd0a688", size = 9699, upload-time = "2020-10-04T02:12:50.806Z" } + [[package]] name = "pygrabber" version = "0.2" @@ -488,6 +540,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/13/076a20da28b82be281f7e43e16d9da0f545090f5d14b2125699232b9feba/PyMonCtl-0.92-py3-none-any.whl", hash = "sha256:2495d8dab78f9a7dbce37e74543e60b8bd404a35c3108935697dda7768611b5a", size = 45945, upload-time = "2024-04-22T10:07:09.566Z" }, ] +[[package]] +name = "pymsgbox" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/6a/e80da7594ee598a776972d09e2813df2b06b3bc29218f440631dfa7c78a8/pymsgbox-2.0.1.tar.gz", hash = "sha256:98d055c49a511dcc10fa08c3043e7102d468f5e4b3a83c6d3c61df722c7d798d", size = 20768, upload-time = "2025-09-09T00:38:56.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/3e/08c8cac81b2b2f7502746e6b9c8e5b0ec6432cd882c605560fc409aaf087/pymsgbox-2.0.1-py3-none-any.whl", hash = "sha256:5de8ec19bca2ca7e6c09d39c817c83f17c75cee80275235f43a9931db699f73b", size = 9994, upload-time = "2025-09-09T00:38:55.672Z" }, +] + +[[package]] +name = "pyperclip" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/52/d87eba7cb129b81563019d1679026e7a112ef76855d6159d24754dbd2a51/pyperclip-1.11.0.tar.gz", hash = "sha256:244035963e4428530d9e3a6101a1ef97209c6825edab1567beac148ccc1db1b6", size = 12185, upload-time = "2025-09-26T14:40:37.245Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" }, +] + +[[package]] +name = "pyrect" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/04/2ba023d5f771b645f7be0c281cdacdcd939fe13d1deb331fc5ed1a6b3a98/PyRect-0.2.0.tar.gz", hash = "sha256:f65155f6df9b929b67caffbd57c0947c5ae5449d3b580d178074bffb47a09b78", size = 17219, upload-time = "2022-03-16T04:45:52.36Z" } + [[package]] name = "pyright" version = "1.1.409" @@ -506,6 +582,12 @@ nodejs = [ { name = "nodejs-wheel-binaries", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] +[[package]] +name = "pyscreeze" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/f0/cb456ac4f1a73723d5b866933b7986f02bacea27516629c00f8e7da94c2d/pyscreeze-1.0.1.tar.gz", hash = "sha256:cf1662710f1b46aa5ff229ee23f367da9e20af4a78e6e365bee973cad0ead4be", size = 27826, upload-time = "2024-08-20T23:03:07.291Z" } + [[package]] name = "pyside6-essentials" version = "6.8.0.2" @@ -553,6 +635,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/b8/ff33610932e0ee81ae7f1269c890f697d56ff74b9f5b2ee5d9b7fa2c5355/python_xlib-0.33-py2.py3-none-any.whl", hash = "sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398", size = 182185, upload-time = "2022-12-25T18:52:58.662Z" }, ] +[[package]] +name = "python3-xlib" +version = "0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/c6/2c5999de3bb1533521f1101e8fe56fd9c266732f4d48011c7c69b29d12ae/python3-xlib-0.15.tar.gz", hash = "sha256:dc4245f3ae4aa5949c1d112ee4723901ade37a96721ba9645f2bfa56e5b383f8", size = 132828, upload-time = "2014-05-31T12:28:59.603Z" } + +[[package]] +name = "pytweening" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/0c/c16bc93ac2755bac0066a8ecbd2a2931a1735a6fffd99a2b9681c7e83e90/pytweening-1.2.0.tar.gz", hash = "sha256:243318b7736698066c5f362ec5c2b6434ecf4297c3c8e7caa8abfe6af4cac71b", size = 171241, upload-time = "2024-02-20T03:37:56.809Z" } + [[package]] name = "pywin32" version = "312" @@ -729,6 +823,9 @@ wheels = [ name = "types-pyautogui" version = "0.9.3.20241230" source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-pyscreeze", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, +] sdist = { url = "https://files.pythonhosted.org/packages/9b/b2/29e9a680f1eec37421261f8035310bccb74e7ffe51c108ab616149248086/types_pyautogui-0.9.3.20241230.tar.gz", hash = "sha256:e075f9815a4e7181dc3a63dabb5f266be7dbe9534fa9cb538075795db76d98ae", size = 9186, upload-time = "2024-12-30T02:44:52.239Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/75/51/b6e787b2837fa7e564ff27784630911db953c4c17f91d39c1814e0651e8a/types_PyAutoGUI-0.9.3.20241230-py3-none-any.whl", hash = "sha256:314a5e59bbb6292e53b41c7bbd4edb1197564b3dd00f569d3bc2f3f62bdc116c", size = 9020, upload-time = "2024-12-30T02:44:50.257Z" }, @@ -743,6 +840,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/fc/9d86a9c0aba04c60b5786a7929bdba4f5b97401ea1bc2ed8d7a485e026a4/types_pyinstaller-6.19.0.20260215-py3-none-any.whl", hash = "sha256:5e3af03dad356be22eb2524c1955149ebd4723ad1af529ac4fecf9d8fbc17ec1", size = 22064, upload-time = "2026-02-15T04:10:36.921Z" }, ] +[[package]] +name = "types-pyscreeze" +version = "1.0.1.20260518" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pillow", version = "12.2.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'win32'" }, + { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/37/640cfda01947ba49e8ffe0c01ee2d8d648a400d98892affaec0fd49b74a0/types_pyscreeze-1.0.1.20260518.tar.gz", hash = "sha256:882f10f9f0ba17e64a4a2db2633ce398ad5e812a22136ae49b407a7b2303c788", size = 9425, upload-time = "2026-05-18T06:07:09.891Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/35/fba48e94195bff53446a444016d0a19b015bda8c08b886fa4ad130c4583d/types_pyscreeze-1.0.1.20260518-py3-none-any.whl", hash = "sha256:cb4b47de51ddf2c811bc4435cb49377975cb1140b07816d2f18bc818586278c8", size = 8652, upload-time = "2026-05-18T06:07:08.568Z" }, +] + [[package]] name = "types-python-xlib" version = "0.33.0.20250809" From 6d35e4e780665c70c04e5d310d73df469e54995d Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 10 Jun 2026 20:19:10 -0400 Subject: [PATCH 02/50] Linux 3.15 builds --- pyproject.toml | 63 ++-------------------- pyrightconfig.json | 53 +++++++++++++++++++ uv.lock | 127 +++++++++++---------------------------------- 3 files changed, 88 insertions(+), 155 deletions(-) create mode 100644 pyrightconfig.json diff --git a/pyproject.toml b/pyproject.toml index e90f5210..49fbf119 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ "winrt-Windows.Graphics.Imaging >=3.2.1; sys_platform == 'win32'", # # Linux-only dependencies - "pillow>=12.3.0.dev0; sys_platform == 'linux'", # Python 3.15 # Necessary for ImageGrab. + "pillow>=12.2.0; sys_platform == 'linux'", # Security fix # Necessary for ImageGrab. # TODO: Bump when 3.15 wheels "python-xlib >=0.33; sys_platform == 'linux'", ] [dependency-groups] @@ -76,71 +76,18 @@ dependency-metadata = [ { name = "PyAutoGUI", requires-dist = [] }, { name = "types-PyAutoGUI", requires-dist = [] }, ] -exclude-newer = "1 week" +exclude-newer = "6 days" [tool.uv.exclude-newer-package] # package = "3 days" # Reason -pillow = "" # Python 3.15 [tool.uv.sources] # Development channels beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config" } -# pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version == '3.16'" } +# pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.16'" } # numpy = { index = "scientific-python-nightly-wheels" } -pillow = { index = "scientific-python-nightly-wheels" } # Python 3.15 +pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } [[tool.uv.index]] +exclude-newer = false # Anaconda index doesn't have upload dates # https://anaconda.org/scientific-python-nightly-wheels/ name = "scientific-python-nightly-wheels" url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" explicit = true - -# https://github.com/microsoft/pyright/blob/main/docs/configuration.md#sample-pyprojecttoml-file -[tool.pyright] -typeCheckingMode = "strict" -# Prefer `pyright: ignore` -enableTypeIgnoreComments = false - -### -# Downgraded diagnostics -### -# Type stubs may not be completable -reportMissingTypeStubs = "warning" -# Extra runtime safety -reportUnnecessaryComparison = "warning" -# Using Ruff instead. Name is already grayed out and red squiggle looks like a mistyped import -reportUnusedImport = "none" - -### -# Off by default even in strict mode -### -deprecateTypingAliases = true -enableExperimentalFeatures = true -reportCallInDefaultInitializer = "error" -reportImplicitOverride = "error" -reportImplicitStringConcatenation = "error" -# False positives with TYPE_CHECKING, mostly covered by Ruff TCH00 -reportImportCycles = "none" -# Too strict. False positives on base classes -reportMissingSuperCall = "none" -reportPropertyTypeMismatch = "error" -reportUninitializedInstanceVariable = "error" -reportUnnecessaryTypeIgnoreComment = "error" -reportUnusedCallResult = "none" - -# Exclude from scanning when running pyright -exclude = [ - # mypyc build folder - "build/", - # PyInstaller dist folder - "dist/", - # Auto generated, fails some strict pyright checks - "src/gen/", - # Defaults - "**/.*", - "**/__pycache__", - "**/node_modules", - ".venv", -] -# Ignore must be specified for Pylance to stop displaying errors -ignore = [ - # We expect stub files to be incomplete or contain useless statements - "**/*.pyi", -] diff --git a/pyrightconfig.json b/pyrightconfig.json new file mode 100644 index 00000000..82565bbb --- /dev/null +++ b/pyrightconfig.json @@ -0,0 +1,53 @@ +// https://github.com/microsoft/pyright/blob/main/docs/configuration.md//sample-config-file +{ + "typeCheckingMode": "strict", + // Prefer `pyright: ignore` + "enableTypeIgnoreComments": false, + + /** + * Downgraded diagnostics + */ + // Type stubs may not be completable + "reportMissingTypeStubs": "warning", + // Extra runtime safety + "reportUnnecessaryComparison": "warning", + // Using Ruff instead. Name is already grayed out and red squiggle looks like a mistyped import + "reportUnusedImport": "none", + + /** + * Off by default even in strict mode + */ + "deprecateTypingAliases": true, + "enableExperimentalFeatures": true, + "reportCallInDefaultInitializer": "error", + "reportImplicitOverride": "error", + "reportImplicitStringConcatenation": "error", + // False positives with TYPE_CHECKING, mostly covered by Ruff TCH00 + "reportImportCycles": "none", + // Too strict. False positives on base classes + "reportMissingSuperCall": "none", + "reportPropertyTypeMismatch": "error", + "reportUninitializedInstanceVariable": "error", + "reportUnnecessaryTypeIgnoreComment": "error", + "reportUnusedCallResult": "none", + + // Exclude from scanning when running pyright + "exclude": [ + // mypyc build folder + "build/", + // PyInstaller dist folder + "dist/", + // Auto generated, fails some strict pyright checks + "src/gen/", + // Defaults + "**/.*", + "**/__pycache__", + "**/node_modules", + ".venv", + ], + // Ignore must be specified for Pylance to stop displaying errors + "ignore": [ + // We expect stub files to be incomplete or contain useless statements + "**/*.pyi", + ], +} diff --git a/uv.lock b/uv.lock index dfa9cd0b..279f4453 100644 --- a/uv.lock +++ b/uv.lock @@ -14,6 +14,18 @@ supported-markers = [ "sys_platform == 'win32'", ] +[options] +exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. +exclude-newer-span = "P6D" + +[manifest] + +[[manifest.dependency-metadata]] +name = "pyautogui" + +[[manifest.dependency-metadata]] +name = "types-pyautogui" + [[package]] name = "altgraph" version = "0.17.4" @@ -69,7 +81,8 @@ dependencies = [ { name = "numpy", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "opencv-contrib-python-headless", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "sys_platform == 'linux'" }, + { name = "pillow", version = "12.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.15' and sys_platform == 'linux'" }, + { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "python_full_version >= '3.15' and sys_platform == 'linux'" }, { name = "pyautogui", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pygrabber", marker = "sys_platform == 'win32'" }, { name = "pyinstaller", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -116,7 +129,8 @@ requires-dist = [ { name = "numpy", specifier = ">=2.3.2" }, { name = "opencv-contrib-python-headless", specifier = ">=4.10" }, { name = "packaging", specifier = ">=20.0" }, - { name = "pillow", marker = "sys_platform == 'linux'", specifier = ">=12.3.0.dev0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, + { name = "pillow", marker = "python_full_version < '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0" }, + { name = "pillow", marker = "python_full_version >= '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, { name = "pyinstaller", specifier = ">=6.15.0" }, @@ -259,16 +273,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/62/b40b382fa0c66fee1478073eb8db352a4a6beda4a1adccf1df911d8c289c/librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253", size = 102572, upload-time = "2026-05-10T18:17:06.809Z" }, ] -[[package]] -name = "mouseinfo" -version = "0.1.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyperclip", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "python3-xlib", marker = "sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/28/fa/b2ba8229b9381e8f6381c1dcae6f4159a7f72349e414ed19cfbbd1817173/MouseInfo-0.1.3.tar.gz", hash = "sha256:2c62fb8885062b8e520a3cce0a297c657adcc08c60952eb05bc8256ef6f7f6e7", size = 10850, upload-time = "2020-03-27T21:20:10.136Z" } - [[package]] name = "mypy" version = "2.1.0" @@ -396,20 +400,26 @@ name = "pillow" version = "12.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version < '3.15' and sys_platform == 'win32'", + "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", ] sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, - { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, - { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, - { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, - { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, - { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, + { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, + { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, + { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, + { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, + { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, + { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, + { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, ] [[package]] @@ -418,9 +428,7 @@ version = "12.3.0.dev0" source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" } resolution-markers = [ "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", ] wheels = [ { url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple/pillow/12.3.0.dev0/pillow-12.3.0.dev0-cp314-cp314-ios_13_0_arm64_iphoneos.whl" }, @@ -455,25 +463,8 @@ wheels = [ name = "pyautogui" version = "0.9.54" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mouseinfo", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pygetwindow", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pymsgbox", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pyscreeze", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "python3-xlib", marker = "sys_platform == 'linux'" }, - { name = "pytweening", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, -] sdist = { url = "https://files.pythonhosted.org/packages/65/ff/cdae0a8c2118a0de74b6cf4cbcdcaf8fd25857e6c3f205ce4b1794b27814/PyAutoGUI-0.9.54.tar.gz", hash = "sha256:dd1d29e8fd118941cb193f74df57e5c6ff8e9253b99c7b04f39cfc69f3ae04b2", size = 61236, upload-time = "2023-05-24T20:11:32.972Z" } -[[package]] -name = "pygetwindow" -version = "0.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyrect", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e1/70/c7a4f46dbf06048c6d57d9489b8e0f9c4c3d36b7479f03c5ca97eaa2541d/PyGetWindow-0.0.9.tar.gz", hash = "sha256:17894355e7d2b305cd832d717708384017c1698a90ce24f6f7fbf0242dd0a688", size = 9699, upload-time = "2020-10-04T02:12:50.806Z" } - [[package]] name = "pygrabber" version = "0.2" @@ -540,30 +531,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/13/076a20da28b82be281f7e43e16d9da0f545090f5d14b2125699232b9feba/PyMonCtl-0.92-py3-none-any.whl", hash = "sha256:2495d8dab78f9a7dbce37e74543e60b8bd404a35c3108935697dda7768611b5a", size = 45945, upload-time = "2024-04-22T10:07:09.566Z" }, ] -[[package]] -name = "pymsgbox" -version = "2.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/6a/e80da7594ee598a776972d09e2813df2b06b3bc29218f440631dfa7c78a8/pymsgbox-2.0.1.tar.gz", hash = "sha256:98d055c49a511dcc10fa08c3043e7102d468f5e4b3a83c6d3c61df722c7d798d", size = 20768, upload-time = "2025-09-09T00:38:56.863Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/3e/08c8cac81b2b2f7502746e6b9c8e5b0ec6432cd882c605560fc409aaf087/pymsgbox-2.0.1-py3-none-any.whl", hash = "sha256:5de8ec19bca2ca7e6c09d39c817c83f17c75cee80275235f43a9931db699f73b", size = 9994, upload-time = "2025-09-09T00:38:55.672Z" }, -] - -[[package]] -name = "pyperclip" -version = "1.11.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/52/d87eba7cb129b81563019d1679026e7a112ef76855d6159d24754dbd2a51/pyperclip-1.11.0.tar.gz", hash = "sha256:244035963e4428530d9e3a6101a1ef97209c6825edab1567beac148ccc1db1b6", size = 12185, upload-time = "2025-09-26T14:40:37.245Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" }, -] - -[[package]] -name = "pyrect" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/04/2ba023d5f771b645f7be0c281cdacdcd939fe13d1deb331fc5ed1a6b3a98/PyRect-0.2.0.tar.gz", hash = "sha256:f65155f6df9b929b67caffbd57c0947c5ae5449d3b580d178074bffb47a09b78", size = 17219, upload-time = "2022-03-16T04:45:52.36Z" } - [[package]] name = "pyright" version = "1.1.409" @@ -582,12 +549,6 @@ nodejs = [ { name = "nodejs-wheel-binaries", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] -[[package]] -name = "pyscreeze" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/f0/cb456ac4f1a73723d5b866933b7986f02bacea27516629c00f8e7da94c2d/pyscreeze-1.0.1.tar.gz", hash = "sha256:cf1662710f1b46aa5ff229ee23f367da9e20af4a78e6e365bee973cad0ead4be", size = 27826, upload-time = "2024-08-20T23:03:07.291Z" } - [[package]] name = "pyside6-essentials" version = "6.8.0.2" @@ -635,18 +596,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/b8/ff33610932e0ee81ae7f1269c890f697d56ff74b9f5b2ee5d9b7fa2c5355/python_xlib-0.33-py2.py3-none-any.whl", hash = "sha256:c3534038d42e0df2f1392a1b30a15a4ff5fdc2b86cfa94f072bf11b10a164398", size = 182185, upload-time = "2022-12-25T18:52:58.662Z" }, ] -[[package]] -name = "python3-xlib" -version = "0.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ef/c6/2c5999de3bb1533521f1101e8fe56fd9c266732f4d48011c7c69b29d12ae/python3-xlib-0.15.tar.gz", hash = "sha256:dc4245f3ae4aa5949c1d112ee4723901ade37a96721ba9645f2bfa56e5b383f8", size = 132828, upload-time = "2014-05-31T12:28:59.603Z" } - -[[package]] -name = "pytweening" -version = "1.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/0c/c16bc93ac2755bac0066a8ecbd2a2931a1735a6fffd99a2b9681c7e83e90/pytweening-1.2.0.tar.gz", hash = "sha256:243318b7736698066c5f362ec5c2b6434ecf4297c3c8e7caa8abfe6af4cac71b", size = 171241, upload-time = "2024-02-20T03:37:56.809Z" } - [[package]] name = "pywin32" version = "312" @@ -823,9 +772,6 @@ wheels = [ name = "types-pyautogui" version = "0.9.3.20241230" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "types-pyscreeze", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, -] sdist = { url = "https://files.pythonhosted.org/packages/9b/b2/29e9a680f1eec37421261f8035310bccb74e7ffe51c108ab616149248086/types_pyautogui-0.9.3.20241230.tar.gz", hash = "sha256:e075f9815a4e7181dc3a63dabb5f266be7dbe9534fa9cb538075795db76d98ae", size = 9186, upload-time = "2024-12-30T02:44:52.239Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/75/51/b6e787b2837fa7e564ff27784630911db953c4c17f91d39c1814e0651e8a/types_PyAutoGUI-0.9.3.20241230-py3-none-any.whl", hash = "sha256:314a5e59bbb6292e53b41c7bbd4edb1197564b3dd00f569d3bc2f3f62bdc116c", size = 9020, upload-time = "2024-12-30T02:44:50.257Z" }, @@ -840,19 +786,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/fc/9d86a9c0aba04c60b5786a7929bdba4f5b97401ea1bc2ed8d7a485e026a4/types_pyinstaller-6.19.0.20260215-py3-none-any.whl", hash = "sha256:5e3af03dad356be22eb2524c1955149ebd4723ad1af529ac4fecf9d8fbc17ec1", size = 22064, upload-time = "2026-02-15T04:10:36.921Z" }, ] -[[package]] -name = "types-pyscreeze" -version = "1.0.1.20260518" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pillow", version = "12.2.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'win32'" }, - { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/de/37/640cfda01947ba49e8ffe0c01ee2d8d648a400d98892affaec0fd49b74a0/types_pyscreeze-1.0.1.20260518.tar.gz", hash = "sha256:882f10f9f0ba17e64a4a2db2633ce398ad5e812a22136ae49b407a7b2303c788", size = 9425, upload-time = "2026-05-18T06:07:09.891Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/35/fba48e94195bff53446a444016d0a19b015bda8c08b886fa4ad130c4583d/types_pyscreeze-1.0.1.20260518-py3-none-any.whl", hash = "sha256:cb4b47de51ddf2c811bc4435cb49377975cb1140b07816d2f18bc818586278c8", size = 8652, upload-time = "2026-05-18T06:07:08.568Z" }, -] - [[package]] name = "types-python-xlib" version = "0.33.0.20250809" From 72290024d7047118f85a4bf49a83baab1987cba0 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 10 Jun 2026 20:44:18 -0400 Subject: [PATCH 03/50] Add lazy imports --- src/AutoControlledThread.py | 2 ++ src/AutoSplit.py | 27 ++++++++++++++++++- src/AutoSplitImage.py | 9 +++++++ src/capture_method/BitBltCaptureMethod.py | 10 +++++++ src/capture_method/CaptureMethodBase.py | 2 ++ .../DesktopDuplicationCaptureMethod.py | 2 ++ .../Screenshot using QT attempt.py | 2 ++ src/capture_method/ScrotCaptureMethod.py | 10 +++++++ .../VideoCaptureDeviceCaptureMethod.py | 2 ++ .../WindowsGraphicsCaptureMethod.py | 14 ++++++++++ src/capture_method/XcbCaptureMethod.py | 11 ++++++++ src/capture_method/__init__.py | 9 +++++++ src/compare.py | 9 +++++++ src/d3d11.py | 2 ++ src/error_messages.py | 2 ++ src/hotkeys.py | 2 ++ src/menu_bar.py | 18 +++++++++++++ src/region_selection.py | 12 +++++++++ src/split_parser.py | 10 +++++++ src/user_profile.py | 12 +++++++++ src/utils.py | 19 +++++++++++++ uv.lock | 4 +-- 22 files changed, 187 insertions(+), 3 deletions(-) diff --git a/src/AutoControlledThread.py b/src/AutoControlledThread.py index 2375f3c5..cee08619 100644 --- a/src/AutoControlledThread.py +++ b/src/AutoControlledThread.py @@ -1,5 +1,7 @@ from __future__ import annotations +__lazy_modules__ = {"error_messages", "user_profile"} + from typing import TYPE_CHECKING from PySide6 import QtCore diff --git a/src/AutoSplit.py b/src/AutoSplit.py index deec9b5e..cfee2101 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -1,4 +1,29 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 + +__lazy_modules__ = { + "AutoControlledThread", + "AutoSplitImage", + "PySide6", + "PySide6.QtTest", + "capture_method", + "capture_method.CaptureMethodBase", + "collections", + "collections.abc", + "copy", + "cv2", + "error_messages", + "hotkeys", + "menu_bar", + "region_selection", + "signal", + "split_parser", + "types", + "user_profile", + "utils", + "win32comext", + "win32comext.shell", +} + import os import sys diff --git a/src/AutoSplitImage.py b/src/AutoSplitImage.py index 6b04852f..c5758e79 100644 --- a/src/AutoSplitImage.py +++ b/src/AutoSplitImage.py @@ -1,5 +1,14 @@ from __future__ import annotations +__lazy_modules__ = { + "compare", + "cv2", + "error_messages", + "math", + "split_parser", + "tomllib", +} + import os import tomllib from enum import IntEnum, auto diff --git a/src/capture_method/BitBltCaptureMethod.py b/src/capture_method/BitBltCaptureMethod.py index 26eedb34..60ef6956 100644 --- a/src/capture_method/BitBltCaptureMethod.py +++ b/src/capture_method/BitBltCaptureMethod.py @@ -1,3 +1,13 @@ +__lazy_modules__ = { + "ctypes", + "numpy", + "pywintypes", + "utils", + "win32con", + "win32gui", + "win32ui", +} + import sys if sys.platform != "win32": diff --git a/src/capture_method/CaptureMethodBase.py b/src/capture_method/CaptureMethodBase.py index 3a937e7e..e8e386b0 100644 --- a/src/capture_method/CaptureMethodBase.py +++ b/src/capture_method/CaptureMethodBase.py @@ -1,5 +1,7 @@ from __future__ import annotations +__lazy_modules__ = {"utils"} + from typing import TYPE_CHECKING from utils import is_valid_hwnd diff --git a/src/capture_method/DesktopDuplicationCaptureMethod.py b/src/capture_method/DesktopDuplicationCaptureMethod.py index fc03206b..fa664991 100644 --- a/src/capture_method/DesktopDuplicationCaptureMethod.py +++ b/src/capture_method/DesktopDuplicationCaptureMethod.py @@ -1,5 +1,7 @@ from __future__ import annotations +__lazy_modules__ = {"cv2", "utils", "win32api", "win32con", "win32gui"} + import sys if sys.platform != "win32": diff --git a/src/capture_method/Screenshot using QT attempt.py b/src/capture_method/Screenshot using QT attempt.py index 27fbe542..819eb389 100644 --- a/src/capture_method/Screenshot using QT attempt.py +++ b/src/capture_method/Screenshot using QT attempt.py @@ -1,3 +1,5 @@ +__lazy_modules__ = {"PySide6", "PySide6.QtCore", "PySide6.QtGui", "numpy"} + import sys if sys.platform != "linux": diff --git a/src/capture_method/ScrotCaptureMethod.py b/src/capture_method/ScrotCaptureMethod.py index 834a9686..80373083 100644 --- a/src/capture_method/ScrotCaptureMethod.py +++ b/src/capture_method/ScrotCaptureMethod.py @@ -1,3 +1,13 @@ +__lazy_modules__ = { + "Xlib", + "Xlib.display", + "Xlib.error", + "cv2", + "pywinctl", + "subprocess", + "tempfile", +} + import sys if sys.platform != "linux": diff --git a/src/capture_method/VideoCaptureDeviceCaptureMethod.py b/src/capture_method/VideoCaptureDeviceCaptureMethod.py index d824802d..861003f3 100644 --- a/src/capture_method/VideoCaptureDeviceCaptureMethod.py +++ b/src/capture_method/VideoCaptureDeviceCaptureMethod.py @@ -1,5 +1,7 @@ from __future__ import annotations +__lazy_modules__ = {"cv2", "cv2.Error", "error_messages", "numpy", "threading", "utils"} + from threading import Event, Thread from typing import TYPE_CHECKING, override diff --git a/src/capture_method/WindowsGraphicsCaptureMethod.py b/src/capture_method/WindowsGraphicsCaptureMethod.py index 9058a483..17bfeaeb 100644 --- a/src/capture_method/WindowsGraphicsCaptureMethod.py +++ b/src/capture_method/WindowsGraphicsCaptureMethod.py @@ -1,5 +1,19 @@ from __future__ import annotations +__lazy_modules__ = { + "asyncio", + "d3d11", + "numpy", + "win32gui", + "winrt", + "winrt.windows", + "winrt.windows.graphics.capture", + "winrt.windows.graphics.capture.interop", + "winrt.windows.graphics.directx", + "winrt.windows.graphics.directx.direct3d11.interop", + "winrt.windows.graphics.imaging", +} + import sys if sys.platform != "win32": diff --git a/src/capture_method/XcbCaptureMethod.py b/src/capture_method/XcbCaptureMethod.py index 901df671..6a16ade8 100644 --- a/src/capture_method/XcbCaptureMethod.py +++ b/src/capture_method/XcbCaptureMethod.py @@ -1,3 +1,14 @@ +__lazy_modules__ = { + "PIL", + "Xlib", + "Xlib.display", + "Xlib.error", + "cv2", + "numpy", + "pywinctl", + "utils", +} + import sys if sys.platform != "linux": diff --git a/src/capture_method/__init__.py b/src/capture_method/__init__.py index feb5b51e..7ec172d7 100644 --- a/src/capture_method/__init__.py +++ b/src/capture_method/__init__.py @@ -1,5 +1,14 @@ from __future__ import annotations +__lazy_modules__ = { + "fcntl", + "itertools", + "pathlib", + "utils", + "vidioc_querycap", + "winerror", +} + import sys from collections import OrderedDict from dataclasses import dataclass diff --git a/src/compare.py b/src/compare.py index 574c9c8f..c357803d 100644 --- a/src/compare.py +++ b/src/compare.py @@ -1,3 +1,12 @@ +__lazy_modules__ = { + "Levenshtein", + "collections", + "collections.abc", + "cv2", + "math", + "numpy", +} + from collections.abc import Iterable from math import sqrt from typing import TYPE_CHECKING diff --git a/src/d3d11.py b/src/d3d11.py index a268f335..c2fcfac2 100644 --- a/src/d3d11.py +++ b/src/d3d11.py @@ -2,6 +2,8 @@ # Copyright (c) 2024 David Lechner from __future__ import annotations +__lazy_modules__ = {"uuid"} + import sys if sys.platform != "win32": diff --git a/src/error_messages.py b/src/error_messages.py index 3c41479c..87019fb5 100644 --- a/src/error_messages.py +++ b/src/error_messages.py @@ -2,6 +2,8 @@ from __future__ import annotations +__lazy_modules__ = {"PySide6", "signal", "traceback", "types"} + import os import signal import sys diff --git a/src/hotkeys.py b/src/hotkeys.py index c6825520..918880c6 100644 --- a/src/hotkeys.py +++ b/src/hotkeys.py @@ -1,5 +1,7 @@ from __future__ import annotations +__lazy_modules__ = {"collections", "collections.abc", "error_messages", "keyboard"} + import sys from collections.abc import Callable from typing import TYPE_CHECKING, Literal, cast diff --git a/src/menu_bar.py b/src/menu_bar.py index 23cb5e02..bfd44bd6 100644 --- a/src/menu_bar.py +++ b/src/menu_bar.py @@ -1,5 +1,23 @@ from __future__ import annotations +__lazy_modules__ = { + "PySide6.QtCore", + "PySide6.QtGui", + "PySide6.QtWidgets", + "capture_method", + "functools", + "hotkeys", + "json", + "packaging", + "packaging.version", + "urllib", + "urllib.error", + "urllib.request", + "user_profile", + "utils", + "webbrowser", +} + import json import sys import webbrowser diff --git a/src/region_selection.py b/src/region_selection.py index 67e53f37..ec592fa0 100644 --- a/src/region_selection.py +++ b/src/region_selection.py @@ -1,5 +1,17 @@ from __future__ import annotations +__lazy_modules__ = { + "PySide6.QtTest", + "capture_method", + "cv2", + "error_messages", + "math", + "numpy", + "pywinctl", + "utils", + "win32gui", +} + import sys from math import ceil from typing import TYPE_CHECKING, override diff --git a/src/split_parser.py b/src/split_parser.py index 333a08d0..8348d921 100644 --- a/src/split_parser.py +++ b/src/split_parser.py @@ -1,5 +1,15 @@ from __future__ import annotations +__lazy_modules__ = { + "AutoSplitImage", + "collections", + "collections.abc", + "error_messages", + "functools", + "re", + "utils", +} + import os import re import sys diff --git a/src/user_profile.py b/src/user_profile.py index 6aa93cd2..9b115148 100644 --- a/src/user_profile.py +++ b/src/user_profile.py @@ -1,5 +1,17 @@ from __future__ import annotations +__lazy_modules__ = { + "PySide6", + "copy", + "error_messages", + "hotkeys", + "menu_bar", + "tomli_w", + "tomllib", + "utils", + "warnings", +} + import os import tomllib from copy import deepcopy diff --git a/src/utils.py b/src/utils.py index 097a7215..d32c006d 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,5 +1,24 @@ from __future__ import annotations +__lazy_modules__ = { + "_ctypes", + "asyncio", + "collections", + "collections.abc", + "ctypes", + "ctypes.wintypes", + "fcntl", + "functools", + "itertools", + "numpy", + "pathlib", + "shutil", + "threading", + "win32gui", + "win32ui", + "winerror", +} + import asyncio import os import shutil diff --git a/uv.lock b/uv.lock index 279f4453..3fc034b2 100644 --- a/uv.lock +++ b/uv.lock @@ -172,8 +172,8 @@ ruff = [ [[package]] name = "beslogic-ruff-config" -version = "1.0.1" -source = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config#dd94f26b1de7234195d1a52cc3f9e6ac65b8ca51" } +version = "1.1.0" +source = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config#312cfab8a1e2653639a2ef665e99eac6c7412ba7" } dependencies = [ { name = "ruff", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] From 99e080466de343ddf53f07645502a200aa1c9d53 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:45:17 +0000 Subject: [PATCH 04/50] [autofix.ci] apply automated fixes --- src/AutoSplit.py | 2 +- src/menu_bar.py | 2 +- src/user_profile.py | 3 ++- src/utils.py | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index cfee2101..fffd3c13 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -60,6 +60,7 @@ def do_nothing(*_): ... from typing import TYPE_CHECKING, NoReturn, override import cv2 +from gen import about, design, settings, update_checker from PySide6 import QtCore, QtGui from PySide6.QtTest import QTest from PySide6.QtWidgets import QApplication, QFileDialog, QLabel, QMainWindow, QMessageBox @@ -70,7 +71,6 @@ def do_nothing(*_): ... from AutoSplitImage import START_KEYWORD, AutoSplitImage, ImageType from capture_method import CaptureMethodEnum from capture_method.CaptureMethodBase import CaptureMethodBase -from gen import about, design, settings, update_checker from hotkeys import ( HOTKEYS, KEYBOARD_GROUPS_ISSUE, diff --git a/src/menu_bar.py b/src/menu_bar.py index bfd44bd6..c4eb34f7 100644 --- a/src/menu_bar.py +++ b/src/menu_bar.py @@ -26,6 +26,7 @@ from urllib.error import URLError from urllib.request import urlopen +from gen import about, design, settings as settings_ui, update_checker from packaging.version import parse as version_parse from PySide6 import QtCore, QtWidgets from PySide6.QtCore import Qt @@ -41,7 +42,6 @@ change_capture_method, get_all_video_capture_devices, ) -from gen import about, design, settings as settings_ui, update_checker from hotkeys import HOTKEYS, HOTKEYS_WHEN_AUTOCONTROLLED, CommandStr, set_hotkey from utils import AUTOSPLIT_VERSION, GITHUB_REPOSITORY, ONE_SECOND, decimal, fire_and_forget diff --git a/src/user_profile.py b/src/user_profile.py index 9b115148..0b6e8295 100644 --- a/src/user_profile.py +++ b/src/user_profile.py @@ -28,9 +28,10 @@ from utils import auto_split_directory if TYPE_CHECKING: - from AutoSplit import AutoSplit from gen import design + from AutoSplit import AutoSplit + class UserProfileDict(TypedDict): split_hotkey: str diff --git a/src/utils.py b/src/utils.py index d32c006d..39323a40 100644 --- a/src/utils.py +++ b/src/utils.py @@ -36,7 +36,6 @@ import cv2 import numpy as np - from gen.build_vars import AUTOSPLIT_BUILD_NUMBER, AUTOSPLIT_GITHUB_REPOSITORY if sys.platform == "win32": From 42c2ca7522637321470af1e69ed91caf3b8d2426 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:50:45 +0000 Subject: [PATCH 05/50] [autofix.ci] apply automated fixes --- src/AutoSplit.py | 2 +- src/menu_bar.py | 2 +- src/user_profile.py | 3 +-- src/utils.py | 1 + 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index fffd3c13..cfee2101 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -60,7 +60,6 @@ def do_nothing(*_): ... from typing import TYPE_CHECKING, NoReturn, override import cv2 -from gen import about, design, settings, update_checker from PySide6 import QtCore, QtGui from PySide6.QtTest import QTest from PySide6.QtWidgets import QApplication, QFileDialog, QLabel, QMainWindow, QMessageBox @@ -71,6 +70,7 @@ def do_nothing(*_): ... from AutoSplitImage import START_KEYWORD, AutoSplitImage, ImageType from capture_method import CaptureMethodEnum from capture_method.CaptureMethodBase import CaptureMethodBase +from gen import about, design, settings, update_checker from hotkeys import ( HOTKEYS, KEYBOARD_GROUPS_ISSUE, diff --git a/src/menu_bar.py b/src/menu_bar.py index c4eb34f7..bfd44bd6 100644 --- a/src/menu_bar.py +++ b/src/menu_bar.py @@ -26,7 +26,6 @@ from urllib.error import URLError from urllib.request import urlopen -from gen import about, design, settings as settings_ui, update_checker from packaging.version import parse as version_parse from PySide6 import QtCore, QtWidgets from PySide6.QtCore import Qt @@ -42,6 +41,7 @@ change_capture_method, get_all_video_capture_devices, ) +from gen import about, design, settings as settings_ui, update_checker from hotkeys import HOTKEYS, HOTKEYS_WHEN_AUTOCONTROLLED, CommandStr, set_hotkey from utils import AUTOSPLIT_VERSION, GITHUB_REPOSITORY, ONE_SECOND, decimal, fire_and_forget diff --git a/src/user_profile.py b/src/user_profile.py index 0b6e8295..9b115148 100644 --- a/src/user_profile.py +++ b/src/user_profile.py @@ -28,9 +28,8 @@ from utils import auto_split_directory if TYPE_CHECKING: - from gen import design - from AutoSplit import AutoSplit + from gen import design class UserProfileDict(TypedDict): diff --git a/src/utils.py b/src/utils.py index 39323a40..d32c006d 100644 --- a/src/utils.py +++ b/src/utils.py @@ -36,6 +36,7 @@ import cv2 import numpy as np + from gen.build_vars import AUTOSPLIT_BUILD_NUMBER, AUTOSPLIT_GITHUB_REPOSITORY if sys.platform == "win32": From 7ee9bedaca0b6edde99208aec600a044d4755dbb Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 10 Jun 2026 21:21:14 -0400 Subject: [PATCH 06/50] Apply suggestion from @Avasam --- .github/workflows/lint-and-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 23711e85..06420b78 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -92,7 +92,7 @@ jobs: - os: ubuntu-22.04 python-version: "3.15" wine-compat: [""] - - os: ubuntu-22.04-arm] + - os: ubuntu-22.04-arm python-version: "3.15" wine-compat: [""] - os: windows-latest From 8e737e7208a4c67870ff57e4ffcfc33b6651d72c Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 10 Jun 2026 23:46:06 -0400 Subject: [PATCH 07/50] pickup local wheels --- pyproject.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 49fbf119..a7f2c4f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,18 +76,24 @@ dependency-metadata = [ { name = "PyAutoGUI", requires-dist = [] }, { name = "types-PyAutoGUI", requires-dist = [] }, ] +find-links = ["./scripts"] # Discover local wheels + exclude-newer = "6 days" [tool.uv.exclude-newer-package] # package = "3 days" # Reason -[tool.uv.sources] # Development channels +### +# Development channels +### +[tool.uv.sources] beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config" } # pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.16'" } # numpy = { index = "scientific-python-nightly-wheels" } pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } + [[tool.uv.index]] exclude-newer = false # Anaconda index doesn't have upload dates # https://anaconda.org/scientific-python-nightly-wheels/ name = "scientific-python-nightly-wheels" url = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" -explicit = true +explicit = true # Avoid index hijacking From 125988c165a6bbd255311fe17539ba8bd7d63153 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 00:02:08 -0400 Subject: [PATCH 08/50] Move CMAKE_ARGS to shared local + CI install script --- .github/workflows/lint-and-build.yml | 4 ---- scripts/install.ps1 | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 06420b78..9f077b55 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -32,10 +32,6 @@ env: GITHUB_EXCLUDE_BUILD_NUMBER: ${{ inputs.excludeBuildNumber }} UV_NO_SYNC: true # Avoid accidentally pulling in dependency-groups with uv run APPIMAGE_EXTRACT_AND_RUN: true # Avoid needing libfuse2 - # https://github.com/opencv/opencv-python#source-distributions - # Allows building OpenCV on Windows ARM64 - # https://github.com/opencv/opencv-python/issues/1092#issuecomment-2862538656 - CMAKE_ARGS: "-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 6d7f6e5c..16485f0c 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -87,6 +87,11 @@ if (` Remove-Item $PSScriptRoot/.upx/$UPXFolderName } +# https://github.com/opencv/opencv-python#source-distributions +# Allows building OpenCV on Windows ARM64 +# https://github.com/opencv/opencv-python/issues/1092#issuecomment-2862538656 +$Env:CMAKE_ARGS = '-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF' + $prod = if ($Env:GITHUB_JOB -eq 'Build') { '--no-dev' } else { } $lock = if ($Env:GITHUB_JOB) { '--locked' } else { } Write-Output "Installing Python dependencies with: uv sync $prod $lock" From 9e3ae66addcf59d39970671a6efd4df1be9bc016 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 01:06:57 -0400 Subject: [PATCH 09/50] Verbose uv sync --- scripts/install.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 16485f0c..250b164c 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -95,7 +95,8 @@ $Env:CMAKE_ARGS = '-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF' $prod = if ($Env:GITHUB_JOB -eq 'Build') { '--no-dev' } else { } $lock = if ($Env:GITHUB_JOB) { '--locked' } else { } Write-Output "Installing Python dependencies with: uv sync $prod $lock" -uv sync --active $prod $lock +# Verbose to see sdist progression +uv sync --verbose --active $prod $lock # Don't compile resources on the Build CI job as it'll do so in build script if (-not $prod) { From b610b8a4e5f4efa74899a3484fe7fb810141458f Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 20:35:16 -0400 Subject: [PATCH 10/50] pyinstaller 3.15 --- pyproject.toml | 6 +++-- uv.lock | 68 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a7f2c4f0..723ea728 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,9 +87,11 @@ exclude-newer = "6 days" ### [tool.uv.sources] beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config" } -# pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.16'" } -# numpy = { index = "scientific-python-nightly-wheels" } +# pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.15'" } +# numpy = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } +# pyinstaller = { url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip", marker = "python_version >= '3.15'" } +pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller", rev = "9803892a21f84c695885ca85c14dbad47a283a32", marker = "python_version >= '3.15'" } [[tool.uv.index]] exclude-newer = false # Anaconda index doesn't have upload dates diff --git a/uv.lock b/uv.lock index 3fc034b2..5484f210 100644 --- a/uv.lock +++ b/uv.lock @@ -85,7 +85,8 @@ dependencies = [ { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "python_full_version >= '3.15' and sys_platform == 'linux'" }, { name = "pyautogui", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pygrabber", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pyinstaller", version = "6.17.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pyinstaller", version = "6.20.0", source = { git = "https://github.com/pyinstaller/pyinstaller?rev=9803892a21f84c695885ca85c14dbad47a283a32#9803892a21f84c695885ca85c14dbad47a283a32" }, marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, { name = "pyside6-essentials", version = "6.8.0.2", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, { name = "pyside6-essentials", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'" }, { name = "python-xlib", marker = "sys_platform == 'linux'" }, @@ -133,7 +134,8 @@ requires-dist = [ { name = "pillow", marker = "python_full_version >= '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, - { name = "pyinstaller", specifier = ">=6.15.0" }, + { name = "pyinstaller", marker = "python_full_version < '3.15'", specifier = ">=6.15.0" }, + { name = "pyinstaller", marker = "python_full_version >= '3.15'", git = "https://github.com/pyinstaller/pyinstaller?rev=9803892a21f84c695885ca85c14dbad47a283a32" }, { name = "pyside6-essentials", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'", specifier = ">=6.9.0" }, { name = "pyside6-essentials", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'", specifier = "<6.8.1" }, { name = "python-xlib", marker = "sys_platform == 'linux'", specifier = ">=0.33" }, @@ -482,13 +484,18 @@ wheels = [ name = "pyinstaller" version = "6.17.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and sys_platform == 'win32'", +] dependencies = [ - { name = "altgraph", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pefile", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, - { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "altgraph", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "packaging", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pefile", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", version = "2025.10", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pywin32-ctypes", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, + { name = "setuptools", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/01/80/9e0dad9c69a7cfd4b5aaede8c6225d762bab7247a2a6b7651e1995522001/pyinstaller-6.17.0.tar.gz", hash = "sha256:be372bd911392b88277e510940ac32a5c2a6ce4b8d00a311c78fa443f4f27313", size = 4014147, upload-time = "2025-11-24T19:43:32.109Z" } wheels = [ @@ -504,19 +511,60 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/96/14991773c9e599707a53594429ccf372f9ee638df3b7d26b65fd1a7433f0/pyinstaller-6.17.0-py3-none-win_arm64.whl", hash = "sha256:3c92a335e338170df7e615f75279cfeea97ade89e6dd7694943c8c185460f7b7", size = 1320032, upload-time = "2025-11-24T19:43:16.388Z" }, ] +[[package]] +name = "pyinstaller" +version = "6.20.0" +source = { git = "https://github.com/pyinstaller/pyinstaller?rev=9803892a21f84c695885ca85c14dbad47a283a32#9803892a21f84c695885ca85c14dbad47a283a32" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and sys_platform == 'win32'", +] +dependencies = [ + { name = "altgraph", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "packaging", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "pefile", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", version = "2026.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "pywin32-ctypes", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, + { name = "setuptools", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, +] + [[package]] name = "pyinstaller-hooks-contrib" version = "2025.10" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and sys_platform == 'win32'", +] dependencies = [ - { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "packaging", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "setuptools", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/4f/e33132acdb8f732978e577b8a0130a412cbfe7a3414605e3fd380a975522/pyinstaller_hooks_contrib-2025.10.tar.gz", hash = "sha256:a1a737e5c0dccf1cf6f19a25e2efd109b9fec9ddd625f97f553dac16ee884881", size = 168155, upload-time = "2025-11-22T09:34:36.138Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/86/de/a7688eed49a1d3df337cdaa4c0d64e231309a52f269850a72051975e3c4a/pyinstaller_hooks_contrib-2025.10-py3-none-any.whl", hash = "sha256:aa7a378518772846221f63a84d6306d9827299323243db890851474dfd1231a9", size = 447760, upload-time = "2025-11-22T09:34:34.753Z" }, ] +[[package]] +name = "pyinstaller-hooks-contrib" +version = "2026.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and sys_platform == 'win32'", +] +dependencies = [ + { name = "packaging", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "setuptools", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1a/67/f4452d68793fb15beba4f19ef39a38a8822f0da7452b503c400d5a21f5c1/pyinstaller_hooks_contrib-2026.5.tar.gz", hash = "sha256:f066dfca8f7c45ff6336c9cf9fe25b4e48bfeb322a1aa24faaedfb8a8d1b0b08", size = 173689, upload-time = "2026-05-04T22:36:55.124Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/5c/fd465d11da4d12b50d7eb5d2ee2ceb780d8d049dbb489f3828d131e387af/pyinstaller_hooks_contrib-2026.5-py3-none-any.whl", hash = "sha256:ea1535783fbdac4626351709e83f3ea80b681d3a4745763ebb407b5e27342eb9", size = 457314, upload-time = "2026-05-04T22:36:53.598Z" }, +] + [[package]] name = "pymonctl" version = "0.92" From bcb9c96579bf2fd97361c1b423192ba56c5c5d48 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 21:09:22 -0400 Subject: [PATCH 11/50] Fix build script --- scripts/build.ps1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index fdd36757..483de199 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -9,10 +9,20 @@ Push-Location "$PSScriptRoot/.." # Avoid issues with space in path try { & 'scripts/compile_resources.ps1' + # TODO: Remove condition once using the same version across all python $SupportsSplashScreen = [System.Convert]::ToBoolean( $(uv run --active python -c ' +import sys from PyInstaller.building.splash import Splash -Splash._check_tcl_tk_compatibility() +try: + if sys.version_info >= (3, 15): + from PyInstaller.utils.hooks.tcl_tk import tcltk_info + Splash._check_tcl_tk_compatibility(tcltk_info) + Splash._check_tcl_tk_compatibility() + print(True) +except SystemExit as e: + print(e, file=sys.stderr) + print(False) ')) $arguments = @( From 0542ae58f29b65002ca62a2f7ce46ee6310c8d4d Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 21:13:19 -0400 Subject: [PATCH 12/50] Add Windows 3.15 prebuilds --- .github/workflows/lint-and-build.yml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 9f077b55..057f012e 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -46,10 +46,7 @@ jobs: matrix: # arm runner slower as long as opencv doesn't provide arm64 wheels os: [windows-latest, ubuntu-latest] - python-version: ["3.14"] - include: - - os: ubuntu-latest - python-version: "3.15" + python-version: ["3.14", "3.15"] steps: - uses: actions/checkout@v6 - name: Set up uv for Python ${{ matrix.python-version }} @@ -82,18 +79,15 @@ jobs: # Only the Python version we plan on shipping matters. matrix: os: [windows-latest, windows-11-arm, ubuntu-22.04, ubuntu-22.04-arm] - python-version: ["3.14"] + python-version: ["3.14", "3.15"] wine-compat: [""] include: - - os: ubuntu-22.04 - python-version: "3.15" - wine-compat: [""] - - os: ubuntu-22.04-arm - python-version: "3.15" - wine-compat: [""] - os: windows-latest python-version: "3.14" wine-compat: "-WineCompat" + - os: windows-latest + python-version: "3.15" + wine-compat: "-WineCompat" steps: - uses: actions/checkout@v6 # https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 From 85a42303a196bb9b66dd23f07db4c33c9b14b083 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 21:33:38 -0400 Subject: [PATCH 13/50] Use lazy filter --- pyproject.toml | 2 +- src/AutoControlledThread.py | 2 -- src/AutoSplit.py | 28 ++----------------- src/AutoSplitImage.py | 9 ------ src/capture_method/BitBltCaptureMethod.py | 10 ------- src/capture_method/CaptureMethodBase.py | 2 -- .../DesktopDuplicationCaptureMethod.py | 2 -- .../Screenshot using QT attempt.py | 2 -- src/capture_method/ScrotCaptureMethod.py | 10 ------- .../VideoCaptureDeviceCaptureMethod.py | 2 -- .../WindowsGraphicsCaptureMethod.py | 14 ---------- src/capture_method/XcbCaptureMethod.py | 11 -------- src/capture_method/__init__.py | 9 ------ src/compare.py | 9 ------ src/d3d11.py | 2 -- src/error_messages.py | 2 -- src/hotkeys.py | 2 -- src/menu_bar.py | 18 ------------ src/region_selection.py | 12 -------- src/split_parser.py | 10 ------- src/user_profile.py | 12 -------- src/utils.py | 19 ------------- 22 files changed, 4 insertions(+), 185 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 723ea728..ee47ed80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,7 +78,7 @@ dependency-metadata = [ ] find-links = ["./scripts"] # Discover local wheels -exclude-newer = "6 days" +exclude-newer = "1 week" [tool.uv.exclude-newer-package] # package = "3 days" # Reason diff --git a/src/AutoControlledThread.py b/src/AutoControlledThread.py index cee08619..2375f3c5 100644 --- a/src/AutoControlledThread.py +++ b/src/AutoControlledThread.py @@ -1,7 +1,5 @@ from __future__ import annotations -__lazy_modules__ = {"error_messages", "user_profile"} - from typing import TYPE_CHECKING from PySide6 import QtCore diff --git a/src/AutoSplit.py b/src/AutoSplit.py index cfee2101..a1e7845d 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -1,32 +1,10 @@ #!/usr/bin/env python3 - -__lazy_modules__ = { - "AutoControlledThread", - "AutoSplitImage", - "PySide6", - "PySide6.QtTest", - "capture_method", - "capture_method.CaptureMethodBase", - "collections", - "collections.abc", - "copy", - "cv2", - "error_messages", - "hotkeys", - "menu_bar", - "region_selection", - "signal", - "split_parser", - "types", - "user_profile", - "utils", - "win32comext", - "win32comext.shell", -} - import os import sys +if sys.version_info >= (3, 15): + sys.set_lazy_imports("all") + # Prevent PyAutoGUI and pywinctl from setting Process DPI Awareness, # which Qt tries to do then throws warnings about it. # The unittest workaround significantly increases diff --git a/src/AutoSplitImage.py b/src/AutoSplitImage.py index c5758e79..6b04852f 100644 --- a/src/AutoSplitImage.py +++ b/src/AutoSplitImage.py @@ -1,14 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "compare", - "cv2", - "error_messages", - "math", - "split_parser", - "tomllib", -} - import os import tomllib from enum import IntEnum, auto diff --git a/src/capture_method/BitBltCaptureMethod.py b/src/capture_method/BitBltCaptureMethod.py index 60ef6956..26eedb34 100644 --- a/src/capture_method/BitBltCaptureMethod.py +++ b/src/capture_method/BitBltCaptureMethod.py @@ -1,13 +1,3 @@ -__lazy_modules__ = { - "ctypes", - "numpy", - "pywintypes", - "utils", - "win32con", - "win32gui", - "win32ui", -} - import sys if sys.platform != "win32": diff --git a/src/capture_method/CaptureMethodBase.py b/src/capture_method/CaptureMethodBase.py index e8e386b0..3a937e7e 100644 --- a/src/capture_method/CaptureMethodBase.py +++ b/src/capture_method/CaptureMethodBase.py @@ -1,7 +1,5 @@ from __future__ import annotations -__lazy_modules__ = {"utils"} - from typing import TYPE_CHECKING from utils import is_valid_hwnd diff --git a/src/capture_method/DesktopDuplicationCaptureMethod.py b/src/capture_method/DesktopDuplicationCaptureMethod.py index fa664991..fc03206b 100644 --- a/src/capture_method/DesktopDuplicationCaptureMethod.py +++ b/src/capture_method/DesktopDuplicationCaptureMethod.py @@ -1,7 +1,5 @@ from __future__ import annotations -__lazy_modules__ = {"cv2", "utils", "win32api", "win32con", "win32gui"} - import sys if sys.platform != "win32": diff --git a/src/capture_method/Screenshot using QT attempt.py b/src/capture_method/Screenshot using QT attempt.py index 819eb389..27fbe542 100644 --- a/src/capture_method/Screenshot using QT attempt.py +++ b/src/capture_method/Screenshot using QT attempt.py @@ -1,5 +1,3 @@ -__lazy_modules__ = {"PySide6", "PySide6.QtCore", "PySide6.QtGui", "numpy"} - import sys if sys.platform != "linux": diff --git a/src/capture_method/ScrotCaptureMethod.py b/src/capture_method/ScrotCaptureMethod.py index 80373083..834a9686 100644 --- a/src/capture_method/ScrotCaptureMethod.py +++ b/src/capture_method/ScrotCaptureMethod.py @@ -1,13 +1,3 @@ -__lazy_modules__ = { - "Xlib", - "Xlib.display", - "Xlib.error", - "cv2", - "pywinctl", - "subprocess", - "tempfile", -} - import sys if sys.platform != "linux": diff --git a/src/capture_method/VideoCaptureDeviceCaptureMethod.py b/src/capture_method/VideoCaptureDeviceCaptureMethod.py index 861003f3..d824802d 100644 --- a/src/capture_method/VideoCaptureDeviceCaptureMethod.py +++ b/src/capture_method/VideoCaptureDeviceCaptureMethod.py @@ -1,7 +1,5 @@ from __future__ import annotations -__lazy_modules__ = {"cv2", "cv2.Error", "error_messages", "numpy", "threading", "utils"} - from threading import Event, Thread from typing import TYPE_CHECKING, override diff --git a/src/capture_method/WindowsGraphicsCaptureMethod.py b/src/capture_method/WindowsGraphicsCaptureMethod.py index 17bfeaeb..9058a483 100644 --- a/src/capture_method/WindowsGraphicsCaptureMethod.py +++ b/src/capture_method/WindowsGraphicsCaptureMethod.py @@ -1,19 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "asyncio", - "d3d11", - "numpy", - "win32gui", - "winrt", - "winrt.windows", - "winrt.windows.graphics.capture", - "winrt.windows.graphics.capture.interop", - "winrt.windows.graphics.directx", - "winrt.windows.graphics.directx.direct3d11.interop", - "winrt.windows.graphics.imaging", -} - import sys if sys.platform != "win32": diff --git a/src/capture_method/XcbCaptureMethod.py b/src/capture_method/XcbCaptureMethod.py index 6a16ade8..901df671 100644 --- a/src/capture_method/XcbCaptureMethod.py +++ b/src/capture_method/XcbCaptureMethod.py @@ -1,14 +1,3 @@ -__lazy_modules__ = { - "PIL", - "Xlib", - "Xlib.display", - "Xlib.error", - "cv2", - "numpy", - "pywinctl", - "utils", -} - import sys if sys.platform != "linux": diff --git a/src/capture_method/__init__.py b/src/capture_method/__init__.py index 7ec172d7..feb5b51e 100644 --- a/src/capture_method/__init__.py +++ b/src/capture_method/__init__.py @@ -1,14 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "fcntl", - "itertools", - "pathlib", - "utils", - "vidioc_querycap", - "winerror", -} - import sys from collections import OrderedDict from dataclasses import dataclass diff --git a/src/compare.py b/src/compare.py index c357803d..574c9c8f 100644 --- a/src/compare.py +++ b/src/compare.py @@ -1,12 +1,3 @@ -__lazy_modules__ = { - "Levenshtein", - "collections", - "collections.abc", - "cv2", - "math", - "numpy", -} - from collections.abc import Iterable from math import sqrt from typing import TYPE_CHECKING diff --git a/src/d3d11.py b/src/d3d11.py index c2fcfac2..a268f335 100644 --- a/src/d3d11.py +++ b/src/d3d11.py @@ -2,8 +2,6 @@ # Copyright (c) 2024 David Lechner from __future__ import annotations -__lazy_modules__ = {"uuid"} - import sys if sys.platform != "win32": diff --git a/src/error_messages.py b/src/error_messages.py index 87019fb5..3c41479c 100644 --- a/src/error_messages.py +++ b/src/error_messages.py @@ -2,8 +2,6 @@ from __future__ import annotations -__lazy_modules__ = {"PySide6", "signal", "traceback", "types"} - import os import signal import sys diff --git a/src/hotkeys.py b/src/hotkeys.py index 918880c6..c6825520 100644 --- a/src/hotkeys.py +++ b/src/hotkeys.py @@ -1,7 +1,5 @@ from __future__ import annotations -__lazy_modules__ = {"collections", "collections.abc", "error_messages", "keyboard"} - import sys from collections.abc import Callable from typing import TYPE_CHECKING, Literal, cast diff --git a/src/menu_bar.py b/src/menu_bar.py index bfd44bd6..23cb5e02 100644 --- a/src/menu_bar.py +++ b/src/menu_bar.py @@ -1,23 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "PySide6.QtCore", - "PySide6.QtGui", - "PySide6.QtWidgets", - "capture_method", - "functools", - "hotkeys", - "json", - "packaging", - "packaging.version", - "urllib", - "urllib.error", - "urllib.request", - "user_profile", - "utils", - "webbrowser", -} - import json import sys import webbrowser diff --git a/src/region_selection.py b/src/region_selection.py index ec592fa0..67e53f37 100644 --- a/src/region_selection.py +++ b/src/region_selection.py @@ -1,17 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "PySide6.QtTest", - "capture_method", - "cv2", - "error_messages", - "math", - "numpy", - "pywinctl", - "utils", - "win32gui", -} - import sys from math import ceil from typing import TYPE_CHECKING, override diff --git a/src/split_parser.py b/src/split_parser.py index 8348d921..333a08d0 100644 --- a/src/split_parser.py +++ b/src/split_parser.py @@ -1,15 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "AutoSplitImage", - "collections", - "collections.abc", - "error_messages", - "functools", - "re", - "utils", -} - import os import re import sys diff --git a/src/user_profile.py b/src/user_profile.py index 9b115148..6aa93cd2 100644 --- a/src/user_profile.py +++ b/src/user_profile.py @@ -1,17 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "PySide6", - "copy", - "error_messages", - "hotkeys", - "menu_bar", - "tomli_w", - "tomllib", - "utils", - "warnings", -} - import os import tomllib from copy import deepcopy diff --git a/src/utils.py b/src/utils.py index d32c006d..097a7215 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,24 +1,5 @@ from __future__ import annotations -__lazy_modules__ = { - "_ctypes", - "asyncio", - "collections", - "collections.abc", - "ctypes", - "ctypes.wintypes", - "fcntl", - "functools", - "itertools", - "numpy", - "pathlib", - "shutil", - "threading", - "win32gui", - "win32ui", - "winerror", -} - import asyncio import os import shutil From 4ba7e1cd58b1ec4c154a7ae33c5813a28f08b0a7 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 21:34:56 -0400 Subject: [PATCH 14/50] fix build --- scripts/build.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 483de199..451dd86e 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -18,7 +18,8 @@ try: if sys.version_info >= (3, 15): from PyInstaller.utils.hooks.tcl_tk import tcltk_info Splash._check_tcl_tk_compatibility(tcltk_info) - Splash._check_tcl_tk_compatibility() + else: + Splash._check_tcl_tk_compatibility() print(True) except SystemExit as e: print(e, file=sys.stderr) From 4243a1cbe2304faee1d320857e5235221ed4019a Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 21:38:41 -0400 Subject: [PATCH 15/50] uv lock --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 5484f210..9bc43e9e 100644 --- a/uv.lock +++ b/uv.lock @@ -16,7 +16,7 @@ supported-markers = [ [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. -exclude-newer-span = "P6D" +exclude-newer-span = "P1W" [manifest] From 59ed074411487584fe4c2d1953e1396c26c3a9c1 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 21:57:40 -0400 Subject: [PATCH 16/50] ignore pyright error --- src/AutoSplit.py | 2 +- uv.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index a1e7845d..03dd547b 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -3,7 +3,7 @@ import sys if sys.version_info >= (3, 15): - sys.set_lazy_imports("all") + sys.set_lazy_imports("all") # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue] # Not yet added to pyright # Prevent PyAutoGUI and pywinctl from setting Process DPI Awareness, # which Qt tries to do then throws warnings about it. diff --git a/uv.lock b/uv.lock index 9bc43e9e..821d0a4d 100644 --- a/uv.lock +++ b/uv.lock @@ -581,15 +581,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.409" +version = "1.1.410" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "typing-extensions", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/51/4e/3aa27f74211522dba7e9cbc3e74de779c6d4b654c54e50a4840623be8014/pyright-1.1.409.tar.gz", hash = "sha256:986ee05beca9e077c165758ad123667c679e050059a2546aa02473930394bc93", size = 4430434, upload-time = "2026-04-23T11:02:03.799Z" } +sdist = { url = "https://files.pythonhosted.org/packages/10/53/e4d8ea1391bd4355231be6f91bf239479aa0014260ed3fb5526eeb12a1f2/pyright-1.1.410.tar.gz", hash = "sha256:07a073b8ba6749826773c1269773efa11b93440d9a6aa60419d9a3172d6dc488", size = 4062013, upload-time = "2026-06-01T17:35:48.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/6b/330d8ebae582b30c2959a1ef4c3bc344ebde48c2ff0c3f113c4710735e11/pyright-1.1.409-py3-none-any.whl", hash = "sha256:aa3ea228cab90c845c7a60d28db7a844c04315356392aa09fafcee98c8c22fb3", size = 6438161, upload-time = "2026-04-23T11:02:01.309Z" }, + { url = "https://files.pythonhosted.org/packages/d7/33/288b5868fa00846dacf249633719d747893e54aebd196b9968ac1878a5d3/pyright-1.1.410-py3-none-any.whl", hash = "sha256:5e961bed37cacf96b3f7cd7b1da39b350a9239aa2e69138d0e88f728cfaf296c", size = 6082448, upload-time = "2026-06-01T17:35:46.387Z" }, ] [package.optional-dependencies] From 119258683d593b2d1660e2cde553cfd20f05cbb4 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 22:03:11 -0400 Subject: [PATCH 17/50] Replicate tcltk_info.available check --- scripts/build.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 451dd86e..d54d18ee 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -17,6 +17,11 @@ from PyInstaller.building.splash import Splash try: if sys.version_info >= (3, 15): from PyInstaller.utils.hooks.tcl_tk import tcltk_info + if not tcltk_info.available: + raise SystemExit( + "ERROR: Your platform does not support the splash screen feature, since tkinter is not installed. " + "Please install tkinter and try again." + ) Splash._check_tcl_tk_compatibility(tcltk_info) else: Splash._check_tcl_tk_compatibility() From 1201d7f1b37aab38334243ddbdd8424189e8bc1d Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 22:09:34 -0400 Subject: [PATCH 18/50] Use numpy from index --- uv.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/uv.lock b/uv.lock index 821d0a4d..372ac6d1 100644 --- a/uv.lock +++ b/uv.lock @@ -335,24 +335,24 @@ wheels = [ [[package]] name = "numpy" -version = "2.3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/7d/3fec4199c5ffb892bed55cff901e4f39a58c81df9c44c280499e92cad264/numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48", size = 20489306, upload-time = "2025-07-24T21:32:07.553Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c4/43/f12b2ade99199e39c73ad182f103f9d9791f48d885c600c8e05927865baf/numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f", size = 14296292, upload-time = "2025-07-24T20:51:33.488Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f9/77c07d94bf110a916b17210fac38680ed8734c236bfed9982fd8524a7b47/numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5", size = 16638913, upload-time = "2025-07-24T20:51:58.517Z" }, - { url = "https://files.pythonhosted.org/packages/9b/d1/9d9f2c8ea399cc05cfff8a7437453bd4e7d894373a93cdc46361bbb49a7d/numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58", size = 16071180, upload-time = "2025-07-24T20:52:22.827Z" }, - { url = "https://files.pythonhosted.org/packages/4c/41/82e2c68aff2a0c9bf315e47d61951099fed65d8cb2c8d9dc388cb87e947e/numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0", size = 18576809, upload-time = "2025-07-24T20:52:51.015Z" }, - { url = "https://files.pythonhosted.org/packages/14/14/4b4fd3efb0837ed252d0f583c5c35a75121038a8c4e065f2c259be06d2d8/numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2", size = 6366410, upload-time = "2025-07-24T20:56:44.949Z" }, - { url = "https://files.pythonhosted.org/packages/11/9e/b4c24a6b8467b61aced5c8dc7dcfce23621baa2e17f661edb2444a418040/numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b", size = 12918821, upload-time = "2025-07-24T20:57:06.479Z" }, - { url = "https://files.pythonhosted.org/packages/0e/0f/0dc44007c70b1007c1cef86b06986a3812dd7106d8f946c09cfa75782556/numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910", size = 10477303, upload-time = "2025-07-24T20:57:22.879Z" }, - { url = "https://files.pythonhosted.org/packages/15/b0/d004bcd56c2c5e0500ffc65385eb6d569ffd3363cb5e593ae742749b2daa/numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0", size = 14352479, upload-time = "2025-07-24T20:54:25.819Z" }, - { url = "https://files.pythonhosted.org/packages/11/e3/285142fcff8721e0c99b51686426165059874c150ea9ab898e12a492e291/numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0", size = 16702805, upload-time = "2025-07-24T20:54:50.814Z" }, - { url = "https://files.pythonhosted.org/packages/33/c3/33b56b0e47e604af2c7cd065edca892d180f5899599b76830652875249a3/numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2", size = 16133830, upload-time = "2025-07-24T20:55:17.306Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ae/7b1476a1f4d6a48bc669b8deb09939c56dd2a439db1ab03017844374fb67/numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf", size = 18652665, upload-time = "2025-07-24T20:55:46.665Z" }, - { url = "https://files.pythonhosted.org/packages/14/ba/5b5c9978c4bb161034148ade2de9db44ec316fab89ce8c400db0e0c81f86/numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1", size = 6514777, upload-time = "2025-07-24T20:55:57.66Z" }, - { url = "https://files.pythonhosted.org/packages/eb/46/3dbaf0ae7c17cdc46b9f662c56da2054887b8d9e737c1476f335c83d33db/numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b", size = 13111856, upload-time = "2025-07-24T20:56:17.318Z" }, - { url = "https://files.pythonhosted.org/packages/c1/9e/1652778bce745a67b5fe05adde60ed362d38eb17d919a540e813d30f6874/numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631", size = 10544226, upload-time = "2025-07-24T20:56:34.509Z" }, +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, ] [[package]] From 5215ad3a0491c4f06cc64841675135e93c0a9c51 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 22:35:04 -0400 Subject: [PATCH 19/50] Deprecated numpy methods --- src/AutoSplit.py | 2 +- src/capture_method/BitBltCaptureMethod.py | 3 +-- src/capture_method/WindowsGraphicsCaptureMethod.py | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index 03dd547b..a1e7845d 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -3,7 +3,7 @@ import sys if sys.version_info >= (3, 15): - sys.set_lazy_imports("all") # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue] # Not yet added to pyright + sys.set_lazy_imports("all") # Prevent PyAutoGUI and pywinctl from setting Process DPI Awareness, # which Qt tries to do then throws warnings about it. diff --git a/src/capture_method/BitBltCaptureMethod.py b/src/capture_method/BitBltCaptureMethod.py index 26eedb34..d2103a7c 100644 --- a/src/capture_method/BitBltCaptureMethod.py +++ b/src/capture_method/BitBltCaptureMethod.py @@ -73,14 +73,13 @@ def get_frame(self) -> MatLike | None: win32con.SRCCOPY, ) image = np.frombuffer(bitmap.GetBitmapBits(True), dtype=np.uint8) + image = image.reshape((height, width, BGRA_CHANNEL_COUNT)) except win32ui.error, pywintypes.error: # Invalid handle or the window was closed while it was being manipulated return None if is_blank(image): image = None - else: - image.shape = (height, width, BGRA_CHANNEL_COUNT) # Cleanup DC and handle try_delete_dc(dc_object) diff --git a/src/capture_method/WindowsGraphicsCaptureMethod.py b/src/capture_method/WindowsGraphicsCaptureMethod.py index 9058a483..72e2a175 100644 --- a/src/capture_method/WindowsGraphicsCaptureMethod.py +++ b/src/capture_method/WindowsGraphicsCaptureMethod.py @@ -156,7 +156,7 @@ def get_frame(self) -> MatLike | None: raise ValueError("Unable to obtain the BitmapBuffer from SoftwareBitmap.") reference = bitmap_buffer.create_reference() image = np.frombuffer(cast("bytes", reference), dtype=np.uint8) - image.shape = (self.size.height, self.size.width, BGRA_CHANNEL_COUNT) + image = image.reshape((self.size.height, self.size.width, BGRA_CHANNEL_COUNT)) image = image[ selection["y"] : selection["y"] + selection["height"], selection["x"] : selection["x"] + selection["width"], From a092f54998c06e60cdf6570e6146f769c1d2fa47 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 22:45:59 -0400 Subject: [PATCH 20/50] Add UV_PYTHON ot even local script --- .github/workflows/lint-and-build.yml | 2 ++ scripts/install.ps1 | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 057f012e..a05a2dbd 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -90,6 +90,8 @@ jobs: wine-compat: "-WineCompat" steps: - uses: actions/checkout@v6 + # On ARM64, uv defaults to x86_64 Python. + # Also done in local script. Done CI before UV is even set-up for caching and to avoid re-downloading Python # https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 - name: Set UV_PYTHON for ARM runners if: ${{ endsWith(matrix.os, 'arm') }} diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 250b164c..784a9d54 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -92,6 +92,13 @@ if (` # https://github.com/opencv/opencv-python/issues/1092#issuecomment-2862538656 $Env:CMAKE_ARGS = '-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF' +# On ARM64, uv defaults to x86_64 Python. +# This is also done in CI before UV is even set-up for caching and to avoid re-downloading Python +# https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 +if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'Arm64') { + $Env:UV_PYTHON = 'arm64' +} + $prod = if ($Env:GITHUB_JOB -eq 'Build') { '--no-dev' } else { } $lock = if ($Env:GITHUB_JOB) { '--locked' } else { } Write-Output "Installing Python dependencies with: uv sync $prod $lock" From 0d15239e1aec98d7f2e62ebca108dd8ce885763d Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 23:17:33 -0400 Subject: [PATCH 21/50] Try python-version fixes --- .github/workflows/lint-and-build.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index a05a2dbd..527eb3bb 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -89,13 +89,6 @@ jobs: python-version: "3.15" wine-compat: "-WineCompat" steps: - - uses: actions/checkout@v6 - # On ARM64, uv defaults to x86_64 Python. - # Also done in local script. Done CI before UV is even set-up for caching and to avoid re-downloading Python - # https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 - - name: Set UV_PYTHON for ARM runners - if: ${{ endsWith(matrix.os, 'arm') }} - run: echo "UV_PYTHON=arm64" >> "$GITHUB_ENV" # region https://github.com/pyinstaller/pyinstaller/issues/9204 - name: Set up Python for PyInstaller tk issue on Linux if: ${{ startsWith(matrix.os, 'ubuntu') }} @@ -106,7 +99,13 @@ jobs: - name: Set up uv for Python ${{ matrix.python-version }} uses: astral-sh/setup-uv@v7 with: - python-version: ${{ !startsWith(matrix.os, 'ubuntu') && matrix.python-version || null }} + # On ARM64, uv defaults to x86_64 Python, force it to aarch64. + # Also done in local script. Done CI for cache-matching and to avoid re-downloading Python. + # https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 + python-version: >- + ${{ (!startsWith(matrix.os, 'ubuntu') + && format('{0}-{1}', matrix.python-version, endsWith(matrix.os, 'arm') && 'aarch64' || 'x86_64')) + || null }} # endregion - run: scripts/install.ps1 ${{ matrix.wine-compat }} shell: pwsh From e1ad4d8c639273bf8646aee38e6a94b0cfa241fa Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 23:23:06 -0400 Subject: [PATCH 22/50] fixed accidentally removed line --- .github/workflows/lint-and-build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 527eb3bb..1428f5eb 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -89,6 +89,7 @@ jobs: python-version: "3.15" wine-compat: "-WineCompat" steps: + - uses: actions/checkout@v6 # region https://github.com/pyinstaller/pyinstaller/issues/9204 - name: Set up Python for PyInstaller tk issue on Linux if: ${{ startsWith(matrix.os, 'ubuntu') }} @@ -102,6 +103,8 @@ jobs: # On ARM64, uv defaults to x86_64 Python, force it to aarch64. # Also done in local script. Done CI for cache-matching and to avoid re-downloading Python. # https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 + # + # On Ubuntu use the global Python install (null) for reason above python-version: >- ${{ (!startsWith(matrix.os, 'ubuntu') && format('{0}-{1}', matrix.python-version, endsWith(matrix.os, 'arm') && 'aarch64' || 'x86_64')) From 977d24ad87e016607eaf4085f583091e1e7eec65 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 23:32:01 -0400 Subject: [PATCH 23/50] Avoid SupportsSplashScreen check on CI --- scripts/build.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index d54d18ee..9ec90024 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -9,8 +9,9 @@ Push-Location "$PSScriptRoot/.." # Avoid issues with space in path try { & 'scripts/compile_resources.ps1' - # TODO: Remove condition once using the same version across all python - $SupportsSplashScreen = [System.Convert]::ToBoolean( + # CI not allowed to skip splash screen, it MUST build (will fail when calling PyInstaller) + $SupportsSplashScreen = $Env:CI -or [System.Convert]::ToBoolean( + # TODO: Remove condition once using the same version across all python $(uv run --active python -c ' import sys from PyInstaller.building.splash import Splash From 989a5e0c965a1b6355db874acb607e153317887e Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 23:49:24 -0400 Subject: [PATCH 24/50] Fix UV_PYTHON --- .github/workflows/lint-and-build.yml | 1 - scripts/build.ps1 | 2 +- scripts/install.ps1 | 30 ++++++++++++---------------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 1428f5eb..61957345 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -101,7 +101,6 @@ jobs: uses: astral-sh/setup-uv@v7 with: # On ARM64, uv defaults to x86_64 Python, force it to aarch64. - # Also done in local script. Done CI for cache-matching and to avoid re-downloading Python. # https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 # # On Ubuntu use the global Python install (null) for reason above diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 9ec90024..98787fa3 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -10,7 +10,7 @@ try { & 'scripts/compile_resources.ps1' # CI not allowed to skip splash screen, it MUST build (will fail when calling PyInstaller) - $SupportsSplashScreen = $Env:CI -or [System.Convert]::ToBoolean( + $SupportsSplashScreen = $Env:GITHUB_JOB -or [System.Convert]::ToBoolean( # TODO: Remove condition once using the same version across all python $(uv run --active python -c ' import sys diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 784a9d54..de20e81e 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -33,14 +33,16 @@ if ($IsLinux) { if ($IsLinux) { if (-not $Env:GITHUB_JOB -or $Env:GITHUB_JOB -eq 'Build') { # System dependencies - sudo apt-get update - # python3-tk for splash screen - # libxcb-cursor-dev for QT_QPA_PLATFORM=xcb - # the rest for PySide6 - sudo apt-get install -y ` - python3-tk ` - libxcb-cursor-dev ` - libegl1 libxkbcommon0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1 + if (Get-Command apt-get -ErrorAction SilentlyContinue) { + sudo apt-get update + # python3-tk for splash screen + # libxcb-cursor-dev for QT_QPA_PLATFORM=xcb + # the rest for PySide6 + sudo apt-get install -y ` + python3-tk ` + libxcb-cursor-dev ` + libegl1 libxkbcommon0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1 + } Write-Output 'Installing appimagetool' Invoke-WebRequest ` @@ -92,18 +94,12 @@ if (` # https://github.com/opencv/opencv-python/issues/1092#issuecomment-2862538656 $Env:CMAKE_ARGS = '-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF' -# On ARM64, uv defaults to x86_64 Python. -# This is also done in CI before UV is even set-up for caching and to avoid re-downloading Python -# https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179 -if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq 'Arm64') { - $Env:UV_PYTHON = 'arm64' -} - $prod = if ($Env:GITHUB_JOB -eq 'Build') { '--no-dev' } else { } $lock = if ($Env:GITHUB_JOB) { '--locked' } else { } -Write-Output "Installing Python dependencies with: uv sync $prod $lock" # Verbose to see sdist progression -uv sync --verbose --active $prod $lock +$uvSyncArgs = @('sync', '--verbose', '--active') + $prod + $lock +Write-Output "Installing Python dependencies with: uv $uvSyncArgs" +uv @uvSyncArgs # Don't compile resources on the Build CI job as it'll do so in build script if (-not $prod) { From bb4c264ae1622003002228614172cde88c0ecd36 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 11 Jun 2026 23:55:27 -0400 Subject: [PATCH 25/50] let skip splash on 3.15 on ci --- scripts/build.ps1 | 10 ++++++---- scripts/install.ps1 | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 98787fa3..94a61d43 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -9,10 +9,12 @@ Push-Location "$PSScriptRoot/.." # Avoid issues with space in path try { & 'scripts/compile_resources.ps1' + # TODO: Remove UV_PYTHON check once tcl/tk is fixed on Python 3.15 # CI not allowed to skip splash screen, it MUST build (will fail when calling PyInstaller) - $SupportsSplashScreen = $Env:GITHUB_JOB -or [System.Convert]::ToBoolean( - # TODO: Remove condition once using the same version across all python - $(uv run --active python -c ' + $SupportsSplashScreen = ($Env:UV_PYTHON -notlike '3.15*') -and ( + $Env:GITHUB_JOB -or [System.Convert]::ToBoolean( + # TODO: Remove condition once using the same version across all python + $(uv run --active python -c ' import sys from PyInstaller.building.splash import Splash try: @@ -30,7 +32,7 @@ try: except SystemExit as e: print(e, file=sys.stderr) print(False) - ')) + '))) $arguments = @( 'src/AutoSplit.py', diff --git a/scripts/install.ps1 b/scripts/install.ps1 index de20e81e..4828b488 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -90,7 +90,7 @@ if (` } # https://github.com/opencv/opencv-python#source-distributions -# Allows building OpenCV on Windows ARM64 +# Allows building OpenCV on Windows ARM64 when only sdist is available # https://github.com/opencv/opencv-python/issues/1092#issuecomment-2862538656 $Env:CMAKE_ARGS = '-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF' From 11255b46c9985507bc59b8fd5ff2148177c341fa Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 10:34:12 -0400 Subject: [PATCH 26/50] Attempt a fix for numpy 3.15 arm --- .github/workflows/lint-and-build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 61957345..e7d501ce 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -109,6 +109,12 @@ jobs: && format('{0}-{1}', matrix.python-version, endsWith(matrix.os, 'arm') && 'aarch64' || 'x86_64')) || null }} # endregion + # MinGW (cc) fails SIZEOF_PY_INTPTR_T detection on ARM64; force MSVC for numpy sdist + - name: Set up MSVC ARM64 environment + if: ${{ matrix.os == 'windows-11-arm' && matrix.python-version == '3.15' }} + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: aarch64 - run: scripts/install.ps1 ${{ matrix.wine-compat }} shell: pwsh - run: "scripts/build.ps1 ${{ matrix.wine-compat }}" From 8e93a74d872e349f52aa64f78d8cea0a12e0a586 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 10:40:15 -0400 Subject: [PATCH 27/50] correct arch --- .github/workflows/lint-and-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index e7d501ce..3690fc50 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -114,7 +114,7 @@ jobs: if: ${{ matrix.os == 'windows-11-arm' && matrix.python-version == '3.15' }} uses: ilammy/msvc-dev-cmd@v1 with: - arch: aarch64 + arch: arm64 - run: scripts/install.ps1 ${{ matrix.wine-compat }} shell: pwsh - run: "scripts/build.ps1 ${{ matrix.wine-compat }}" From a22409d33a48337645e6dbf7499bdd345b6e3a78 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 12:17:34 -0400 Subject: [PATCH 28/50] resync --- src/capture_method/BitBltCaptureMethod.py | 4 +- uv.lock | 99 +++++++---------------- 2 files changed, 29 insertions(+), 74 deletions(-) diff --git a/src/capture_method/BitBltCaptureMethod.py b/src/capture_method/BitBltCaptureMethod.py index d2103a7c..31e6b180 100644 --- a/src/capture_method/BitBltCaptureMethod.py +++ b/src/capture_method/BitBltCaptureMethod.py @@ -73,13 +73,11 @@ def get_frame(self) -> MatLike | None: win32con.SRCCOPY, ) image = np.frombuffer(bitmap.GetBitmapBits(True), dtype=np.uint8) - image = image.reshape((height, width, BGRA_CHANNEL_COUNT)) except win32ui.error, pywintypes.error: # Invalid handle or the window was closed while it was being manipulated return None - if is_blank(image): - image = None + image = None if is_blank(image) else image.reshape((height, width, BGRA_CHANNEL_COUNT)) # Cleanup DC and handle try_delete_dc(dc_object) diff --git a/uv.lock b/uv.lock index 372ac6d1..bd12105d 100644 --- a/uv.lock +++ b/uv.lock @@ -85,8 +85,7 @@ dependencies = [ { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "python_full_version >= '3.15' and sys_platform == 'linux'" }, { name = "pyautogui", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pygrabber", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller", version = "6.17.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "pyinstaller", version = "6.20.0", source = { git = "https://github.com/pyinstaller/pyinstaller?rev=9803892a21f84c695885ca85c14dbad47a283a32#9803892a21f84c695885ca85c14dbad47a283a32" }, marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "pyinstaller", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pyside6-essentials", version = "6.8.0.2", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, { name = "pyside6-essentials", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or sys_platform == 'win32'" }, { name = "python-xlib", marker = "sys_platform == 'linux'" }, @@ -134,8 +133,7 @@ requires-dist = [ { name = "pillow", marker = "python_full_version >= '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, - { name = "pyinstaller", marker = "python_full_version < '3.15'", specifier = ">=6.15.0" }, - { name = "pyinstaller", marker = "python_full_version >= '3.15'", git = "https://github.com/pyinstaller/pyinstaller?rev=9803892a21f84c695885ca85c14dbad47a283a32" }, + { name = "pyinstaller", url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" }, { name = "pyside6-essentials", marker = "platform_machine != 'aarch64' or sys_platform != 'linux'", specifier = ">=6.9.0" }, { name = "pyside6-essentials", marker = "platform_machine == 'aarch64' and sys_platform == 'linux'", specifier = "<6.8.1" }, { name = "python-xlib", marker = "sys_platform == 'linux'", specifier = ">=0.33" }, @@ -480,85 +478,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/51/0359e171686a7eeda5e975d7f9dfba6a67e04b33c7ddad1f7a343c171e55/pygrabber-0.2-py3-none-any.whl", hash = "sha256:5ac8bbe5f6a5dfb7c1c9c55d80ca9b9457743abd3ac8efa21cb9e302bdbf03ac", size = 24193, upload-time = "2023-10-20T07:17:13.1Z" }, ] -[[package]] -name = "pyinstaller" -version = "6.17.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and sys_platform == 'win32'", -] -dependencies = [ - { name = "altgraph", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "packaging", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "pefile", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib", version = "2025.10", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "pywin32-ctypes", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, - { name = "setuptools", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/01/80/9e0dad9c69a7cfd4b5aaede8c6225d762bab7247a2a6b7651e1995522001/pyinstaller-6.17.0.tar.gz", hash = "sha256:be372bd911392b88277e510940ac32a5c2a6ce4b8d00a311c78fa443f4f27313", size = 4014147, upload-time = "2025-11-24T19:43:32.109Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/b6/2e184879ab9cf90a1d2867fdd34d507c4d246b3cc52ca05aad00bfc70ee7/pyinstaller-6.17.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa9fd87aaa28239c6f0d0210114029bd03f8cac316a90bab071a5092d7c85ad7", size = 731968, upload-time = "2025-11-24T19:42:35.421Z" }, - { url = "https://files.pythonhosted.org/packages/40/76/f529de98f7e5cce7904c19b224990003fc2267eda2ee5fdd8452acb420a9/pyinstaller-6.17.0-py3-none-manylinux2014_i686.whl", hash = "sha256:060b122e43e7c0b23e759a4153be34bd70914135ab955bb18a67181e0dca85a2", size = 743217, upload-time = "2025-11-24T19:42:39.286Z" }, - { url = "https://files.pythonhosted.org/packages/a3/10/c02bfbb050cafc4c353cf69baf95407e211e1372bd286ab5ce5cbc13a30a/pyinstaller-6.17.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:cd213d1a545c97dfe4a3c40e8213ff7c5127fc115c49229f27a3fa541503444b", size = 741119, upload-time = "2025-11-24T19:42:43.12Z" }, - { url = "https://files.pythonhosted.org/packages/11/9d/69fdacfd9335695f5900a376cfe3e4aed28f0720ffc15fee81fdb9d920bc/pyinstaller-6.17.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:89c0d18ba8b62c6607abd8cf2299ae5ffa5c36d8c47f39608ce8c3f357f6099f", size = 738111, upload-time = "2025-11-24T19:42:46.97Z" }, - { url = "https://files.pythonhosted.org/packages/5e/1e/e8e36e1568f6865ac706c6e1f875c1a346ddaa9f9a8f923d66545d2240ed/pyinstaller-6.17.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2a147b83cdebb07855bd5a663600891550062373a2ca375c58eacead33741a27", size = 737795, upload-time = "2025-11-24T19:42:50.675Z" }, - { url = "https://files.pythonhosted.org/packages/8d/15/9dc0f81ccb746c27bfa6ee53164422fe47ee079c7a717d9c4791aba78797/pyinstaller-6.17.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:f8cfbbfa6708e54fb936df6dd6eafaf133e84efb0d2fe25b91cfeefa793c4ca4", size = 736891, upload-time = "2025-11-24T19:42:54.458Z" }, - { url = "https://files.pythonhosted.org/packages/97/e6/bed54821c1ebe1275c559661d3e7bfa23c406673b515252dfbf89db56c65/pyinstaller-6.17.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:97f4c1942f7b4cd73f9e38b49cc8f5f8a6fbb44922cb60dd3073a189b77ee1ae", size = 736752, upload-time = "2025-11-24T19:42:58.144Z" }, - { url = "https://files.pythonhosted.org/packages/c7/84/897d759198676b910d69d42640b6d25d50b449f2209e18127a974cf59dbe/pyinstaller-6.17.0-py3-none-win32.whl", hash = "sha256:ce0be227a037fd4be672226db709088565484f597d6b230bceec19850fdd4c85", size = 1317851, upload-time = "2025-11-24T19:43:04.361Z" }, - { url = "https://files.pythonhosted.org/packages/2d/f5/6a122efe024433ecc34aab6f499e0bd2bbe059c639b77b0045aa2421b0bf/pyinstaller-6.17.0-py3-none-win_amd64.whl", hash = "sha256:b019940dbf7a01489d6b26f9fb97db74b504e0a757010f7ad078675befc85a82", size = 1378685, upload-time = "2025-11-24T19:43:10.395Z" }, - { url = "https://files.pythonhosted.org/packages/c4/96/14991773c9e599707a53594429ccf372f9ee638df3b7d26b65fd1a7433f0/pyinstaller-6.17.0-py3-none-win_arm64.whl", hash = "sha256:3c92a335e338170df7e615f75279cfeea97ade89e6dd7694943c8c185460f7b7", size = 1320032, upload-time = "2025-11-24T19:43:16.388Z" }, -] - [[package]] name = "pyinstaller" version = "6.20.0" -source = { git = "https://github.com/pyinstaller/pyinstaller?rev=9803892a21f84c695885ca85c14dbad47a283a32#9803892a21f84c695885ca85c14dbad47a283a32" } -resolution-markers = [ - "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.15' and sys_platform == 'win32'", -] +source = { url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" } dependencies = [ - { name = "altgraph", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "packaging", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "pefile", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib", version = "2026.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "pywin32-ctypes", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, - { name = "setuptools", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "altgraph", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pefile", marker = "sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] +sdist = { hash = "sha256:f90f479bb4c4a63c3119eedffd778d3cbea7d842821b286bd25a5bd6dba6c860" } -[[package]] -name = "pyinstaller-hooks-contrib" -version = "2025.10" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and sys_platform == 'win32'", -] -dependencies = [ - { name = "packaging", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "setuptools", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/26/4f/e33132acdb8f732978e577b8a0130a412cbfe7a3414605e3fd380a975522/pyinstaller_hooks_contrib-2025.10.tar.gz", hash = "sha256:a1a737e5c0dccf1cf6f19a25e2efd109b9fec9ddd625f97f553dac16ee884881", size = 168155, upload-time = "2025-11-22T09:34:36.138Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/de/a7688eed49a1d3df337cdaa4c0d64e231309a52f269850a72051975e3c4a/pyinstaller_hooks_contrib-2025.10-py3-none-any.whl", hash = "sha256:aa7a378518772846221f63a84d6306d9827299323243db890851474dfd1231a9", size = 447760, upload-time = "2025-11-22T09:34:34.753Z" }, -] +[package.metadata] +requires-dist = [ + { name = "altgraph" }, + { name = "argcomplete", marker = "extra == 'completion'" }, + { name = "execnet", marker = "extra == 'hook-testing'", specifier = ">=1.5.0" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'", specifier = ">=4.6" }, + { name = "macholib", marker = "sys_platform == 'darwin'", specifier = ">=1.8" }, + { name = "packaging", specifier = ">=22.0" }, + { name = "pefile", marker = "sys_platform == 'win32'", specifier = ">=2022.5.30" }, + { name = "psutil", marker = "extra == 'hook-testing'" }, + { name = "pyinstaller-hooks-contrib", specifier = ">=2026.4" }, + { name = "pytest", marker = "extra == 'hook-testing'", specifier = ">=2.7.3" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'", specifier = ">=0.2.1" }, + { name = "setuptools", specifier = ">=42.0.0" }, +] +provides-extras = ["completion", "hook-testing"] [[package]] name = "pyinstaller-hooks-contrib" version = "2026.5" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.15' and sys_platform == 'win32'", -] dependencies = [ - { name = "packaging", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "setuptools", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1a/67/f4452d68793fb15beba4f19ef39a38a8822f0da7452b503c400d5a21f5c1/pyinstaller_hooks_contrib-2026.5.tar.gz", hash = "sha256:f066dfca8f7c45ff6336c9cf9fe25b4e48bfeb322a1aa24faaedfb8a8d1b0b08", size = 173689, upload-time = "2026-05-04T22:36:55.124Z" } wheels = [ From 9196b0427c698becbe0f036967ddc1fd1fc37906 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 12:18:26 -0400 Subject: [PATCH 29/50] additional todo comment --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ae093043..b9551fe1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ # # Build and compile resources - "pyinstaller >=6.15.0", # Python 3.14 support + "pyinstaller >=6.15.0", # Python 3.14 support # TODO: Bump when 3.15 wheels # # https://packaging.python.org/en/latest/specifications/dependency-specifiers/#environment-markers From 64615d3495cc3276b7a6982dee5f529e9e59a781 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 12:30:01 -0400 Subject: [PATCH 30/50] Extract splash screen check script --- scripts/build.ps1 | 17 +---------------- scripts/check_splash_support.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 scripts/check_splash_support.py diff --git a/scripts/build.ps1 b/scripts/build.ps1 index a82668a4..aeec0f34 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -13,22 +13,7 @@ try { # CI not allowed to skip splash screen, it MUST build (will fail when calling PyInstaller) $SupportsSplashScreen = ($Env:UV_PYTHON -notlike '3.15*') -and ( $Env:GITHUB_JOB -or [System.Convert]::ToBoolean( - $(uv run --active python -c ' -import sys -from PyInstaller.building.splash import Splash -try: - from PyInstaller.utils.hooks.tcl_tk import tcltk_info - if not tcltk_info.available: - raise SystemExit( - "ERROR: Your platform does not support the splash screen feature, since tkinter is not installed. " - "Please install tkinter and try again." - ) - Splash._check_tcl_tk_compatibility(tcltk_info) - print(True) -except SystemExit as e: - print(e, file=sys.stderr) - print(False) - '))) + $(uv run --active scripts/check_splash_support.py))) $arguments = @( 'src/AutoSplit.py', diff --git a/scripts/check_splash_support.py b/scripts/check_splash_support.py new file mode 100644 index 00000000..fc7f40c1 --- /dev/null +++ b/scripts/check_splash_support.py @@ -0,0 +1,26 @@ +""" +Check whether PyInstaller can build the splash screen on this platform. + +Prints "True" or "False" to stdout for consumption by build.ps1. +""" + +# Not found in typeshed because private +# pyright: reportMissingImports=false, reportUnknownVariableType=false, reportUnknownMemberType=false, reportAttributeAccessIssue=false + +import sys + +from PyInstaller.building.splash import Splash + +try: + from PyInstaller.utils.hooks.tcl_tk import tcltk_info + + if not tcltk_info.available: + raise SystemExit( # noqa: TRY301 # Copies source + "ERROR: Your platform does not support the splash screen feature, " + + "since tkinter is not installed. Please install tkinter and try again." + ) + Splash._check_tcl_tk_compatibility(tcltk_info) # noqa: SLF001 + print(True) +except SystemExit as e: + print(e, file=sys.stderr) + print(False) From ba2e3d4f4dcc9d97b78e7830fc4ec72cc86c3076 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 13:54:28 -0400 Subject: [PATCH 31/50] Make own imports lazy --- scripts/compile_resources.ps1 | 12 ++++++++++++ src/AutoSplit.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/scripts/compile_resources.ps1 b/scripts/compile_resources.ps1 index 9457d067..937fd790 100644 --- a/scripts/compile_resources.ps1 +++ b/scripts/compile_resources.ps1 @@ -40,9 +40,21 @@ if (-not $GITHUB_REPOSITORY) { $GITHUB_REPOSITORY = 'Toufool/AutoSplit' } +# Our own top-level modules and packages, used by AutoSplit.py's lazy imports +# filter (Python 3.15+). Generated because PyInstaller-frozen builds can't +# discover pure modules on disk: they live inside the PYZ archive. +$SRC_ROOT_MODULES = ( + @('"__main__"') + ( + Get-ChildItem ./src | + Where-Object { ($_.Extension -eq '.py' -or $_.PSIsContainer) -and $_.Name -notlike '__*' } | + ForEach-Object { "`"$($_.BaseName)`"" } + ) +) -join ', ' + New-Item $build_vars_path -ItemType File -Force | Out-Null Add-Content $build_vars_path "AUTOSPLIT_BUILD_NUMBER = `"$BUILD_NUMBER`"" Add-Content $build_vars_path "AUTOSPLIT_GITHUB_REPOSITORY = `"$GITHUB_REPOSITORY`"" +Add-Content $build_vars_path "SRC_ROOT_MODULES = frozenset(($SRC_ROOT_MODULES))" Write-Host "Generated build number: `"$BUILD_NUMBER`"" Write-Host "Set repository to `"$GITHUB_REPOSITORY`"" diff --git a/src/AutoSplit.py b/src/AutoSplit.py index a1e7845d..ac8d7983 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -3,6 +3,34 @@ import sys if sys.version_info >= (3, 15): + # Our own top-level modules and packages, generated by compile_resources.ps1 + # because PyInstaller-frozen builds can't discover pure modules on disk + # (they live inside the PYZ archive). + from gen.build_vars import SRC_ROOT_MODULES + + def _lazy_imports_filter( + importer: str | None, + imported: str, + fromlist: tuple[str, ...] | None = None, # noqa: ARG001 + /, + ) -> bool: + # Only our own imports are lazy. Third-party internals must stay eager: + # shiboken6's exec'd signature bootstrap can't resolve lazy proxies + # (and hides behind aliased module names), and numpy's import-order + # self-check raises a bogus version conflict. + if not importer: + return False + # A package importing its own submodule must stay eager: the import + # system rebinds the submodule name on the parent package, clobbering + # any same-named lazy proxy in the package's namespace + # (e.g. "from capture_method.ScrotCaptureMethod import ScrotCaptureMethod"). + # TODO: Try to discuss online if this is intended, and if it can be worked around + # TODO: or maybe suggesting a lint to avoid this issue. + if imported.startswith(importer + "."): + return False + return importer.partition(".")[0] in SRC_ROOT_MODULES + + sys.set_lazy_imports_filter(_lazy_imports_filter) sys.set_lazy_imports("all") # Prevent PyAutoGUI and pywinctl from setting Process DPI Awareness, From 279218e7f9f3a1b38c2205c039a367243a3dbf6b Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 14:41:41 -0400 Subject: [PATCH 32/50] Much faster startup with lazy imports --- src/AutoSplit.py | 49 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index ac8d7983..8d8198ca 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -3,32 +3,49 @@ import sys if sys.version_info >= (3, 15): - # Our own top-level modules and packages, generated by compile_resources.ps1 - # because PyInstaller-frozen builds can't discover pure modules on disk - # (they live inside the PYZ archive). - from gen.build_vars import SRC_ROOT_MODULES + # Packages whose *internal* imports must stay eager + # (importing them from elsewhere is still lazy): + # - stdlib: gains nothing (loads at startup anyway), + # and its lazy proxies fail to reify under shiboken6's patched __import__ + # (e.g. typing.Union: "'lazy_import' object is not subscriptable"). + # - shiboken6/shibokensupport: patch __import__ (feature_import) and exec + # embedded modules behind aliased spec names + # (PySide6.support.signature.* vs shibokensupport.*). + # - numpy: its self-check raises a bogus version conflict when imported + # through shiboken6's patched __import__. + _EAGER_INTERNALS = ( + frozenset({ + "PySide6", + "shiboken6", + "shibokensupport", + "numpy", + }) + | sys.stdlib_module_names + ) def _lazy_imports_filter( - importer: str | None, + importing: str | None, imported: str, fromlist: tuple[str, ...] | None = None, # noqa: ARG001 /, ) -> bool: - # Only our own imports are lazy. Third-party internals must stay eager: - # shiboken6's exec'd signature bootstrap can't resolve lazy proxies - # (and hides behind aliased module names), and numpy's import-order - # self-check raises a bogus version conflict. - if not importer: + # No importer means exec'd/embedded code (e.g. shiboken6's signature + # bootstrap), which can't be trusted to resolve lazy proxies. + if not importing: return False - # A package importing its own submodule must stay eager: the import - # system rebinds the submodule name on the parent package, clobbering - # any same-named lazy proxy in the package's namespace - # (e.g. "from capture_method.ScrotCaptureMethod import ScrotCaptureMethod"). + # Imports within the same top-level package must stay eager: + # - A package importing its own submodule rebinds the submodule name on + # the parent package, clobbering any same-named lazy proxy in the + # package's namespace + # (e.g. "from capture_method.ScrotCaptureMethod import ScrotCaptureMethod"). + # - A relative "from . import x" binds a lazy proxy that fails to reify + # on attribute access (e.g. PIL/__init__.py's + # "__version__ = _version.__version__" sees the raw proxy). # TODO: Try to discuss online if this is intended, and if it can be worked around # TODO: or maybe suggesting a lint to avoid this issue. - if imported.startswith(importer + "."): + if importing.partition(".")[0] == imported.partition(".")[0]: return False - return importer.partition(".")[0] in SRC_ROOT_MODULES + return importing.partition(".")[0] not in _EAGER_INTERNALS sys.set_lazy_imports_filter(_lazy_imports_filter) sys.set_lazy_imports("all") From 1e22413cb35912c3b68eb41d73907227edf122cc Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 15:08:24 -0400 Subject: [PATCH 33/50] add ref https://github.com/python/cpython/issues/151208 --- src/AutoSplit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AutoSplit.py b/src/AutoSplit.py index 8d8198ca..d4d8918a 100755 --- a/src/AutoSplit.py +++ b/src/AutoSplit.py @@ -38,11 +38,11 @@ def _lazy_imports_filter( # the parent package, clobbering any same-named lazy proxy in the # package's namespace # (e.g. "from capture_method.ScrotCaptureMethod import ScrotCaptureMethod"). + # https://github.com/python/cpython/issues/151208 # - A relative "from . import x" binds a lazy proxy that fails to reify # on attribute access (e.g. PIL/__init__.py's # "__version__ = _version.__version__" sees the raw proxy). - # TODO: Try to discuss online if this is intended, and if it can be worked around - # TODO: or maybe suggesting a lint to avoid this issue. + # TODO: Report upstream, possibly same root cause as the issue above. if importing.partition(".")[0] == imported.partition(".")[0]: return False return importing.partition(".")[0] not in _EAGER_INTERNALS From 8bf8fc942367a5c3635cb5f1b594d258418688de Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 15:18:57 -0400 Subject: [PATCH 34/50] Make `shell: pwsh` the default --- .github/workflows/lint-and-build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 3690fc50..eb739e99 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -37,6 +37,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +defaults: + run: + shell: pwsh + jobs: Pyright: runs-on: ${{ matrix.os }} @@ -55,7 +59,6 @@ jobs: python-version: ${{ matrix.python-version }} activate-environment: true - run: scripts/install.ps1 - shell: pwsh - name: Analysing the code with Pyright uses: jakebailey/pyright-action@v3 with: @@ -116,7 +119,6 @@ jobs: with: arch: arm64 - run: scripts/install.ps1 ${{ matrix.wine-compat }} - shell: pwsh - run: "scripts/build.ps1 ${{ matrix.wine-compat }}" shell: pwsh - name: Add empty profile @@ -128,7 +130,6 @@ jobs: $Env:AUTOSPLIT_VERSION=uv run python -c "import utils; print(utils.AUTOSPLIT_VERSION)" echo "AUTOSPLIT_VERSION=$Env:AUTOSPLIT_VERSION" >> $Env:GITHUB_OUTPUT echo "OS=$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)" >> $Env:GITHUB_OUTPUT - shell: pwsh - name: Upload Build Artifact uses: actions/upload-artifact@v6 with: @@ -157,7 +158,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Annotate release template URL - shell: pwsh run: | $version = "v${{ needs.Build.outputs.AUTOSPLIT_VERSION }}" $body = [uri]::EscapeDataString(((@' From 6785091c6d28321421a7d3b6495488810cb02031 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 16:20:16 -0400 Subject: [PATCH 35/50] Add import tests --- .github/workflows/lint-and-build.yml | 6 +- ruff.toml | 2 + scripts/install.ps1 | 3 + tests/test_import_all_modules.py | 103 +++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tests/test_import_all_modules.py diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index eb739e99..f1426528 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -120,7 +120,11 @@ jobs: arch: arm64 - run: scripts/install.ps1 ${{ matrix.wine-compat }} - run: "scripts/build.ps1 ${{ matrix.wine-compat }}" - shell: pwsh + - name: Run test suite + # pywinctl/pymonctl connect to the X display at import-time, hence xvfb + run: >- + ${{ startsWith(matrix.os, 'ubuntu') && 'xvfb-run --auto-servernum' || '' }} + uv run -m unittest discover --start-directory tests --verbose - name: Add empty profile run: echo "" > dist/settings.toml - name: Extract AutoSplit version diff --git a/ruff.toml b/ruff.toml index a43af86e..45f5c245 100644 --- a/ruff.toml +++ b/ruff.toml @@ -9,6 +9,8 @@ ignore = [ "N999", # pep8-naming: Invalid module name # Print are used as debug logs "T20", # flake8-print + # We use unittest, not pytest + "PT", # flake8-pytest-style # This is a relatively small, low contributors project. Git blame suffice. "TD002", # missing-todo-author # We do work in __init__ modules diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 4828b488..3b497a5c 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -35,10 +35,13 @@ if ($IsLinux) { # System dependencies if (Get-Command apt-get -ErrorAction SilentlyContinue) { sudo apt-get update + # xvfb to run import smoke test headless on CI + $xvfb = $Env:GITHUB_JOB ? 'xvfb' : $null # python3-tk for splash screen # libxcb-cursor-dev for QT_QPA_PLATFORM=xcb # the rest for PySide6 sudo apt-get install -y ` + $xvfb ` python3-tk ` libxcb-cursor-dev ` libegl1 libxkbcommon0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1 diff --git a/tests/test_import_all_modules.py b/tests/test_import_all_modules.py new file mode 100644 index 00000000..29f5c213 --- /dev/null +++ b/tests/test_import_all_modules.py @@ -0,0 +1,103 @@ +""" +Smoke test: import every one of our own modules, including submodules. + +Catches import-time errors early: syntax errors, missing dependencies, +broken platform guards and lazy import issues in module-level code. +""" + +import importlib +import pkgutil +import subprocess # noqa: S404 +import sys +import textwrap +import unittest +from pathlib import Path + +SRC_DIR = Path(__file__).parent.parent / "src" +sys.path.insert(0, str(SRC_DIR)) + +from gen.build_vars import SRC_ROOT_MODULES # noqa: E402 + +EXCLUDED = {"__main__"} + +# Single-platform modules, by the platform they support. +# Importing one on any other platform is expected to raise OSError. +PLATFORM_MODULES = { + "win32": { + "capture_method.BitBltCaptureMethod", + "capture_method.DesktopDuplicationCaptureMethod", + "capture_method.ForceFullContentRenderingCaptureMethod", + "capture_method.WindowsGraphicsCaptureMethod", + "d3d11", + }, + "linux": { + "capture_method.Screenshot using QT attempt", + "capture_method.ScrotCaptureMethod", + "capture_method.XcbCaptureMethod", + }, +} +EXPECTED_OS_ERRORS = frozenset( + module + for platform, modules in PLATFORM_MODULES.items() + if platform != sys.platform + for module in modules +) + + +def iter_all_modules(): + """Yields every top-level module, followed by its direct submodules (source runs only).""" + for top_level in sorted(SRC_ROOT_MODULES.difference(EXCLUDED)): + yield top_level + for submodule in pkgutil.iter_modules([str(SRC_DIR / top_level)]): + yield f"{top_level}.{submodule.name}" + + +class TestImportAllModules(unittest.TestCase): + def test_import_all_modules(self): + for module_name in iter_all_modules(): + with self.subTest(module=module_name): + if module_name in EXPECTED_OS_ERRORS: + with self.assertRaises(OSError): + importlib.import_module(module_name) + continue + module = importlib.import_module(module_name) + # Force every lazy import proxy to resolve. eval's LOAD_NAME + # on the module's namespace triggers reification + # (plain getattr does not). + for attr_name in [ + k for k, v in vars(module).items() if type(v).__name__ == "lazy_import" + ]: + eval(attr_name, vars(module)) # noqa: S307 + + def test_app_entrypoint_in_fresh_interpreter(self): + """ + The test runner itself has already imported most of the stdlib, which + masks lazy import issues that only occur with a clean sys.modules + (e.g. shiboken6's bootstrap importing stdlib modules through lazy + proxies). Mimic a real app launch instead. + + Also probes shiboken6's signature support: its bootstrap swallows + errors and only logs them, and it isn't otherwise guaranteed to be + exercised by mere imports. + """ + code = textwrap.dedent(""" + import AutoSplit + import inspect + from PySide6 import QtCore + signature = inspect.signature(QtCore.QObject.objectName) + assert isinstance(signature, inspect.Signature), signature + """) + # Trusted, hardcoded code string ran with our own interpreter + result = subprocess.run( # noqa: S603 + [sys.executable, "-c", code], + capture_output=True, + text=True, + check=False, + cwd=SRC_DIR, + timeout=120, + ) + self.assertEqual(result.returncode, 0, msg=result.stderr) + + +if __name__ == "__main__": + unittest.main() From 742c702a8b736fad3dcde84f3675af1cbf5c3b34 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 16:31:55 -0400 Subject: [PATCH 36/50] Also install x11-xserver-utils --- .github/workflows/lint-and-build.yml | 1 + scripts/install.ps1 | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index f1426528..957596db 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -113,6 +113,7 @@ jobs: || null }} # endregion # MinGW (cc) fails SIZEOF_PY_INTPTR_T detection on ARM64; force MSVC for numpy sdist + # TODO: Remove this action once we use numpy 3.15 wheels - name: Set up MSVC ARM64 environment if: ${{ matrix.os == 'windows-11-arm' && matrix.python-version == '3.15' }} uses: ilammy/msvc-dev-cmd@v1 diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 3b497a5c..1a3b4598 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -35,8 +35,9 @@ if ($IsLinux) { # System dependencies if (Get-Command apt-get -ErrorAction SilentlyContinue) { sudo apt-get update - # xvfb to run import smoke test headless on CI - $xvfb = $Env:GITHUB_JOB ? 'xvfb' : $null + # xvfb to run tests headless on CI + # x11-xserver-utils (xset, xrandr) which pymonctl requires at import + $xvfb = $Env:GITHUB_JOB ? @('xvfb', 'x11-xserver-utils') : $null # python3-tk for splash screen # libxcb-cursor-dev for QT_QPA_PLATFORM=xcb # the rest for PySide6 From 4480c2c1d791649b3ed52baf8110c320f0dad4d8 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 12 Jun 2026 16:48:01 -0400 Subject: [PATCH 37/50] Avoid marking already installed packages as manual --- scripts/install.ps1 | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 1a3b4598..e670c336 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -33,19 +33,28 @@ if ($IsLinux) { if ($IsLinux) { if (-not $Env:GITHUB_JOB -or $Env:GITHUB_JOB -eq 'Build') { # System dependencies - if (Get-Command apt-get -ErrorAction SilentlyContinue) { - sudo apt-get update - # xvfb to run tests headless on CI - # x11-xserver-utils (xset, xrandr) which pymonctl requires at import - $xvfb = $Env:GITHUB_JOB ? @('xvfb', 'x11-xserver-utils') : $null - # python3-tk for splash screen - # libxcb-cursor-dev for QT_QPA_PLATFORM=xcb - # the rest for PySide6 - sudo apt-get install -y ` - $xvfb ` - python3-tk ` - libxcb-cursor-dev ` - libegl1 libxkbcommon0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1 + if ((Get-Command apt-get, dpkg-query -ErrorAction SilentlyContinue).Count -eq 2) { + $packages = @( + # For running tests headless on CI + ($Env:GITHUB_JOB ? 'xvfb' : $null), + # Required by pymonctl at import + 'x11-xserver-utils', + # For splash screen + 'python3-tk', + # For QT_QPA_PLATFORM=xcb + 'libxcb-cursor-dev', + # The rest for PySide6 + 'libegl1', 'libxkbcommon0', 'libxkbcommon-x11-0', 'libxcb-icccm4', 'libxcb-keysyms1' + ).Where({ $_ }) + # Only install missing packages so apt doesn't re-mark them as manually installed. + # Multi-arch packages report one status line per architecture. + $missing = $packages.Where({ + @(dpkg-query -W -f='${db:Status-Status}\n' $_ 2>$null) -notcontains 'installed' + }) + if ($missing) { + sudo apt-get update + sudo apt-get install -y $missing + } } Write-Output 'Installing appimagetool' @@ -100,8 +109,9 @@ $Env:CMAKE_ARGS = '-DBUILD_opencv_dnn=OFF -DENABLE_NEON=OFF' $prod = if ($Env:GITHUB_JOB -eq 'Build') { '--no-dev' } else { } $lock = if ($Env:GITHUB_JOB) { '--locked' } else { } +$verbose = if ($Env:GITHUB_JOB) { '--verbose' } else { } # Verbose to see sdist progression -$uvSyncArgs = @('sync', '--verbose', '--active') + $prod + $lock +$uvSyncArgs = @('sync', '--active') + $prod + $lock + $verbose Write-Output "Installing Python dependencies with: uv $uvSyncArgs" uv @uvSyncArgs From 631eae57fa5c6aaced3bc50d4af9e5a0499cefeb Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 13 Jun 2026 13:22:57 -0400 Subject: [PATCH 38/50] tool.uv.exclude-newer-packag.pyinstaller-hooks-contrib = false # pyinstaller develop build --- pyproject.toml | 1 + uv.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 47f72219..d576b215 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,6 +81,7 @@ find-links = ["./scripts"] # Discover local wheels exclude-newer = "1 week" [tool.uv.exclude-newer-package] typed-D3DShot = false # I own it +pyinstaller-hooks-contrib = false # pyinstaller develop build ### # Development channels diff --git a/uv.lock b/uv.lock index e44cab68..02226f45 100644 --- a/uv.lock +++ b/uv.lock @@ -22,6 +22,7 @@ exclude-newer-span = "P1W" [options.exclude-newer-package] typed-d3dshot = false +pyinstaller-hooks-contrib = false [manifest] @@ -485,7 +486,7 @@ wheels = [ [[package]] name = "pyinstaller" -version = "6.20.0" +version = "6.21.0" source = { url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" } dependencies = [ { name = "altgraph", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -495,7 +496,7 @@ dependencies = [ { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { hash = "sha256:f90f479bb4c4a63c3119eedffd778d3cbea7d842821b286bd25a5bd6dba6c860" } +sdist = { hash = "sha256:e044252d7577d5800c6f7fe7a944e3e934458146a11fb4876917916f587c2da8" } [package.metadata] requires-dist = [ @@ -507,7 +508,7 @@ requires-dist = [ { name = "packaging", specifier = ">=22.0" }, { name = "pefile", marker = "sys_platform == 'win32'", specifier = ">=2022.5.30" }, { name = "psutil", marker = "extra == 'hook-testing'" }, - { name = "pyinstaller-hooks-contrib", specifier = ">=2026.4" }, + { name = "pyinstaller-hooks-contrib", specifier = ">=2026.6" }, { name = "pytest", marker = "extra == 'hook-testing'", specifier = ">=2.7.3" }, { name = "pywin32-ctypes", marker = "sys_platform == 'win32'", specifier = ">=0.2.1" }, { name = "setuptools", specifier = ">=42.0.0" }, @@ -516,15 +517,14 @@ provides-extras = ["completion", "hook-testing"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2026.5" +version = "2026.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1a/67/f4452d68793fb15beba4f19ef39a38a8822f0da7452b503c400d5a21f5c1/pyinstaller_hooks_contrib-2026.5.tar.gz", hash = "sha256:f066dfca8f7c45ff6336c9cf9fe25b4e48bfeb322a1aa24faaedfb8a8d1b0b08", size = 173689, upload-time = "2026-05-04T22:36:55.124Z" } +sdist = { url = "https://files.pythonhosted.org/packages/94/5b/c9fe0db5e83ee1c39b2258fa21d23b15e1a60786b6c5990ee5074ead8bb6/pyinstaller_hooks_contrib-2026.6.tar.gz", hash = "sha256:bef5002c32f4f50bd55b005da12cff64eca8783e7eaf86a06a62410164bab725", size = 173354, upload-time = "2026-06-08T22:37:16.152Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/5c/fd465d11da4d12b50d7eb5d2ee2ceb780d8d049dbb489f3828d131e387af/pyinstaller_hooks_contrib-2026.5-py3-none-any.whl", hash = "sha256:ea1535783fbdac4626351709e83f3ea80b681d3a4745763ebb407b5e27342eb9", size = 457314, upload-time = "2026-05-04T22:36:53.598Z" }, + { url = "https://files.pythonhosted.org/packages/e7/31/f2d7343d8ed5f7c4678377886f6ce533e6eaaa131b252ce950114c2a7efa/pyinstaller_hooks_contrib-2026.6-py3-none-any.whl", hash = "sha256:fd13b8ac126b35361175edacd41a0d97080b75dd5f4b594ecefefff969509dd3", size = 457159, upload-time = "2026-06-08T22:37:14.722Z" }, ] [[package]] From 0f12c1b25812479ab8884565e9f8540bfe182cb7 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 13:20:54 -0400 Subject: [PATCH 39/50] fix lockfile --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 22caa0f9..63dd94f3 100644 --- a/uv.lock +++ b/uv.lock @@ -492,7 +492,7 @@ dependencies = [ { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { hash = "sha256:e044252d7577d5800c6f7fe7a944e3e934458146a11fb4876917916f587c2da8" } +sdist = { hash = "sha256:adde8febec31a86057f8655b92f778000eef6816593b65309aceb8ab26fd51a3" } [package.metadata] requires-dist = [ From 35633386e3872147cd2cc1397a3553e7a696e9b7 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 13:24:56 -0400 Subject: [PATCH 40/50] Add Levenshtein exclusion --- .github/workflows/lint-and-build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 3900a7a3..519a2e30 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -51,7 +51,8 @@ jobs: # Per-package no-binary overrides no-build, allowing # known pure-Python source-only dependencies to still build. # The Build job intentionally builds some binary packages from source. - UV_NO_BINARY_PACKAGE: keyboard pyinstaller PyAutoGUI beslogic-ruff-config + # TODO: Remove Levenshtein once 3.15 wheels released + UV_NO_BINARY_PACKAGE: keyboard pyinstaller PyAutoGUI beslogic-ruff-config Levenshtein strategy: fail-fast: false # Pyright is version and platform sensible From aebb397828bcec0f29524c3beb565651d2a9a210 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 13:33:48 -0400 Subject: [PATCH 41/50] numpy --- .github/workflows/lint-and-build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 519a2e30..cb35ffce 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -51,8 +51,10 @@ jobs: # Per-package no-binary overrides no-build, allowing # known pure-Python source-only dependencies to still build. # The Build job intentionally builds some binary packages from source. - # TODO: Remove Levenshtein once 3.15 wheels released - UV_NO_BINARY_PACKAGE: keyboard pyinstaller PyAutoGUI beslogic-ruff-config Levenshtein + # Levenshtein and numpy don't have 3.15 wheels yet; remove once they do. + UV_NO_BINARY_PACKAGE: >- + keyboard pyinstaller PyAutoGUI beslogic-ruff-config + ${{ matrix.python-version != '3.15' && 'Levenshtein numpy' || '' }} strategy: fail-fast: false # Pyright is version and platform sensible From 820f09527e3ee7758740fd7f1687ca0d29f15599 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 13:36:47 -0400 Subject: [PATCH 42/50] Inverted condition --- .github/workflows/lint-and-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index cb35ffce..34115296 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -54,7 +54,7 @@ jobs: # Levenshtein and numpy don't have 3.15 wheels yet; remove once they do. UV_NO_BINARY_PACKAGE: >- keyboard pyinstaller PyAutoGUI beslogic-ruff-config - ${{ matrix.python-version != '3.15' && 'Levenshtein numpy' || '' }} + ${{ matrix.python-version == '3.15' && 'Levenshtein numpy' || '' }} strategy: fail-fast: false # Pyright is version and platform sensible From d6823fdd6390040b3d7f2165b1915c9dfc07ff16 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 13:40:40 -0400 Subject: [PATCH 43/50] pyinstaller better hash --- .github/workflows/lint-and-build.yml | 6 +++--- pyproject.toml | 4 +++- uv.lock | 22 ++-------------------- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 34115296..5f121af3 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -51,10 +51,10 @@ jobs: # Per-package no-binary overrides no-build, allowing # known pure-Python source-only dependencies to still build. # The Build job intentionally builds some binary packages from source. - # Levenshtein and numpy don't have 3.15 wheels yet; remove once they do. UV_NO_BINARY_PACKAGE: >- - keyboard pyinstaller PyAutoGUI beslogic-ruff-config - ${{ matrix.python-version == '3.15' && 'Levenshtein numpy' || '' }} + keyboard PyAutoGUI beslogic-ruff-config + ${{ matrix.python-version == '3.15' && 'Levenshtein numpy pyinstaller' || '' }} + # TODO: ^ Remove these exceptions once 3.15 wheels are released strategy: fail-fast: false # Pyright is version and platform sensible diff --git a/pyproject.toml b/pyproject.toml index a32ec26c..b230b392 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,9 @@ beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config # pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.15'" } # numpy = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } -pyinstaller = { url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" } +# NOTE: pyinstaller exposes https://github.com/pyinstaller/pyinstaller/archive/develop.zip, +# but that hash may change at any time. Whilst git hashes persist +pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller.git" } [[tool.uv.index]] exclude-newer = false # Anaconda index doesn't have upload dates diff --git a/uv.lock b/uv.lock index 63dd94f3..63025846 100644 --- a/uv.lock +++ b/uv.lock @@ -137,7 +137,7 @@ requires-dist = [ { name = "pillow", marker = "python_full_version >= '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, - { name = "pyinstaller", url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" }, + { name = "pyinstaller", git = "https://github.com/pyinstaller/pyinstaller.git" }, { name = "pyside6-essentials", specifier = ">=6.9.0" }, { name = "python-xlib", marker = "sys_platform == 'linux'", specifier = ">=0.33" }, { name = "pywin32", marker = "sys_platform == 'win32'", specifier = ">=312" }, @@ -483,7 +483,7 @@ wheels = [ [[package]] name = "pyinstaller" version = "6.21.0" -source = { url = "https://github.com/pyinstaller/pyinstaller/archive/develop.zip" } +source = { git = "https://github.com/pyinstaller/pyinstaller.git#f809c9d1a4d82ed949912ada2fb9d46a112ce3d1" } dependencies = [ { name = "altgraph", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -492,24 +492,6 @@ dependencies = [ { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, ] -sdist = { hash = "sha256:adde8febec31a86057f8655b92f778000eef6816593b65309aceb8ab26fd51a3" } - -[package.metadata] -requires-dist = [ - { name = "altgraph" }, - { name = "argcomplete", marker = "extra == 'completion'" }, - { name = "execnet", marker = "extra == 'hook-testing'", specifier = ">=1.5.0" }, - { name = "importlib-metadata", marker = "python_full_version < '3.10'", specifier = ">=4.6" }, - { name = "macholib", marker = "sys_platform == 'darwin'", specifier = ">=1.8" }, - { name = "packaging", specifier = ">=22.0" }, - { name = "pefile", marker = "sys_platform == 'win32'", specifier = ">=2022.5.30" }, - { name = "psutil", marker = "extra == 'hook-testing'" }, - { name = "pyinstaller-hooks-contrib", specifier = ">=2026.6" }, - { name = "pytest", marker = "extra == 'hook-testing'", specifier = ">=2.7.3" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'", specifier = ">=0.2.1" }, - { name = "setuptools", specifier = ">=42.0.0" }, -] -provides-extras = ["completion", "hook-testing"] [[package]] name = "pyinstaller-hooks-contrib" From cf7748e13e1108cb1561ec2cdb024d324dca6535 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 13:42:15 -0400 Subject: [PATCH 44/50] unecessary comment --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b230b392..da51c588 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,8 +94,6 @@ beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config # pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.15'" } # numpy = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } -# NOTE: pyinstaller exposes https://github.com/pyinstaller/pyinstaller/archive/develop.zip, -# but that hash may change at any time. Whilst git hashes persist pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller.git" } [[tool.uv.index]] From 2b9905bade2126ce9705c9fa1745850561dae21c Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 15:26:54 -0400 Subject: [PATCH 45/50] Add more 3.15 markers --- pyproject.toml | 4 +-- uv.lock | 70 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index da51c588..dd3df779 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ dev = [ # # Linters & Formatters "dprint-py >=0.50.0.0", - "mypy >=2.1", # TODO: Bump when 3.15 wheels + "mypy >=2.1; python_version < '3.15'", # TODO: Bump when 3.15 wheels "pyright[nodejs] >=1.1.400", # reportPrivateImportUsage behaviour change { include-group = "ruff" }, # @@ -94,7 +94,7 @@ beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config # pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.15'" } # numpy = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } -pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller.git" } +pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller.git", marker = "python_version >= '3.15'" } [[tool.uv.index]] exclude-newer = false # Anaconda index doesn't have upload dates diff --git a/uv.lock b/uv.lock index 63025846..0968e0fe 100644 --- a/uv.lock +++ b/uv.lock @@ -91,7 +91,8 @@ dependencies = [ { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "python_full_version >= '3.15' and sys_platform == 'linux'" }, { name = "pyautogui", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pygrabber", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pyinstaller", version = "6.20.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pyinstaller", version = "6.21.0", source = { git = "https://github.com/pyinstaller/pyinstaller.git#f809c9d1a4d82ed949912ada2fb9d46a112ce3d1" }, marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, { name = "pyside6-essentials", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "python-xlib", marker = "sys_platform == 'linux'" }, { name = "pywin32", marker = "sys_platform == 'win32'" }, @@ -112,7 +113,7 @@ dependencies = [ dev = [ { name = "beslogic-ruff-config", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "dprint-py", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "mypy", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "mypy", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, { name = "pyright", extra = ["nodejs"], marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "ruff", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "types-keyboard", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, @@ -137,7 +138,8 @@ requires-dist = [ { name = "pillow", marker = "python_full_version >= '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, - { name = "pyinstaller", git = "https://github.com/pyinstaller/pyinstaller.git" }, + { name = "pyinstaller", marker = "python_full_version < '3.15'", specifier = ">=6.15.0" }, + { name = "pyinstaller", marker = "python_full_version >= '3.15'", git = "https://github.com/pyinstaller/pyinstaller.git" }, { name = "pyside6-essentials", specifier = ">=6.9.0" }, { name = "python-xlib", marker = "sys_platform == 'linux'", specifier = ">=0.33" }, { name = "pywin32", marker = "sys_platform == 'win32'", specifier = ">=312" }, @@ -158,7 +160,7 @@ requires-dist = [ dev = [ { name = "beslogic-ruff-config", git = "https://github.com/Beslogic/Beslogic-Ruff-Config?rev=312cfab8a1e2653639a2ef665e99eac6c7412ba7" }, { name = "dprint-py", specifier = ">=0.50.0.0" }, - { name = "mypy", specifier = ">=2.1" }, + { name = "mypy", marker = "python_full_version < '3.15'", specifier = ">=2.1" }, { name = "pyright", extras = ["nodejs"], specifier = ">=1.1.400" }, { name = "ruff" }, { name = "types-keyboard" }, @@ -280,11 +282,11 @@ name = "mypy" version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ast-serialize", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "librt", marker = "(platform_python_implementation != 'PyPy' and sys_platform == 'linux') or (platform_python_implementation != 'PyPy' and sys_platform == 'win32')" }, - { name = "mypy-extensions", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pathspec", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "typing-extensions", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "ast-serialize", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "librt", marker = "(python_full_version < '3.15' and platform_python_implementation != 'PyPy' and sys_platform == 'linux') or (python_full_version < '3.15' and platform_python_implementation != 'PyPy' and sys_platform == 'win32')" }, + { name = "mypy-extensions", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pathspec", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "typing-extensions", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/82/15/cca9d88503549ed6fedeaa1d448cdddd542ee8a490232d732e278036fbf2/mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633", size = 3898359, upload-time = "2026-05-11T18:37:36.237Z" } wheels = [ @@ -480,17 +482,55 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/51/0359e171686a7eeda5e975d7f9dfba6a67e04b33c7ddad1f7a343c171e55/pygrabber-0.2-py3-none-any.whl", hash = "sha256:5ac8bbe5f6a5dfb7c1c9c55d80ca9b9457743abd3ac8efa21cb9e302bdbf03ac", size = 24193, upload-time = "2023-10-20T07:17:13.1Z" }, ] +[[package]] +name = "pyinstaller" +version = "6.20.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version < '3.15' and platform_machine == 'ARM64' and sys_platform == 'win32'", + "python_full_version < '3.15' and platform_machine != 'ARM64' and sys_platform == 'win32'", +] +dependencies = [ + { name = "altgraph", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "packaging", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pefile", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, + { name = "pywin32-ctypes", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, + { name = "setuptools", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/60/d03d52e6690d4e9caf333dcd14550cde634ce6c118b3bc8fa3112c3186fd/pyinstaller-6.20.0.tar.gz", hash = "sha256:95c5c7e03d5d61e9dfb8ef259c699cf492bb1041beb6dbe83696608cec07347a", size = 4048728, upload-time = "2026-04-22T20:59:36.96Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/bd/afb631bcb3f9040efebd4f6d067f0828b51710818f69fb41a2d4b7787f52/pyinstaller-6.20.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:72ae9c1fdea134afa791f58bdc9a1934d5c7609753c111e0026bfc272b32b712", size = 742494, upload-time = "2026-04-22T20:58:36.285Z" }, + { url = "https://files.pythonhosted.org/packages/76/08/0729a5bac14754150e5d83b39d87d842eb42b0bffcaa03dbad6252e23a39/pyinstaller-6.20.0-py3-none-manylinux2014_i686.whl", hash = "sha256:1031bcc307f3fbeffd4e162723e64d46dbf591c82dd0997413afb2a07328b941", size = 754191, upload-time = "2026-04-22T20:58:40.603Z" }, + { url = "https://files.pythonhosted.org/packages/e6/82/bc0ee4c7b97db1958eb651e0da9fb1e672e5ae53ca8867fd97701de52906/pyinstaller-6.20.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:8df3b3f347659fa2562d8d193a98ad4600133b8b8d07c268df89e4154376750e", size = 751902, upload-time = "2026-04-22T20:58:44.7Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e7/770002d6aaa54173881cb2c49bb195ba67b97bf39bac1cdf320f28401629/pyinstaller-6.20.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b0d3cc9dd8120d448459bd3880a12e2f9774c51443af49047801446377999a59", size = 748634, upload-time = "2026-04-22T20:58:48.579Z" }, + { url = "https://files.pythonhosted.org/packages/fe/db/68ba1fccb71278b2124fb90b37b7c8c0bc4c1173fba45b94466df3d9cb7f/pyinstaller-6.20.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:03696bb6350177c6bc23bcaf78e71a33c4a89b6754dd90d1be2f318e978c918b", size = 748490, upload-time = "2026-04-22T20:58:52.749Z" }, + { url = "https://files.pythonhosted.org/packages/03/0f/ac77ffa996a56be3d5c8f85734a007f8347240691657f9704e7de2527fa3/pyinstaller-6.20.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:6357f1699f6af84f37e7367f031d4f68abdba65543b83990c9e8f5a4cebed0b7", size = 747650, upload-time = "2026-04-22T20:58:57.093Z" }, + { url = "https://files.pythonhosted.org/packages/e0/56/1ee91c3a2bc10ca1f36da10a6fd55ff7efc4dec367171eb25992a827874f/pyinstaller-6.20.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0ab39c690abad26ba148e8f664f0478acc82a733997f4f22e757774832802da9", size = 747413, upload-time = "2026-04-22T20:59:01.174Z" }, + { url = "https://files.pythonhosted.org/packages/d7/55/ae264339996953c4cdf9d89d916a0a8fa26a83cf917a742fff8b9d5f3fe8/pyinstaller-6.20.0-py3-none-win32.whl", hash = "sha256:9a7637e8e44b4387b13667fdcaac86ab6b29c446c16d34d8401539b81838759c", size = 1331584, upload-time = "2026-04-22T20:59:07.201Z" }, + { url = "https://files.pythonhosted.org/packages/76/8c/300f57578882cce259bfb5ae56fda3b69caa3fe9df40a176c719920ea6e2/pyinstaller-6.20.0-py3-none-win_amd64.whl", hash = "sha256:d588844e890ee80c4365867f98146636e1849bbca8e4284bbf0c809aff0f161a", size = 1391851, upload-time = "2026-04-22T20:59:14.024Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ea/b2f8e1642aecda78c0b75c7321f708e49e10bb3c00dd4f148c40761a1527/pyinstaller-6.20.0-py3-none-win_arm64.whl", hash = "sha256:bd53282c0a73e5c95573e1ddc8e5d564d4932bec91efbaed4dc5fdff9c2ae7f2", size = 1332259, upload-time = "2026-04-22T20:59:20.509Z" }, +] + [[package]] name = "pyinstaller" version = "6.21.0" source = { git = "https://github.com/pyinstaller/pyinstaller.git#f809c9d1a4d82ed949912ada2fb9d46a112ce3d1" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", + "python_full_version >= '3.15' and platform_machine == 'ARM64' and sys_platform == 'win32'", + "python_full_version >= '3.15' and platform_machine != 'ARM64' and sys_platform == 'win32'", +] dependencies = [ - { name = "altgraph", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pefile", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, - { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "altgraph", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "packaging", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "pefile", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "pywin32-ctypes", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, + { name = "setuptools", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, ] [[package]] From 1773ecadecef0c1c73abbd5f2fb51521aaac6442 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 15:46:56 -0400 Subject: [PATCH 46/50] Add more --- .github/workflows/lint-and-build.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 5f121af3..5d3e3d3f 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -53,7 +53,15 @@ jobs: # The Build job intentionally builds some binary packages from source. UV_NO_BINARY_PACKAGE: >- keyboard PyAutoGUI beslogic-ruff-config - ${{ matrix.python-version == '3.15' && 'Levenshtein numpy pyinstaller' || '' }} + ${{ matrix.python-version == '3.15' && 'RapidFuzz Levenshtein numpy pyinstaller' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Foundation' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.Capture' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.Capture.Interop' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.DirectX' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.DirectX.Direct3D11' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.DirectX.Direct3D11.Interop' || '' }} + ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.Imaging' || '' }} # TODO: ^ Remove these exceptions once 3.15 wheels are released strategy: fail-fast: false From fa7f24a1959613c6fe66919881a2916489940b4a Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 15:53:56 -0400 Subject: [PATCH 47/50] UV_NO_BUILD conditional --- .github/workflows/lint-and-build.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 5d3e3d3f..03aeeed9 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -47,21 +47,13 @@ jobs: env: # Prevent accidentally slower type-checking due to missing arm wheels. # Fail rather than accidentally compile C/binary extensions from sdist. - UV_NO_BUILD: true + UV_NO_BUILD: ${{ !(matrix.python-version == '3.15' && matrix.os == 'windows-latest') }} # winrt-Windows no wheels for 3.15 yet # Per-package no-binary overrides no-build, allowing # known pure-Python source-only dependencies to still build. # The Build job intentionally builds some binary packages from source. UV_NO_BINARY_PACKAGE: >- keyboard PyAutoGUI beslogic-ruff-config ${{ matrix.python-version == '3.15' && 'RapidFuzz Levenshtein numpy pyinstaller' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Foundation' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.Capture' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.Capture.Interop' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.DirectX' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.DirectX.Direct3D11' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.DirectX.Direct3D11.Interop' || '' }} - ${{ matrix.python-version == '3.15' && 'winrt-Windows.Graphics.Imaging' || '' }} # TODO: ^ Remove these exceptions once 3.15 wheels are released strategy: fail-fast: false From 9a08d9009f8e5735383a7c4e780b3ab048c529e2 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 15 Jun 2026 16:50:07 -0400 Subject: [PATCH 48/50] Bump pyinstaller 3.15 release --- .github/workflows/lint-and-build.yml | 2 +- pyproject.toml | 8 +-- uv.lock | 74 +++++++++------------------- 3 files changed, 30 insertions(+), 54 deletions(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 03aeeed9..6b2d7aaa 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -53,7 +53,7 @@ jobs: # The Build job intentionally builds some binary packages from source. UV_NO_BINARY_PACKAGE: >- keyboard PyAutoGUI beslogic-ruff-config - ${{ matrix.python-version == '3.15' && 'RapidFuzz Levenshtein numpy pyinstaller' || '' }} + ${{ matrix.python-version == '3.15' && 'RapidFuzz Levenshtein numpy' || '' }} # TODO: ^ Remove these exceptions once 3.15 wheels are released strategy: fail-fast: false diff --git a/pyproject.toml b/pyproject.toml index dd3df779..fe861f9e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ dependencies = [ # # Build and compile resources - "pyinstaller >=6.15.0", # Python 3.14 support # TODO: Bump when 3.15 wheels + "pyinstaller >=6.21.0", # Python 3.15 support # # https://packaging.python.org/en/latest/specifications/dependency-specifiers/#environment-markers @@ -84,7 +84,9 @@ find-links = ["./scripts"] # Discover local wheels exclude-newer = "1 week" [tool.uv.exclude-newer-package] typed-D3DShot = false # I own it -pyinstaller-hooks-contrib = false # pyinstaller develop build +# pyinstaller-hooks-contrib = false # pyinstaller develop build +pyinstaller = "2 days" # TODO: REMOVE BEFORE MERGING +pyinstaller-hooks-contrib = "6 days" # TODO: REMOVE BEFORE MERGING ### # Development channels @@ -92,9 +94,9 @@ pyinstaller-hooks-contrib = false # pyinstaller develop build [tool.uv.sources] beslogic-ruff-config = { git = "https://github.com/Beslogic/Beslogic-Ruff-Config", rev = "312cfab8a1e2653639a2ef665e99eac6c7412ba7" } # pywin32 = { git = "https://github.com/mhammond/pywin32.git", marker = "python_version >= '3.15'" } +# pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller.git", marker = "python_version >= '3.15'" } # numpy = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } pillow = { index = "scientific-python-nightly-wheels", marker = "python_version >= '3.15'" } -pyinstaller = { git = "https://github.com/pyinstaller/pyinstaller.git", marker = "python_version >= '3.15'" } [[tool.uv.index]] exclude-newer = false # Anaconda index doesn't have upload dates diff --git a/uv.lock b/uv.lock index 0968e0fe..643e7d26 100644 --- a/uv.lock +++ b/uv.lock @@ -22,7 +22,8 @@ exclude-newer-span = "P1W" [options.exclude-newer-package] typed-d3dshot = false -pyinstaller-hooks-contrib = false +pyinstaller-hooks-contrib = { timestamp = "0001-01-01T00:00:00Z", span = "P6D" } +pyinstaller = { timestamp = "0001-01-01T00:00:00Z", span = "P2D" } [manifest] @@ -91,8 +92,7 @@ dependencies = [ { name = "pillow", version = "12.3.0.dev0", source = { registry = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, marker = "python_full_version >= '3.15' and sys_platform == 'linux'" }, { name = "pyautogui", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pygrabber", marker = "sys_platform == 'win32'" }, - { name = "pyinstaller", version = "6.20.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "pyinstaller", version = "6.21.0", source = { git = "https://github.com/pyinstaller/pyinstaller.git#f809c9d1a4d82ed949912ada2fb9d46a112ce3d1" }, marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "pyinstaller", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "pyside6-essentials", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, { name = "python-xlib", marker = "sys_platform == 'linux'" }, { name = "pywin32", marker = "sys_platform == 'win32'" }, @@ -138,8 +138,7 @@ requires-dist = [ { name = "pillow", marker = "python_full_version >= '3.15' and sys_platform == 'linux'", specifier = ">=12.2.0", index = "https://pypi.anaconda.org/scientific-python-nightly-wheels/simple" }, { name = "pyautogui", specifier = ">=0.9.52" }, { name = "pygrabber", marker = "sys_platform == 'win32'", specifier = ">=0.2" }, - { name = "pyinstaller", marker = "python_full_version < '3.15'", specifier = ">=6.15.0" }, - { name = "pyinstaller", marker = "python_full_version >= '3.15'", git = "https://github.com/pyinstaller/pyinstaller.git" }, + { name = "pyinstaller", specifier = ">=6.21.0" }, { name = "pyside6-essentials", specifier = ">=6.9.0" }, { name = "python-xlib", marker = "sys_platform == 'linux'", specifier = ">=0.33" }, { name = "pywin32", marker = "sys_platform == 'win32'", specifier = ">=312" }, @@ -482,55 +481,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7a/51/0359e171686a7eeda5e975d7f9dfba6a67e04b33c7ddad1f7a343c171e55/pygrabber-0.2-py3-none-any.whl", hash = "sha256:5ac8bbe5f6a5dfb7c1c9c55d80ca9b9457743abd3ac8efa21cb9e302bdbf03ac", size = 24193, upload-time = "2023-10-20T07:17:13.1Z" }, ] -[[package]] -name = "pyinstaller" -version = "6.20.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version < '3.15' and platform_machine == 'ARM64' and sys_platform == 'win32'", - "python_full_version < '3.15' and platform_machine != 'ARM64' and sys_platform == 'win32'", -] -dependencies = [ - { name = "altgraph", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "packaging", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "pefile", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, - { name = "pywin32-ctypes", marker = "python_full_version < '3.15' and sys_platform == 'win32'" }, - { name = "setuptools", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version < '3.15' and sys_platform == 'win32')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/46/60/d03d52e6690d4e9caf333dcd14550cde634ce6c118b3bc8fa3112c3186fd/pyinstaller-6.20.0.tar.gz", hash = "sha256:95c5c7e03d5d61e9dfb8ef259c699cf492bb1041beb6dbe83696608cec07347a", size = 4048728, upload-time = "2026-04-22T20:59:36.96Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/bd/afb631bcb3f9040efebd4f6d067f0828b51710818f69fb41a2d4b7787f52/pyinstaller-6.20.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:72ae9c1fdea134afa791f58bdc9a1934d5c7609753c111e0026bfc272b32b712", size = 742494, upload-time = "2026-04-22T20:58:36.285Z" }, - { url = "https://files.pythonhosted.org/packages/76/08/0729a5bac14754150e5d83b39d87d842eb42b0bffcaa03dbad6252e23a39/pyinstaller-6.20.0-py3-none-manylinux2014_i686.whl", hash = "sha256:1031bcc307f3fbeffd4e162723e64d46dbf591c82dd0997413afb2a07328b941", size = 754191, upload-time = "2026-04-22T20:58:40.603Z" }, - { url = "https://files.pythonhosted.org/packages/e6/82/bc0ee4c7b97db1958eb651e0da9fb1e672e5ae53ca8867fd97701de52906/pyinstaller-6.20.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:8df3b3f347659fa2562d8d193a98ad4600133b8b8d07c268df89e4154376750e", size = 751902, upload-time = "2026-04-22T20:58:44.7Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e7/770002d6aaa54173881cb2c49bb195ba67b97bf39bac1cdf320f28401629/pyinstaller-6.20.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:b0d3cc9dd8120d448459bd3880a12e2f9774c51443af49047801446377999a59", size = 748634, upload-time = "2026-04-22T20:58:48.579Z" }, - { url = "https://files.pythonhosted.org/packages/fe/db/68ba1fccb71278b2124fb90b37b7c8c0bc4c1173fba45b94466df3d9cb7f/pyinstaller-6.20.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:03696bb6350177c6bc23bcaf78e71a33c4a89b6754dd90d1be2f318e978c918b", size = 748490, upload-time = "2026-04-22T20:58:52.749Z" }, - { url = "https://files.pythonhosted.org/packages/03/0f/ac77ffa996a56be3d5c8f85734a007f8347240691657f9704e7de2527fa3/pyinstaller-6.20.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:6357f1699f6af84f37e7367f031d4f68abdba65543b83990c9e8f5a4cebed0b7", size = 747650, upload-time = "2026-04-22T20:58:57.093Z" }, - { url = "https://files.pythonhosted.org/packages/e0/56/1ee91c3a2bc10ca1f36da10a6fd55ff7efc4dec367171eb25992a827874f/pyinstaller-6.20.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0ab39c690abad26ba148e8f664f0478acc82a733997f4f22e757774832802da9", size = 747413, upload-time = "2026-04-22T20:59:01.174Z" }, - { url = "https://files.pythonhosted.org/packages/d7/55/ae264339996953c4cdf9d89d916a0a8fa26a83cf917a742fff8b9d5f3fe8/pyinstaller-6.20.0-py3-none-win32.whl", hash = "sha256:9a7637e8e44b4387b13667fdcaac86ab6b29c446c16d34d8401539b81838759c", size = 1331584, upload-time = "2026-04-22T20:59:07.201Z" }, - { url = "https://files.pythonhosted.org/packages/76/8c/300f57578882cce259bfb5ae56fda3b69caa3fe9df40a176c719920ea6e2/pyinstaller-6.20.0-py3-none-win_amd64.whl", hash = "sha256:d588844e890ee80c4365867f98146636e1849bbca8e4284bbf0c809aff0f161a", size = 1391851, upload-time = "2026-04-22T20:59:14.024Z" }, - { url = "https://files.pythonhosted.org/packages/8a/ea/b2f8e1642aecda78c0b75c7321f708e49e10bb3c00dd4f148c40761a1527/pyinstaller-6.20.0-py3-none-win_arm64.whl", hash = "sha256:bd53282c0a73e5c95573e1ddc8e5d564d4932bec91efbaed4dc5fdff9c2ae7f2", size = 1332259, upload-time = "2026-04-22T20:59:20.509Z" }, -] - [[package]] name = "pyinstaller" version = "6.21.0" -source = { git = "https://github.com/pyinstaller/pyinstaller.git#f809c9d1a4d82ed949912ada2fb9d46a112ce3d1" } -resolution-markers = [ - "python_full_version >= '3.15' and platform_machine == 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.15' and platform_machine != 'aarch64' and sys_platform == 'linux'", - "python_full_version >= '3.15' and platform_machine == 'ARM64' and sys_platform == 'win32'", - "python_full_version >= '3.15' and platform_machine != 'ARM64' and sys_platform == 'win32'", -] +source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "altgraph", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "packaging", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "pefile", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, - { name = "pyinstaller-hooks-contrib", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, - { name = "pywin32-ctypes", marker = "python_full_version >= '3.15' and sys_platform == 'win32'" }, - { name = "setuptools", marker = "(python_full_version >= '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and sys_platform == 'win32')" }, + { name = "altgraph", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "packaging", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pefile", marker = "sys_platform == 'win32'" }, + { name = "pyinstaller-hooks-contrib", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "setuptools", marker = "sys_platform == 'linux' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/4d/ec706c3fcf39e26888c35b39615ff4d5865d184069666c47492cff1fbe50/pyinstaller-6.21.0.tar.gz", hash = "sha256:bb9fab705983e393a2d1cac77d6972513057ad800215fd861dc15ff5272e98fd", size = 4061519, upload-time = "2026-06-13T14:15:06.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/83/b591295c352ef464c50b4c6ffff1c4f771d875c9e833f578d1b9f564f6b3/pyinstaller-6.21.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7071d4b094d5b40deeef5fa3d3b98a1b846087f7562b49209663d5f9281fe251", size = 748477, upload-time = "2026-06-13T14:14:00.327Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8f/88fff4e403873b1e22286911350e75ff00db014aa08e57045da9d4328993/pyinstaller-6.21.0-py3-none-manylinux2014_i686.whl", hash = "sha256:6b6374d652107dd4a2eeece903ff82bb4045bb5e1006c5a158a6dcdbefe84bf2", size = 760877, upload-time = "2026-06-13T14:14:04.836Z" }, + { url = "https://files.pythonhosted.org/packages/8a/13/f0e48fbdfd1d05d948157121cea8b1b823dcb89efe6934b71fdd8bdb3f0f/pyinstaller-6.21.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:4e3108b3f02384560da70e39b8bf22b0ad597d02bd68a40d76ea91c1cfa00cad", size = 759194, upload-time = "2026-06-13T14:14:10.61Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d5/ea7878cf9924ed30d946d8288777424e6d069d94f5bde56b4d0890069664/pyinstaller-6.21.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:697532279f535ad572bda613db4f821540e235c7854ca6da4d3bf0373f4415ee", size = 754979, upload-time = "2026-06-13T14:14:15.226Z" }, + { url = "https://files.pythonhosted.org/packages/9f/09/51b8905714b733bac66dbc041a7821372d70d888d273ae474c4037d4202d/pyinstaller-6.21.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:605169523a6b5ace39f13dfbff21add9f2bc43df99c7daf9394fefb2c45e8b6f", size = 754812, upload-time = "2026-06-13T14:14:20.264Z" }, + { url = "https://files.pythonhosted.org/packages/4b/43/d77779439d8c6c2e27a77bcfbd1d5cc0f568ebb611bb472b11af81b5f177/pyinstaller-6.21.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:5fa56746c1e76f93634d018502301378a2d0c382553d37d8c3c34ff436c12dd1", size = 753887, upload-time = "2026-06-13T14:14:25.268Z" }, + { url = "https://files.pythonhosted.org/packages/51/8f/c22df1f6837784ac349057ba693f08e7b1ca7a0e06f9c33c63bc6280007b/pyinstaller-6.21.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:42395ec76df8e8120c36b13339d9db8cab83e316a12839ee303cc00fc941bb74", size = 753779, upload-time = "2026-06-13T14:14:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/c9/76/1ce8a27ce62ba8cf3a87c9ce6d575610f4e55d7cb0123e7512fc3f4b921a/pyinstaller-6.21.0-py3-none-win32.whl", hash = "sha256:c6b28d30d8fd99ce162ff3aab5013ed44dbfb747566b1f01b9bed7964d7c14e9", size = 1336462, upload-time = "2026-06-13T14:14:35.785Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fa/ca1d7e5257dd8566a9dfc0dfb02f8a8075eeb53d4b2d3c579f1276759042/pyinstaller-6.21.0-py3-none-win_amd64.whl", hash = "sha256:7fae06c494ce0ebfe6bd3055c0e409def884f63af2e3705d06bd431ad9237fc7", size = 1397487, upload-time = "2026-06-13T14:14:42.328Z" }, + { url = "https://files.pythonhosted.org/packages/dc/75/21b51523ce8d96629b71311775a0a65f5f5a872124ab0de33e5c848f8bff/pyinstaller-6.21.0-py3-none-win_arm64.whl", hash = "sha256:f13c95c9c03fb567217135919f93815c305813126780b0ed6e0123cb8acaf025", size = 1346094, upload-time = "2026-06-13T14:14:48.914Z" }, ] [[package]] From b4107188864e9d47dda1dc1a7216b22480fdee4c Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 22 Jun 2026 15:09:57 -0400 Subject: [PATCH 49/50] Apply suggestion from @Avasam --- .github/workflows/lint-and-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-and-build.yml b/.github/workflows/lint-and-build.yml index 6b2d7aaa..f36ba192 100644 --- a/.github/workflows/lint-and-build.yml +++ b/.github/workflows/lint-and-build.yml @@ -92,7 +92,7 @@ jobs: fail-fast: false # Only the Python version we plan on shipping matters. matrix: - os: [windows-latest, windows-11-arm, ubuntu-22.04, ubuntu-24.04-arm] + os: [windows-latest, windows-11-arm, ubuntu-24.04, ubuntu-24.04-arm] python-version: ["3.14", "3.15"] wine-compat: [""] include: From 77d9526b7187c50c7a97f6e7b76d073f292b438c Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 23 Jun 2026 20:08:06 -0400 Subject: [PATCH 50/50] tcl/tk issue fixed in 3.5 beta 3 --- pyproject.toml | 5 +---- scripts/build.ps1 | 6 ++---- scripts/check_splash_support.py | 3 --- uv.lock | 10 ++++------ 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fe861f9e..59d9707e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ dev = [ # Types "types-PyAutoGUI", "types-keyboard", - "types-pyinstaller", + "types-pyinstaller >=6.21.0.20260616", "types-python-xlib; sys_platform == 'linux'", "types-pywin32 >=306.0.0.20240130; sys_platform == 'win32'", ] @@ -84,9 +84,6 @@ find-links = ["./scripts"] # Discover local wheels exclude-newer = "1 week" [tool.uv.exclude-newer-package] typed-D3DShot = false # I own it -# pyinstaller-hooks-contrib = false # pyinstaller develop build -pyinstaller = "2 days" # TODO: REMOVE BEFORE MERGING -pyinstaller-hooks-contrib = "6 days" # TODO: REMOVE BEFORE MERGING ### # Development channels diff --git a/scripts/build.ps1 b/scripts/build.ps1 index e4400473..da71fbdb 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -10,11 +10,9 @@ Push-Location "$PSScriptRoot/.." # Avoid issues with space in path try { & 'scripts/compile_resources.ps1' - # TODO: Remove UV_PYTHON check once tcl/tk is fixed on Python 3.15 # CI not allowed to skip splash screen, it MUST build (will fail when calling PyInstaller) - $SupportsSplashScreen = ($Env:UV_PYTHON -notlike '3.15*') -and ( - $Env:GITHUB_JOB -or [System.Convert]::ToBoolean( - $(uv run --active scripts/check_splash_support.py))) + $SupportsSplashScreen = $Env:GITHUB_JOB -or [System.Convert]::ToBoolean( + $(uv run --active scripts/check_splash_support.py)) $arguments = @( 'src/AutoSplit.py', diff --git a/scripts/check_splash_support.py b/scripts/check_splash_support.py index fc7f40c1..bf027920 100644 --- a/scripts/check_splash_support.py +++ b/scripts/check_splash_support.py @@ -4,9 +4,6 @@ Prints "True" or "False" to stdout for consumption by build.ps1. """ -# Not found in typeshed because private -# pyright: reportMissingImports=false, reportUnknownVariableType=false, reportUnknownMemberType=false, reportAttributeAccessIssue=false - import sys from PyInstaller.building.splash import Splash diff --git a/uv.lock b/uv.lock index 643e7d26..d2c12a66 100644 --- a/uv.lock +++ b/uv.lock @@ -22,8 +22,6 @@ exclude-newer-span = "P1W" [options.exclude-newer-package] typed-d3dshot = false -pyinstaller-hooks-contrib = { timestamp = "0001-01-01T00:00:00Z", span = "P6D" } -pyinstaller = { timestamp = "0001-01-01T00:00:00Z", span = "P2D" } [manifest] @@ -164,7 +162,7 @@ dev = [ { name = "ruff" }, { name = "types-keyboard" }, { name = "types-pyautogui" }, - { name = "types-pyinstaller" }, + { name = "types-pyinstaller", specifier = ">=6.21.0.20260616" }, { name = "types-python-xlib", marker = "sys_platform == 'linux'" }, { name = "types-pywin32", marker = "sys_platform == 'win32'", specifier = ">=306.0.0.20240130" }, ] @@ -753,11 +751,11 @@ wheels = [ [[package]] name = "types-pyinstaller" -version = "6.19.0.20260215" +version = "6.21.0.20260616" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/ac/552ef1a39253189266638f439655b7e73658413ad290e4126cf1985e2ccb/types_pyinstaller-6.19.0.20260215.tar.gz", hash = "sha256:dead1011722ad06d6c8482be271dc8c7e2f995ec76c7b8fc54b24f996ae8c608", size = 19945, upload-time = "2026-02-15T04:10:38.201Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7a/7f/34eb7a7e347a41a1f8211b4f5387f7d7c5e9a6cb575be59ec91da8e48400/types_pyinstaller-6.21.0.20260616.tar.gz", hash = "sha256:57d8d3510c72010e2bc1af4ced43a35fdae3f8d229995d0c0a73d3bdc46d2323", size = 20547, upload-time = "2026-06-16T07:11:56.966Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/fc/9d86a9c0aba04c60b5786a7929bdba4f5b97401ea1bc2ed8d7a485e026a4/types_pyinstaller-6.19.0.20260215-py3-none-any.whl", hash = "sha256:5e3af03dad356be22eb2524c1955149ebd4723ad1af529ac4fecf9d8fbc17ec1", size = 22064, upload-time = "2026-02-15T04:10:36.921Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0a/aea1b388201325dbe7959de9d48a95086d2b50c7ba3888437f2cc22a8eb9/types_pyinstaller-6.21.0.20260616-py3-none-any.whl", hash = "sha256:75c57b230112071c2dd2049bc7d7aeab5e3765ebf94620f0b723a1263f450e66", size = 22651, upload-time = "2026-06-16T07:11:56.047Z" }, ] [[package]]