pyallel 2.0.4__tar.gz → 2.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyallel-2.0.5/.base_branch +1 -0
- pyallel-2.0.5/.github/workflows/build.yml +43 -0
- pyallel-2.0.5/.github/workflows/test.yml +49 -0
- pyallel-2.0.5/.gitignore +160 -0
- pyallel-2.0.5/.vim/project.shada +0 -0
- pyallel-2.0.5/Dockerfile +25 -0
- pyallel-2.0.5/Dockerfile.alpine +46 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/PKG-INFO +11 -20
- {pyallel-2.0.4 → pyallel-2.0.5}/README.md +4 -4
- pyallel-2.0.5/benchmark_process.py +68 -0
- pyallel-2.0.5/bin/ldd +13 -0
- pyallel-2.0.5/bin/pyinstaller.sh +9 -0
- pyallel-2.0.5/build.sh +36 -0
- pyallel-2.0.5/build_all.sh +27 -0
- pyallel-2.0.5/pyproject.toml +48 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/process.py +39 -14
- pyallel-2.0.5/tests/assets/test_handle_multiple_signals.sh +7 -0
- pyallel-2.0.5/tests/assets/test_output.sh +21 -0
- pyallel-2.0.5/tests/test_main.py +505 -0
- pyallel-2.0.5/tests/test_printer.py +302 -0
- pyallel-2.0.5/tests/test_process.py +101 -0
- pyallel-2.0.5/tests/test_process_group.py +120 -0
- pyallel-2.0.5/tests/test_process_manager.py +197 -0
- pyallel-2.0.5/uv.lock +364 -0
- pyallel-2.0.4/pyproject.toml +0 -38
- {pyallel-2.0.4 → pyallel-2.0.5}/LICENSE +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/__init__.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/colours.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/constants.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/errors.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/main.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/parser.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/printer.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/process_group.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/process_group_manager.py +0 -0
- {pyallel-2.0.4 → pyallel-2.0.5}/src/pyallel/py.typed +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
main
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
- workflow_dispatch
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
build:
|
|
8
|
+
runs-on: ${{ matrix.os }}
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
os:
|
|
13
|
+
- ubuntu-latest
|
|
14
|
+
- macos-latest
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout
|
|
18
|
+
uses: actions/checkout@v3
|
|
19
|
+
|
|
20
|
+
- name: 📦 Install uv
|
|
21
|
+
run: |
|
|
22
|
+
pipx install uv
|
|
23
|
+
|
|
24
|
+
- name: Setup Python
|
|
25
|
+
uses: actions/setup-python@v4
|
|
26
|
+
with:
|
|
27
|
+
python-version: 3.12
|
|
28
|
+
cache: 'pip'
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: uv sync
|
|
32
|
+
|
|
33
|
+
- name: Run pyinstaller
|
|
34
|
+
run: |
|
|
35
|
+
source .venv/bin/activate && \
|
|
36
|
+
./build.sh
|
|
37
|
+
|
|
38
|
+
- name: Upload artifacts
|
|
39
|
+
uses: actions/upload-artifact@v4
|
|
40
|
+
if: ${{ always() }}
|
|
41
|
+
with:
|
|
42
|
+
name: ${{ runner.os }} Build
|
|
43
|
+
path: dist/*
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
- pull_request
|
|
5
|
+
- workflow_dispatch
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
tests:
|
|
9
|
+
name: ${{ matrix.os.name }} ${{ matrix.python }}
|
|
10
|
+
runs-on: ${{ matrix.os.runs-on }}
|
|
11
|
+
strategy:
|
|
12
|
+
fail-fast: false
|
|
13
|
+
matrix:
|
|
14
|
+
python:
|
|
15
|
+
- "3.8"
|
|
16
|
+
- "3.9"
|
|
17
|
+
- "3.10"
|
|
18
|
+
- "3.11"
|
|
19
|
+
- "3.12"
|
|
20
|
+
- "3.13"
|
|
21
|
+
os:
|
|
22
|
+
- name: Linux
|
|
23
|
+
matrix: linux
|
|
24
|
+
runs-on: [ubuntu-latest]
|
|
25
|
+
- name: macOS
|
|
26
|
+
matrix: macos
|
|
27
|
+
runs-on: [macos-latest]
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: 📦 Install uv
|
|
34
|
+
run: |
|
|
35
|
+
pipx install uv
|
|
36
|
+
|
|
37
|
+
- name: Set up Python ${{ matrix.python }}
|
|
38
|
+
uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: ${{ matrix.python }}
|
|
41
|
+
cache: 'pip'
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: uv sync
|
|
45
|
+
|
|
46
|
+
- name: Run pyallel
|
|
47
|
+
run: |
|
|
48
|
+
source .venv/bin/activate && \
|
|
49
|
+
pyallel --colour yes -- MYPY_FORCE_COLOR=1 mypy . :: pytest --color=yes -s .
|
pyallel-2.0.5/.gitignore
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
158
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
159
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
160
|
+
#.idea/
|
|
Binary file
|
pyallel-2.0.5/Dockerfile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
ARG arch
|
|
2
|
+
FROM --platform=linux/${arch} python:3.13-bullseye
|
|
3
|
+
|
|
4
|
+
ARG uid=
|
|
5
|
+
ARG gid=
|
|
6
|
+
|
|
7
|
+
VOLUME /src
|
|
8
|
+
WORKDIR /src
|
|
9
|
+
|
|
10
|
+
# Setup a build user
|
|
11
|
+
RUN addgroup --system build --gid 1000 && adduser --system build --uid ${uid} --gid 1000
|
|
12
|
+
|
|
13
|
+
COPY src src
|
|
14
|
+
COPY pyproject.toml pyproject.toml
|
|
15
|
+
COPY README.md README.md
|
|
16
|
+
|
|
17
|
+
# Also install pyallel so we can copy it's metadata when running pyinstaller
|
|
18
|
+
RUN pip install . --group dev
|
|
19
|
+
|
|
20
|
+
# Switch to the build user before running the build scripts
|
|
21
|
+
USER build
|
|
22
|
+
|
|
23
|
+
ENV arch ${arch}
|
|
24
|
+
CMD [ "./build.sh", "linux" ]
|
|
25
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
ARG arch
|
|
2
|
+
FROM --platform=linux/${arch} python:3.13-alpine
|
|
3
|
+
|
|
4
|
+
ARG uid=
|
|
5
|
+
ARG gid=
|
|
6
|
+
|
|
7
|
+
# Official Python base image is needed or some applications will segfault.
|
|
8
|
+
# PyInstaller needs zlib-dev, gcc, libc-dev, and musl-dev
|
|
9
|
+
RUN apk --update --no-cache add \
|
|
10
|
+
zlib-dev \
|
|
11
|
+
musl-dev \
|
|
12
|
+
libc-dev \
|
|
13
|
+
libffi-dev \
|
|
14
|
+
gcc \
|
|
15
|
+
g++ \
|
|
16
|
+
git \
|
|
17
|
+
&& pip install --upgrade pip
|
|
18
|
+
|
|
19
|
+
# Build bootloader for alpine
|
|
20
|
+
RUN git clone --depth 1 --single-branch --branch v6.11.0 https://github.com/pyinstaller/pyinstaller.git /tmp/pyinstaller \
|
|
21
|
+
&& cd /tmp/pyinstaller/bootloader \
|
|
22
|
+
&& CFLAGS="-Wno-stringop-overflow -Wno-stringop-truncation" python ./waf configure all \
|
|
23
|
+
&& pip install .. \
|
|
24
|
+
&& rm -Rf /tmp/pyinstaller
|
|
25
|
+
|
|
26
|
+
VOLUME /src
|
|
27
|
+
WORKDIR /src
|
|
28
|
+
|
|
29
|
+
# Setup a build user
|
|
30
|
+
RUN addgroup -g 1000 build && adduser -S -u ${uid} build -G build
|
|
31
|
+
|
|
32
|
+
COPY src .
|
|
33
|
+
COPY pyproject.toml .
|
|
34
|
+
COPY README.md .
|
|
35
|
+
|
|
36
|
+
RUN pip install . --group dev
|
|
37
|
+
|
|
38
|
+
ADD ./bin /pyinstaller
|
|
39
|
+
RUN chmod a+x /pyinstaller/*
|
|
40
|
+
|
|
41
|
+
# Switch to the build user before running the build scripts
|
|
42
|
+
USER build
|
|
43
|
+
|
|
44
|
+
# ENV arch ${arch}
|
|
45
|
+
CMD [ "/pyinstaller/pyinstaller.sh" ]
|
|
46
|
+
|
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyallel
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.5
|
|
4
4
|
Summary: Run and handle the output of multiple executables in pyallel (as in parallel)
|
|
5
|
-
|
|
5
|
+
Project-URL: Homepage, https://github.com/Danthewaann/pyallel
|
|
6
|
+
Project-URL: Repository, https://github.com/Danthewaann/pyallel
|
|
7
|
+
Author-email: Daniel Black <danielcrblack@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
6
9
|
License-File: LICENSE
|
|
7
|
-
Keywords: parallel,
|
|
8
|
-
Author: Daniel Black
|
|
9
|
-
Author-email: danielcrblack@gmail.com
|
|
10
|
-
Requires-Python: >=3.8
|
|
10
|
+
Keywords: command,executable,parallel,runner,shell,terminal
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
13
|
Classifier: Operating System :: MacOS :: MacOS X
|
|
14
14
|
Classifier: Operating System :: POSIX :: Linux
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
-
Project-URL: Homepage, https://github.com/Danthewaann/pyallel
|
|
24
|
-
Project-URL: Repository, https://github.com/Danthewaann/pyallel
|
|
16
|
+
Requires-Python: >=3.8
|
|
25
17
|
Description-Content-Type: text/markdown
|
|
26
18
|
|
|
27
19
|
# Pyallel
|
|
@@ -36,10 +28,10 @@ Tested on Linux and MacOS only
|
|
|
36
28
|
|
|
37
29
|
Pre-built executables are available on the [Releases](https://github.com/Danthewaann/pyallel/releases) page.
|
|
38
30
|
|
|
39
|
-
`pyallel` can also be installed using
|
|
31
|
+
`pyallel` can also be installed using pipx (requires Python >=3.8):
|
|
40
32
|
|
|
41
33
|
```bash
|
|
42
|
-
|
|
34
|
+
pipx install pyallel
|
|
43
35
|
```
|
|
44
36
|
|
|
45
37
|
# Quick start
|
|
@@ -148,9 +140,9 @@ docker build --tag pyallel-alpine --build-arg 'arch=x86_64' --build-arg "uid=$(i
|
|
|
148
140
|
#### Build locally
|
|
149
141
|
|
|
150
142
|
```bash
|
|
151
|
-
|
|
143
|
+
pipx install uv && \
|
|
144
|
+
uv sync && \
|
|
152
145
|
source .venv/bin/activate && \
|
|
153
|
-
pip install . -r requirements_build.txt && \
|
|
154
146
|
./build.sh
|
|
155
147
|
```
|
|
156
148
|
|
|
@@ -174,4 +166,3 @@ python -m venv .venv && \
|
|
|
174
166
|
- [ ] Allow list of files to be provided to supply as input arguments to each command
|
|
175
167
|
- [ ] Allow input to be piped into `pyallel` via stdin to supply as standard input to each
|
|
176
168
|
command
|
|
177
|
-
|
|
@@ -10,10 +10,10 @@ Tested on Linux and MacOS only
|
|
|
10
10
|
|
|
11
11
|
Pre-built executables are available on the [Releases](https://github.com/Danthewaann/pyallel/releases) page.
|
|
12
12
|
|
|
13
|
-
`pyallel` can also be installed using
|
|
13
|
+
`pyallel` can also be installed using pipx (requires Python >=3.8):
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
pipx install pyallel
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
# Quick start
|
|
@@ -122,9 +122,9 @@ docker build --tag pyallel-alpine --build-arg 'arch=x86_64' --build-arg "uid=$(i
|
|
|
122
122
|
#### Build locally
|
|
123
123
|
|
|
124
124
|
```bash
|
|
125
|
-
|
|
125
|
+
pipx install uv && \
|
|
126
|
+
uv sync && \
|
|
126
127
|
source .venv/bin/activate && \
|
|
127
|
-
pip install . -r requirements_build.txt && \
|
|
128
128
|
./build.sh
|
|
129
129
|
```
|
|
130
130
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ad-hoc benchmark comparing Process's stdout reading approach against two
|
|
3
|
+
scenarios:
|
|
4
|
+
|
|
5
|
+
1. A chatty command that produces a lot of output while it's running.
|
|
6
|
+
2. A quick command that exits almost immediately, followed by a period of
|
|
7
|
+
idle polling (simulating other still-running commands in the same group).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import resource
|
|
13
|
+
import sys
|
|
14
|
+
import time
|
|
15
|
+
|
|
16
|
+
sys.path.insert(0, "src")
|
|
17
|
+
|
|
18
|
+
from pyallel.process import Process
|
|
19
|
+
|
|
20
|
+
CHATTY_CMD = "python3 -c \"[print('line', i) for i in range(200000)]\""
|
|
21
|
+
QUICK_CMD = "echo hi"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def cpu_time() -> float:
|
|
25
|
+
usage = resource.getrusage(resource.RUSAGE_SELF)
|
|
26
|
+
return usage.ru_utime + usage.ru_stime
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def run_scenario(
|
|
30
|
+
name: str, command: str, poll_seconds: float, extra_idle_seconds: float
|
|
31
|
+
) -> None:
|
|
32
|
+
process = Process(1, command)
|
|
33
|
+
|
|
34
|
+
start_wall = time.perf_counter()
|
|
35
|
+
start_cpu = cpu_time()
|
|
36
|
+
|
|
37
|
+
process.run()
|
|
38
|
+
|
|
39
|
+
total_bytes = 0
|
|
40
|
+
while process.poll() is None:
|
|
41
|
+
time.sleep(poll_seconds)
|
|
42
|
+
total_bytes += len(process.read())
|
|
43
|
+
|
|
44
|
+
idle_deadline = time.perf_counter() + extra_idle_seconds
|
|
45
|
+
while time.perf_counter() < idle_deadline:
|
|
46
|
+
time.sleep(poll_seconds)
|
|
47
|
+
total_bytes += len(process.read())
|
|
48
|
+
|
|
49
|
+
end_wall = time.perf_counter()
|
|
50
|
+
end_cpu = cpu_time()
|
|
51
|
+
|
|
52
|
+
print(
|
|
53
|
+
f"{name:12} wall={end_wall - start_wall:6.3f}s "
|
|
54
|
+
f"cpu={end_cpu - start_cpu:6.3f}s bytes={total_bytes}"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> None:
|
|
59
|
+
print("--- scenario: chatty command, output while it's still running ---")
|
|
60
|
+
run_scenario("chatty", CHATTY_CMD, poll_seconds=0.1, extra_idle_seconds=0.0)
|
|
61
|
+
|
|
62
|
+
print()
|
|
63
|
+
print("--- scenario: quick command, then 2s of idle polling ---")
|
|
64
|
+
run_scenario("quick+idle", QUICK_CMD, poll_seconds=0.1, extra_idle_seconds=2.0)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
main()
|
pyallel-2.0.5/bin/ldd
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# From http://wiki.musl-libc.org/wiki/FAQ#Q:_where_is_ldd_.3F
|
|
4
|
+
#
|
|
5
|
+
# Musl's dynlinker comes with ldd functionality built in. just create a
|
|
6
|
+
# symlink from ld-musl-$ARCH.so to /bin/ldd. If the dynlinker was started
|
|
7
|
+
# as "ldd", it will detect that and print the appropriate DSO information.
|
|
8
|
+
#
|
|
9
|
+
# Instead, this string replaced "ldd" with the package so that pyinstaller
|
|
10
|
+
# can find the actual lib.
|
|
11
|
+
exec /usr/bin/ldd "$@" | \
|
|
12
|
+
sed -r 's/([^[:space:]]+) => ldd/\1 => \/lib\/\1/g' | \
|
|
13
|
+
sed -r 's/ldd \(.*\)//g'
|
pyallel-2.0.5/build.sh
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
distro="${1:-$distro}"
|
|
6
|
+
arch="${2:-$arch}"
|
|
7
|
+
|
|
8
|
+
if [ -z "$distro" ]; then
|
|
9
|
+
distro=linux
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
if [ -z "$arch" ]; then
|
|
13
|
+
arch=unknown
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
name=pyallel-"$(pyallel -V)"-"$distro"-"$arch"
|
|
17
|
+
|
|
18
|
+
# --bootloader-ignore-signals is needed as two interrupt signals where getting sent
|
|
19
|
+
# to pyallel as it is apart of the same process group as the bootloader
|
|
20
|
+
# From: https://pyinstaller.org/en/stable/usage.html#cmdoption-bootloader-ignore-signals
|
|
21
|
+
pyinstaller \
|
|
22
|
+
--onefile \
|
|
23
|
+
--noconfirm \
|
|
24
|
+
--clean \
|
|
25
|
+
--log-level DEBUG \
|
|
26
|
+
--exclude-module PyInstaller \
|
|
27
|
+
--copy-metadata pyallel \
|
|
28
|
+
--bootloader-ignore-signals \
|
|
29
|
+
--specpath ./specs \
|
|
30
|
+
--name "$name" \
|
|
31
|
+
./src/pyallel/main.py
|
|
32
|
+
|
|
33
|
+
printf "\nExecutable written to './dist/%s'\n" "$name"
|
|
34
|
+
|
|
35
|
+
cd dist
|
|
36
|
+
md5sum "$name" > "$name".md5
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
rm -rf build dist specs
|
|
4
|
+
|
|
5
|
+
user_id=$(id -u)
|
|
6
|
+
group_id=$(id -g)
|
|
7
|
+
cur_dir=$(pwd)
|
|
8
|
+
|
|
9
|
+
# Local OS setup
|
|
10
|
+
distro=$(uname | tr '[:upper:]' '[:lower:]')
|
|
11
|
+
arch=$(uname -m)
|
|
12
|
+
|
|
13
|
+
if [ "$arch" = "arm64" ]; then
|
|
14
|
+
arch="aarch64"
|
|
15
|
+
elif [ "$arch" = "x86_64" ]; then
|
|
16
|
+
arch="x86_64"
|
|
17
|
+
else
|
|
18
|
+
arch=unknown
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
uv sync
|
|
22
|
+
|
|
23
|
+
uv run pyallel "docker build --tag pyallel-x86_64 --build-arg 'arch=x86_64' --build-arg 'uid=$user_id' --build-arg 'gid=$group_id' . && docker run -e 'arch=x86_64' --rm --volume '$cur_dir:/src' pyallel-x86_64" :: \
|
|
24
|
+
"docker build --tag pyallel-aarch64 --build-arg 'arch=aarch64' --build-arg 'uid=$user_id' --build-arg 'gid=$group_id' . && docker run -e 'arch=aarch64' --rm --volume '$cur_dir:/src' pyallel-aarch64" :: \
|
|
25
|
+
"docker build --tag pyallel-x86_64-alpine --build-arg 'arch=x86_64' --build-arg 'uid=$user_id' --build-arg 'gid=$group_id' --file Dockerfile.alpine . && docker run -e 'arch=x86_64' --rm --volume '$cur_dir:/src' pyallel-x86_64-alpine" :: \
|
|
26
|
+
"docker build --tag pyallel-aarch64-alpine --build-arg 'arch=aarch64' --build-arg 'uid=$user_id' --build-arg 'gid=$group_id' --file Dockerfile.alpine . && docker run -e 'arch=aarch64' --rm --volume '$cur_dir:/src' pyallel-aarch64-alpine" :: \
|
|
27
|
+
"source .venv/bin/activate && ./build.sh $distro $arch"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pyallel"
|
|
3
|
+
version = "2.0.5"
|
|
4
|
+
description = "Run and handle the output of multiple executables in pyallel (as in parallel)"
|
|
5
|
+
authors = [{ name = "Daniel Black", email = "danielcrblack@gmail.com" }]
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
license = "MIT"
|
|
9
|
+
keywords = [
|
|
10
|
+
"parallel",
|
|
11
|
+
"command",
|
|
12
|
+
"runner",
|
|
13
|
+
"executable",
|
|
14
|
+
"shell",
|
|
15
|
+
"terminal",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 5 - Production/Stable",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: MacOS :: MacOS X",
|
|
22
|
+
"Operating System :: POSIX :: Linux",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/Danthewaann/pyallel"
|
|
27
|
+
Repository = "https://github.com/Danthewaann/pyallel"
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
pyallel = "pyallel.main:entry_point"
|
|
31
|
+
|
|
32
|
+
[dependency-groups]
|
|
33
|
+
dev = [
|
|
34
|
+
"pytest>=7.4.3,<8",
|
|
35
|
+
"mypy>=1.7.0,<2",
|
|
36
|
+
"pyinstaller==6.11.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = ["hatchling"]
|
|
41
|
+
build-backend = "hatchling.build"
|
|
42
|
+
|
|
43
|
+
[tool.mypy]
|
|
44
|
+
strict = true
|
|
45
|
+
show_error_codes = true
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
addopts = "-vvv"
|