Skip to content

Commit 816b9f2

Browse files
ahoarauBlankSpruce
authored andcommitted
Build single executable
According to PyInstaller documentation freeze_support needs to be called before multiprocessing can be used. Black does similar thing. https://pyinstaller.org/en/stable/common-issues-and-pitfalls.html#multi-processing Additionally fix setup.py about extras_require
1 parent 2b5f154 commit 816b9f2

File tree

8 files changed

+53
-10
lines changed

8 files changed

+53
-10
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
python-version: ['3.8', '3.9', '3.10', '3.11', '3.13']
13+
executable-name: [gersemi]
1314
os: [ubuntu-latest]
1415
include:
1516
- python-version: '3.12'
1617
os: windows-latest
18+
executable-name: gersemi.exe
1719
- python-version: '3.12'
1820
os: macos-latest
1921
- python-version: '3.12'
@@ -35,7 +37,7 @@ jobs:
3537
run: python -m pip install --upgrade setuptools pip wheel tox
3638

3739
- name: Run tests
38-
run: tox -e tests
40+
run: tox -e tests && tox -e build-executable -- ${{ matrix.executable-name }}
3941

4042
- name: Run quality tests
4143
run: tox -e lint && tox -e format && tox -e mypy

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
.mypy_cache
33
.tox
44
*.egg-info
5+
*.spec
56
__pycache__
6-
prof/
7+
build/
8+
dist/
9+
prof/

.pylintrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ disable=
1212

1313
fixme,
1414

15+
import-outside-toplevel,
16+
1517
invalid-name,
1618

1719
missing-class-docstring,

gersemi/__main__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
from gersemi.runner import run, print_to_stderr
2222
from gersemi.__version__ import __title__, __version__
2323

24+
FROZEN = getattr(sys, "frozen", False)
2425
MISSING = "(missing)"
2526

26-
2727
try:
2828
from colorama import __version__ as colorama_version
2929

@@ -33,7 +33,8 @@
3333

3434
class ShowVersion(argparse.Action):
3535
def __call__(self, parser, namespace, values, option_string=None):
36-
print(f"{__title__} {__version__}")
36+
frozen_suffix = " (frozen)" if FROZEN else ""
37+
print(f"{__title__} {__version__}{frozen_suffix}")
3738
print(f"lark {lark_version}")
3839
print(f"colorama {colorama_version}")
3940
print(f"Python {sys.version}")
@@ -335,6 +336,11 @@ def error(text):
335336

336337

337338
def main():
339+
if FROZEN:
340+
from multiprocessing import freeze_support
341+
342+
freeze_support()
343+
338344
try:
339345
argparser = create_argparser()
340346
args = argparser.parse_args()

gersemi/configuration.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from contextlib import contextmanager
22
from dataclasses import astuple, dataclass, field, fields
33
from functools import lru_cache
4-
import multiprocessing
54
import os
65
from pathlib import Path
76
import sys
@@ -15,6 +14,8 @@
1514

1615

1716
def max_number_of_workers():
17+
import multiprocessing
18+
1819
result = multiprocessing.cpu_count()
1920
if sys.platform == "win32":
2021
# https://bugs.python.org/issue26903

gersemi/runner.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from functools import partial
55
from hashlib import sha1
66
from itertools import chain
7-
import multiprocessing as mp
87
from pathlib import Path
98
import sys
109
from typing import Callable, Dict, List, Iterable, Optional, Tuple, Union
@@ -230,7 +229,9 @@ def imap_unordered(self, func, iterable):
230229
yield from map(func, iterable)
231230
return
232231

233-
with mp.Pool(processes=processes) as pool:
232+
import multiprocessing
233+
234+
with multiprocessing.Pool(processes=processes) as pool:
234235
yield from pool.imap_unordered(func, iterable, CHUNKSIZE)
235236

236237

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
"lark>=1.0",
2828
"pyyaml>=5,<7",
2929
],
30-
extras_requires=["colorama>=0.4"],
30+
extras_require={
31+
"color": ["colorama>=0.4"],
32+
},
3133
python_requires=">=3.8",
3234
entry_points={"console_scripts": ["gersemi = gersemi.__main__:main"]},
3335
license=about["__license__"],

tox.ini

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py38, py39, py310, py311, py312, py313, lint, format, mypy
2+
envlist = py38, py39, py310, py311, py312, py313, lint, format, mypy, build-executable
33
skip_missing_interpreters=true
44

55
[testenv]
@@ -65,4 +65,30 @@ deps =
6565
pytest
6666
pytest-profiling
6767
commands =
68-
pytest --profile-svg {posargs}
68+
pytest --profile-svg {posargs}
69+
70+
[testenv:build-executable]
71+
allowlist_externals =
72+
./dist/*
73+
deps =
74+
pyinstaller
75+
colorama
76+
setenv =
77+
FORCE_COLOR = 1
78+
commands =
79+
# Build executable
80+
pyinstaller \
81+
--onefile \
82+
--name "{posargs:gersemi}" \
83+
--hidden-import colorama \
84+
--add-data "gersemi/cmake.lark{:}gersemi" \
85+
"gersemi/__main__.py"
86+
87+
# and test it
88+
./dist/{posargs:gersemi} --version
89+
./dist/{posargs:gersemi} \
90+
--config "{tox_root}/.gersemirc.example" \
91+
--no-cache \
92+
--check \
93+
--diff --color \
94+
"{tox_root}/tests/executable/directory_with_formatted_files"

0 commit comments

Comments
 (0)