zprocess 2.20.4__tar.gz → 2.21.1__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.
- zprocess-2.20.4/.github/workflows/build-and-release.yaml → zprocess-2.21.1/.github/workflows/release.yml +48 -65
- {zprocess-2.20.4/zprocess.egg-info → zprocess-2.21.1}/PKG-INFO +1 -4
- {zprocess-2.20.4 → zprocess-2.21.1}/setup.py +1 -1
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/process_tree.py +11 -4
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/remote/server.py +6 -4
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/security.py +25 -8
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/utils.py +32 -2
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/zlock/__init__.py +2 -2
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/zlog/__init__.py +9 -3
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/zlog/server.py +1 -0
- {zprocess-2.20.4 → zprocess-2.21.1/zprocess.egg-info}/PKG-INFO +1 -4
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess.egg-info/SOURCES.txt +1 -1
- {zprocess-2.20.4 → zprocess-2.21.1}/.coveragerc +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/.gitignore +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/.travis.yml +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/LICENSE.txt +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/README.md +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/doc/Makefile +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/doc/conf.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/doc/index.rst +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/doc/requirements.txt +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/pyproject.toml +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/requirements.txt +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/run_tests.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/setup.cfg +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/tests/GUI_output_redirection.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/tests/output_redirection.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/tests/test_remote.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/tests/test_zlock_server.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/tests/test_zlog_server.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/tests/tests.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/__init__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/__version__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/clientserver.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/cryptoproxy.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/examples/example_child.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/examples/example_parent.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/examples/processclass_example.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/examples/processclass_remote_example.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/locking/__init__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/locking/__main__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/makesecret.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/process_class_wrapper.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/remote/__init__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/remote/__main__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/remote/curses_server.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/socks/__init__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/socks/server.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/tasks.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/zlock/__main__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/zlock/server.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess/zlog/__main__.py +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess.egg-info/dependency_links.txt +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess.egg-info/not-zip-safe +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess.egg-info/requires.txt +0 -0
- {zprocess-2.20.4 → zprocess-2.21.1}/zprocess.egg-info/top_level.txt +0 -0
|
@@ -9,10 +9,6 @@ on:
|
|
|
9
9
|
tags:
|
|
10
10
|
- 'v[0-9]+.[0-9]+.[0-9]+*'
|
|
11
11
|
|
|
12
|
-
defaults:
|
|
13
|
-
run:
|
|
14
|
-
shell: bash -l {0}
|
|
15
|
-
|
|
16
12
|
env:
|
|
17
13
|
PACKAGE_NAME: zprocess
|
|
18
14
|
SCM_LOCAL_SCHEME: no-local-version
|
|
@@ -41,30 +37,30 @@ jobs:
|
|
|
41
37
|
strategy:
|
|
42
38
|
matrix:
|
|
43
39
|
include:
|
|
44
|
-
- { os: ubuntu-latest, python: 3.
|
|
45
|
-
- { os: ubuntu-latest, python: 3.
|
|
46
|
-
- { os: ubuntu-latest, python: 3.
|
|
47
|
-
- { os: ubuntu-latest, python: 3.
|
|
48
|
-
|
|
49
|
-
- { os: macos-
|
|
50
|
-
- { os: macos-
|
|
51
|
-
- { os: macos-
|
|
52
|
-
- { os: macos-
|
|
53
|
-
|
|
54
|
-
- { os: windows-latest, python: 3.
|
|
55
|
-
- { os: windows-latest, python: 3.
|
|
56
|
-
- { os: windows-latest, python: 3.
|
|
57
|
-
- { os: windows-latest, python: 3.
|
|
58
|
-
|
|
59
|
-
- { os: windows-latest, python: 3.
|
|
60
|
-
- { os: windows-latest, python: 3.
|
|
61
|
-
- { os: windows-latest, python: 3.
|
|
62
|
-
- { os: windows-latest, python: 3.
|
|
40
|
+
- { os: ubuntu-latest, python: '3.10', arch: x64 }
|
|
41
|
+
- { os: ubuntu-latest, python: '3.9', arch: x64 }
|
|
42
|
+
- { os: ubuntu-latest, python: '3.8', arch: x64 }
|
|
43
|
+
- { os: ubuntu-latest, python: '3.7', arch: x64 }
|
|
44
|
+
|
|
45
|
+
- { os: macos-10.15, python: '3.10', arch: x64 }
|
|
46
|
+
- { os: macos-10.15, python: '3.9', arch: x64 }
|
|
47
|
+
- { os: macos-10.15, python: '3.8', arch: x64 }
|
|
48
|
+
- { os: macos-10.15, python: '3.7', arch: x64 }
|
|
49
|
+
|
|
50
|
+
- { os: windows-latest, python: '3.10', arch: x64 }
|
|
51
|
+
- { os: windows-latest, python: '3.9', arch: x64 }
|
|
52
|
+
- { os: windows-latest, python: '3.8', arch: x64 }
|
|
53
|
+
- { os: windows-latest, python: '3.7', arch: x64 }
|
|
54
|
+
|
|
55
|
+
- { os: windows-latest, python: '3.10', arch: x86 }
|
|
56
|
+
- { os: windows-latest, python: '3.9', arch: x86 }
|
|
57
|
+
- { os: windows-latest, python: '3.8', arch: x86 }
|
|
58
|
+
- { os: windows-latest, python: '3.7', arch: x86 }
|
|
63
59
|
|
|
64
60
|
if: github.repository == 'chrisjbillington/zprocess' && (github.event_name != 'create' || github.event.ref_type != 'branch')
|
|
65
61
|
steps:
|
|
66
62
|
- name: Checkout
|
|
67
|
-
uses: actions/checkout@
|
|
63
|
+
uses: actions/checkout@v3
|
|
68
64
|
with:
|
|
69
65
|
fetch-depth: 0
|
|
70
66
|
|
|
@@ -73,7 +69,7 @@ jobs:
|
|
|
73
69
|
run: git tag -d $(git tag --points-at HEAD)
|
|
74
70
|
|
|
75
71
|
- name: Install Python
|
|
76
|
-
uses: actions/setup-python@
|
|
72
|
+
uses: actions/setup-python@v4
|
|
77
73
|
with:
|
|
78
74
|
python-version: ${{ matrix.python }}
|
|
79
75
|
architecture: ${{ matrix.arch }}
|
|
@@ -93,12 +89,13 @@ jobs:
|
|
|
93
89
|
|
|
94
90
|
- name: Upload Artifact
|
|
95
91
|
if: strategy.job-index == 0 || (env.PURE == 'false' && runner.os != 'Linux')
|
|
96
|
-
uses: actions/upload-artifact@
|
|
92
|
+
uses: actions/upload-artifact@v3
|
|
97
93
|
with:
|
|
98
94
|
name: dist
|
|
99
95
|
path: ./dist
|
|
100
96
|
|
|
101
97
|
- name: Set Variables for Conda Build
|
|
98
|
+
shell: bash
|
|
102
99
|
run: |
|
|
103
100
|
if [ $NOARCH == true ]; then
|
|
104
101
|
CONDA_BUILD_ARGS="--noarch"
|
|
@@ -108,10 +105,7 @@ jobs:
|
|
|
108
105
|
echo "CONDA_BUILD_ARGS=$CONDA_BUILD_ARGS" >> $GITHUB_ENV
|
|
109
106
|
|
|
110
107
|
- name: Install Miniconda
|
|
111
|
-
|
|
112
|
-
# to be able to install 32-bit miniconda on Windows. Once setup-miniconda 2.1.2
|
|
113
|
-
# is released with this fix, can change to @v2.
|
|
114
|
-
uses: conda-incubator/setup-miniconda@1a875d105ac03256664b54c882c8c374ce617ef6
|
|
108
|
+
uses: conda-incubator/setup-miniconda@v2
|
|
115
109
|
with:
|
|
116
110
|
auto-update-conda: true
|
|
117
111
|
python-version: ${{ matrix.python }}
|
|
@@ -123,9 +117,10 @@ jobs:
|
|
|
123
117
|
uses: maxim-lobanov/setup-xcode@v1
|
|
124
118
|
with:
|
|
125
119
|
xcode-version: 11.7
|
|
126
|
-
|
|
120
|
+
|
|
127
121
|
- name: Conda package (Unix)
|
|
128
122
|
if: runner.os != 'Windows'
|
|
123
|
+
shell: bash -l {0}
|
|
129
124
|
run: |
|
|
130
125
|
conda install -c labscript-suite setuptools-conda
|
|
131
126
|
setuptools-conda build $CONDA_BUILD_ARGS .
|
|
@@ -138,7 +133,7 @@ jobs:
|
|
|
138
133
|
setuptools-conda build %CONDA_BUILD_ARGS% --croot ${{ runner.temp }}\cb .
|
|
139
134
|
|
|
140
135
|
- name: Upload Artifact
|
|
141
|
-
uses: actions/upload-artifact@
|
|
136
|
+
uses: actions/upload-artifact@v3
|
|
142
137
|
with:
|
|
143
138
|
name: conda_packages
|
|
144
139
|
path: ./conda_packages
|
|
@@ -147,16 +142,11 @@ jobs:
|
|
|
147
142
|
manylinux:
|
|
148
143
|
name: Build Manylinux
|
|
149
144
|
runs-on: ubuntu-latest
|
|
150
|
-
strategy:
|
|
151
|
-
matrix:
|
|
152
|
-
include:
|
|
153
|
-
- { python: 'cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39' }
|
|
154
|
-
|
|
155
145
|
if: github.repository == 'chrisjbillington/zprocess' && (github.event_name != 'create' || github.event.ref_type != 'branch')
|
|
156
146
|
steps:
|
|
157
147
|
- name: Checkout
|
|
158
148
|
if: env.PURE == 'false'
|
|
159
|
-
uses: actions/checkout@
|
|
149
|
+
uses: actions/checkout@v3
|
|
160
150
|
with:
|
|
161
151
|
fetch-depth: 0
|
|
162
152
|
|
|
@@ -166,16 +156,17 @@ jobs:
|
|
|
166
156
|
|
|
167
157
|
- name: Build Manylinux Wheels
|
|
168
158
|
if: env.PURE == 'false'
|
|
169
|
-
uses: RalfG/python-wheels-manylinux-build@v0.4.
|
|
159
|
+
uses: RalfG/python-wheels-manylinux-build@v0.4.2
|
|
170
160
|
with:
|
|
171
|
-
python-versions:
|
|
161
|
+
python-versions: 'cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310'
|
|
162
|
+
pre-build-command: 'git config --global --add safe.directory "*"'
|
|
172
163
|
|
|
173
164
|
- name: Upload Artifact
|
|
174
165
|
if: env.PURE == 'false'
|
|
175
|
-
uses: actions/upload-artifact@
|
|
166
|
+
uses: actions/upload-artifact@v3
|
|
176
167
|
with:
|
|
177
168
|
name: dist
|
|
178
|
-
path:
|
|
169
|
+
path: dist/*manylinux*.whl
|
|
179
170
|
|
|
180
171
|
release:
|
|
181
172
|
name: Release
|
|
@@ -184,56 +175,45 @@ jobs:
|
|
|
184
175
|
steps:
|
|
185
176
|
|
|
186
177
|
- name: Download Artifact
|
|
187
|
-
uses: actions/download-artifact@
|
|
178
|
+
uses: actions/download-artifact@v3
|
|
188
179
|
with:
|
|
189
180
|
name: dist
|
|
190
181
|
path: ./dist
|
|
191
182
|
|
|
192
183
|
- name: Download Artifact
|
|
193
|
-
uses: actions/download-artifact@
|
|
184
|
+
uses: actions/download-artifact@v3
|
|
194
185
|
with:
|
|
195
186
|
name: conda_packages
|
|
196
187
|
path: ./conda_packages
|
|
197
188
|
|
|
198
|
-
- name: Publish on TestPyPI
|
|
199
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
200
|
-
with:
|
|
201
|
-
user: __token__
|
|
202
|
-
password: ${{ secrets.testpypi }}
|
|
203
|
-
repository_url: https://test.pypi.org/legacy/
|
|
204
|
-
|
|
205
189
|
- name: Get Version Number
|
|
206
190
|
if: github.event.ref_type == 'tag'
|
|
207
191
|
run: |
|
|
208
192
|
VERSION="${GITHUB_REF/refs\/tags\/v/}"
|
|
209
193
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
210
194
|
|
|
211
|
-
- name: Create GitHub Release
|
|
195
|
+
- name: Create GitHub Release and Upload Release Asset
|
|
212
196
|
if: github.event.ref_type == 'tag'
|
|
213
|
-
|
|
214
|
-
uses: actions/create-release@latest
|
|
197
|
+
uses: softprops/action-gh-release@v1
|
|
215
198
|
env:
|
|
216
199
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
217
200
|
with:
|
|
218
201
|
tag_name: ${{ github.event.ref }}
|
|
219
|
-
|
|
202
|
+
name: ${{ env.PACKAGE_NAME }} ${{ env.VERSION }}
|
|
220
203
|
draft: true
|
|
221
204
|
prerelease: ${{ contains(github.event.ref, 'rc') }}
|
|
205
|
+
files: ./dist/${{ env.PACKAGE_NAME }}-${{ env.VERSION }}.tar.gz
|
|
222
206
|
|
|
223
|
-
- name:
|
|
224
|
-
|
|
225
|
-
uses: actions/upload-release-asset@v1
|
|
226
|
-
env:
|
|
227
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
207
|
+
- name: Publish on TestPyPI
|
|
208
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
228
209
|
with:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
asset_content_type: application/gzip
|
|
210
|
+
user: __token__
|
|
211
|
+
password: ${{ secrets.testpypi }}
|
|
212
|
+
repository-url: https://test.pypi.org/legacy/
|
|
233
213
|
|
|
234
214
|
- name: Publish on PyPI
|
|
235
215
|
if: github.event.ref_type == 'tag'
|
|
236
|
-
uses: pypa/gh-action-pypi-publish@
|
|
216
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
237
217
|
with:
|
|
238
218
|
user: __token__
|
|
239
219
|
password: ${{ secrets.pypi }}
|
|
@@ -244,10 +224,12 @@ jobs:
|
|
|
244
224
|
auto-update-conda: true
|
|
245
225
|
|
|
246
226
|
- name: Install Anaconda cloud client
|
|
227
|
+
shell: bash -l {0}
|
|
247
228
|
run: conda install anaconda-client
|
|
248
229
|
|
|
249
230
|
- name: Publish to Anaconda test label
|
|
250
231
|
if: github.event.ref_type != 'tag'
|
|
232
|
+
shell: bash -l {0}
|
|
251
233
|
run: |
|
|
252
234
|
anaconda \
|
|
253
235
|
--token ${{ secrets.ANACONDA_API_TOKEN }} \
|
|
@@ -257,6 +239,7 @@ jobs:
|
|
|
257
239
|
conda_packages/*/*
|
|
258
240
|
|
|
259
241
|
- name: Publish to Anaconda main label
|
|
242
|
+
shell: bash -l {0}
|
|
260
243
|
if: github.event.ref_type == 'tag'
|
|
261
244
|
run: |
|
|
262
245
|
anaconda \
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: zprocess
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.21.1
|
|
4
4
|
Summary: A set of utilities for multiprocessing using zeromq.
|
|
5
5
|
Home-page: http://github.com/chrisjbillington/zprocess
|
|
6
6
|
Author: Chris Billington
|
|
7
7
|
Author-email: chrisjbillington@gmail.com
|
|
8
8
|
License: BSD
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5
|
|
11
10
|
Description-Content-Type: text/markdown
|
|
12
11
|
License-File: LICENSE.txt
|
|
@@ -29,5 +28,3 @@ and a process-tree-wide event system.
|
|
|
29
28
|
|
|
30
29
|
* Install `python setup.py install`.
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
@@ -24,7 +24,14 @@ if _cwd == 'zprocess' and _path not in sys.path:
|
|
|
24
24
|
import ipaddress
|
|
25
25
|
import zprocess
|
|
26
26
|
from zprocess.security import SecureContext
|
|
27
|
-
from zprocess.utils import
|
|
27
|
+
from zprocess.utils import (
|
|
28
|
+
gethostbyname,
|
|
29
|
+
Interruptor,
|
|
30
|
+
Interrupted,
|
|
31
|
+
TimeoutError,
|
|
32
|
+
get_venv_executable_and_env,
|
|
33
|
+
_get_fileno
|
|
34
|
+
)
|
|
28
35
|
from zprocess.remote import (
|
|
29
36
|
RemoteProcessClient,
|
|
30
37
|
RemoteOutputReceiver,
|
|
@@ -785,7 +792,7 @@ class OutputInterceptor(object):
|
|
|
785
792
|
raise RuntimeError(msg)
|
|
786
793
|
self.streams_connected[self.streamname] = self
|
|
787
794
|
stream = getattr(sys, self.streamname)
|
|
788
|
-
if stream is not None and stream
|
|
795
|
+
if stream is not None and _get_fileno(stream) > 0:
|
|
789
796
|
self.stream_fd = stream.fileno()
|
|
790
797
|
else:
|
|
791
798
|
# On Windows with pythonw, sys.stdout and sys.stderr are None or
|
|
@@ -1386,9 +1393,9 @@ class ProcessTree(object):
|
|
|
1386
1393
|
extra_env = {k.encode(): v.encode() for k, v in extra_env.items()}
|
|
1387
1394
|
|
|
1388
1395
|
if remote_process_client is None:
|
|
1389
|
-
env = os.environ.copy()
|
|
1396
|
+
executable, env = get_venv_executable_and_env(os.environ.copy())
|
|
1390
1397
|
env.update(extra_env)
|
|
1391
|
-
child = subprocess.Popen([
|
|
1398
|
+
child = subprocess.Popen([executable] + cmd, env=env)
|
|
1392
1399
|
else:
|
|
1393
1400
|
# The remote server will prefix the path to its own Python interpreter.
|
|
1394
1401
|
# Also, it will pass to Popen an env consisting of its own env updated with
|
|
@@ -14,7 +14,7 @@ else:
|
|
|
14
14
|
from weakref import WeakSet
|
|
15
15
|
import atexit
|
|
16
16
|
from zprocess import ZMQServer
|
|
17
|
-
from zprocess.utils import setup_logging
|
|
17
|
+
from zprocess.utils import setup_logging, get_venv_executable_and_env
|
|
18
18
|
from zprocess.remote import PROTOCOL_VERSION
|
|
19
19
|
|
|
20
20
|
ERR_INVALID_COMMAND = 'error: invalid command'
|
|
@@ -163,9 +163,11 @@ class RemoteProcessServer(ZMQServer):
|
|
|
163
163
|
|
|
164
164
|
def proxy_Popen(self, cmd, *args, **kwargs):
|
|
165
165
|
if kwargs.pop('prepend_sys_executable', False):
|
|
166
|
-
|
|
166
|
+
executable, kwargs['env'] = get_venv_executable_and_env(os.environ.copy())
|
|
167
|
+
cmd = [executable] + cmd
|
|
168
|
+
else:
|
|
169
|
+
kwargs['env'] = os.environ.copy()
|
|
167
170
|
# Update current environment with the contents of 'extra_env', if given:
|
|
168
|
-
kwargs['env'] = os.environ.copy()
|
|
169
171
|
kwargs['env'].update(kwargs.pop('extra_env', {}))
|
|
170
172
|
if any(kwarg in kwargs for kwarg in ['stdout', 'stdin', 'stderr']):
|
|
171
173
|
msg = "Cannot specify stdout, stdin or stderr for remote process."
|
|
@@ -207,4 +209,4 @@ class RemoteProcessServer(ZMQServer):
|
|
|
207
209
|
return PROTOCOL_VERSION
|
|
208
210
|
else:
|
|
209
211
|
logger.info('%s: invalid command', self.sock.peer_ip)
|
|
210
|
-
return ERR_INVALID_COMMAND
|
|
212
|
+
return ERR_INVALID_COMMAND
|
|
@@ -8,6 +8,8 @@ import zmq
|
|
|
8
8
|
import zmq.auth.thread
|
|
9
9
|
from zmq.utils.monitor import recv_monitor_message
|
|
10
10
|
|
|
11
|
+
from zprocess.utils import _get_fileno
|
|
12
|
+
|
|
11
13
|
_path, _cwd = os.path.split(os.getcwd())
|
|
12
14
|
if _cwd == 'zprocess' and _path not in sys.path:
|
|
13
15
|
# Running from within zprocess dir? Add to sys.path for testing during
|
|
@@ -37,7 +39,7 @@ def _check_versions():
|
|
|
37
39
|
except ImportError:
|
|
38
40
|
# No bundled zmq.
|
|
39
41
|
return
|
|
40
|
-
if sys.stderr is not None and sys.stderr
|
|
42
|
+
if sys.stderr is not None and _get_fileno(sys.stderr) >= 0:
|
|
41
43
|
sys.stderr.write(_bundle_warning)
|
|
42
44
|
|
|
43
45
|
# Events to tell when a conneciton has succeeded, including authentication:
|
|
@@ -139,7 +141,7 @@ class SecureSocket(zmq.Socket):
|
|
|
139
141
|
# remote process server on localhost with no encryption:
|
|
140
142
|
|
|
141
143
|
# Enable IPv6 by default:
|
|
142
|
-
|
|
144
|
+
self.ipv6 = True
|
|
143
145
|
|
|
144
146
|
def _is_internal(self, endpoint):
|
|
145
147
|
"""Return whether a bind or connect endpoint is on an internal
|
|
@@ -147,7 +149,7 @@ class SecureSocket(zmq.Socket):
|
|
|
147
149
|
if endpoint.startswith('inproc://'):
|
|
148
150
|
return True
|
|
149
151
|
if endpoint.startswith('tcp://'):
|
|
150
|
-
host =
|
|
152
|
+
host = endpoint.split('//', 1)[1].rsplit(':', 1)[0]
|
|
151
153
|
if host.startswith('[') and host.endswith(']'):
|
|
152
154
|
host = host[1:-1]
|
|
153
155
|
if host == '*':
|
|
@@ -276,7 +278,11 @@ class SecureSocket(zmq.Socket):
|
|
|
276
278
|
msg = zmq.Socket.recv(self, flags=flags, copy=False, track=track)
|
|
277
279
|
if self.tcp:
|
|
278
280
|
try:
|
|
279
|
-
|
|
281
|
+
peer_ip = msg.get('Peer-Address')
|
|
282
|
+
peer_ip = ipaddress.ip_address(peer_ip)
|
|
283
|
+
if peer_ip.version == 6 and peer_ip.ipv4_mapped is not None:
|
|
284
|
+
peer_ip = peer_ip.ipv4_mapped
|
|
285
|
+
self.peer_ip = str(peer_ip)
|
|
280
286
|
except zmq.error.ZMQError:
|
|
281
287
|
# Sent by a non-TCP client, even though we are a TCP socket. This is
|
|
282
288
|
# possible sometimes. For example, XPUB seems to receive unsubscribe
|
|
@@ -290,7 +296,7 @@ class SecureSocket(zmq.Socket):
|
|
|
290
296
|
msg = INSECURE_RECV_WARNING % self.peer_ip
|
|
291
297
|
if self.logger is not None:
|
|
292
298
|
self.logger.warning(msg)
|
|
293
|
-
elif sys.stderr is not None and sys.stderr
|
|
299
|
+
elif sys.stderr is not None and _get_fileno(sys.stderr) >= 0:
|
|
294
300
|
sys.stderr.write(msg + '\n')
|
|
295
301
|
# Disregard the insecure message and call recv() again
|
|
296
302
|
continue
|
|
@@ -324,12 +330,23 @@ class SecureContext(zmq.Context):
|
|
|
324
330
|
self.client_secretkey, self.server_secretkey = keys
|
|
325
331
|
self.client_publickey = zmq.curve_public(self.client_secretkey)
|
|
326
332
|
self.server_publickey = zmq.curve_public(self.server_secretkey)
|
|
327
|
-
|
|
333
|
+
|
|
334
|
+
# There are potential reference cycles causing the authentication thread to
|
|
335
|
+
# prevent the interpreter from shutting down. In pyzmq <25, the
|
|
336
|
+
# authentication thread holds a reference to the context. So we must avoid
|
|
337
|
+
# holding a reference to it. In pyzmq 25+, the authentication thread and
|
|
338
|
+
# threadauthenticator objects both hold references to each other. So we
|
|
339
|
+
# replace one with a weakref to break the cycle.
|
|
340
|
+
|
|
328
341
|
auth = zmq.auth.thread.ThreadAuthenticator(self)
|
|
329
342
|
auth.start()
|
|
343
|
+
|
|
344
|
+
if auth.thread.authenticator is auth:
|
|
345
|
+
auth.thread.authenticator = weakref.proxy(auth)
|
|
346
|
+
|
|
330
347
|
# Allow only clients who have the client public key:
|
|
331
|
-
auth.
|
|
332
|
-
auth.
|
|
348
|
+
auth.allow_any = False
|
|
349
|
+
auth.certs['*'] = {self.client_publickey: True}
|
|
333
350
|
self.secure = True
|
|
334
351
|
|
|
335
352
|
@classmethod
|
|
@@ -6,6 +6,8 @@ import logging, logging.handlers
|
|
|
6
6
|
from binascii import hexlify
|
|
7
7
|
import socket
|
|
8
8
|
import tempfile
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import io
|
|
9
11
|
|
|
10
12
|
import zmq
|
|
11
13
|
|
|
@@ -157,6 +159,15 @@ def start_daemon(cmd_args):
|
|
|
157
159
|
os._exit(0)
|
|
158
160
|
|
|
159
161
|
|
|
162
|
+
def _get_fileno(stream):
|
|
163
|
+
"""Return stream.get_fileno(), or -1 if the call raises io.UnsupportedOperation"""
|
|
164
|
+
try:
|
|
165
|
+
return stream.fileno()
|
|
166
|
+
except io.UnsupportedOperation:
|
|
167
|
+
# IDLE or Jupyter. Return an invalid fileno
|
|
168
|
+
return -1
|
|
169
|
+
|
|
170
|
+
|
|
160
171
|
def disable_quick_edit():
|
|
161
172
|
"""Disable the 'quick-edit' misfeature of Windows' cmd.exe, in which a single click
|
|
162
173
|
on the console puts it in 'select' mode indefinitely, causing writes to stdout from
|
|
@@ -168,7 +179,7 @@ def disable_quick_edit():
|
|
|
168
179
|
"""
|
|
169
180
|
if os.name == 'nt' and all(
|
|
170
181
|
[
|
|
171
|
-
a is not None and a.isatty() and a
|
|
182
|
+
a is not None and a.isatty() and _get_fileno(a) >= 0
|
|
172
183
|
for a in (sys.stdin, sys.stdout, sys.stderr)
|
|
173
184
|
]
|
|
174
185
|
):
|
|
@@ -261,4 +272,23 @@ def gethostbyname(host, prefer_ipv4=True, require_ipv4=False):
|
|
|
261
272
|
if family == socket.AF_INET:
|
|
262
273
|
return sockaddr[0]
|
|
263
274
|
family, _, _, _, sockaddr = results[0]
|
|
264
|
-
return sockaddr[0]
|
|
275
|
+
return sockaddr[0]
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def get_venv_executable_and_env(env=None):
|
|
279
|
+
"""If we are running in a venv on Windows or MacOS such that sys.executable is a
|
|
280
|
+
shim to sys._base_executable, then return sys._base_executable, as well as the
|
|
281
|
+
environment that should be passed to sys._base_executable in order for it to know to
|
|
282
|
+
configure itself for the virtual environment instead of the base environment. This
|
|
283
|
+
allows us to skip the shim and thus have fewer layers in our process hierarchy. If
|
|
284
|
+
we are not in a venv, return sys.executable and the env as passed in. If env passed
|
|
285
|
+
in is None, and needs to be modified for the subprocess, a copy of os.environ(),
|
|
286
|
+
appropriately modified, will be returned."""
|
|
287
|
+
base_executable = getattr(sys, '_base_executable', sys.executable)
|
|
288
|
+
if Path(base_executable) != Path(sys.executable):
|
|
289
|
+
if env is None:
|
|
290
|
+
env = os.environ.copy()
|
|
291
|
+
env["__PYVENV_LAUNCHER__"] = str(sys.executable)
|
|
292
|
+
return base_executable, env
|
|
293
|
+
return sys.executable, env
|
|
294
|
+
|
|
@@ -47,7 +47,13 @@ class ZLogClient(object):
|
|
|
47
47
|
|
|
48
48
|
RESPONSE_TIMEOUT = 5000
|
|
49
49
|
|
|
50
|
-
def __init__(
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
host='localhost',
|
|
53
|
+
port=DEFAULT_PORT,
|
|
54
|
+
shared_secret=None,
|
|
55
|
+
allow_insecure=True,
|
|
56
|
+
):
|
|
51
57
|
self.host = socket.gethostbyname(host)
|
|
52
58
|
self.port = port
|
|
53
59
|
self.shared_secret = shared_secret
|
|
@@ -194,12 +200,12 @@ class ZMQLoggingHandler(Handler):
|
|
|
194
200
|
|
|
195
201
|
|
|
196
202
|
|
|
197
|
-
# Backwards compatibility
|
|
203
|
+
# Backwards compatibility follows
|
|
198
204
|
|
|
199
205
|
_default_zlog_client = None
|
|
200
206
|
|
|
201
207
|
_ZMQLoggingHandler = ZMQLoggingHandler
|
|
202
|
-
"""Backward compatibility to allow instantiating a lock without a
|
|
208
|
+
"""Backward compatibility to allow instantiating a lock without a ZLogClient as the
|
|
203
209
|
first argument"""
|
|
204
210
|
class ZMQLoggingHandler(_ZMQLoggingHandler):
|
|
205
211
|
def __init__(self, *args, **kwargs):
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: zprocess
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.21.1
|
|
4
4
|
Summary: A set of utilities for multiprocessing using zeromq.
|
|
5
5
|
Home-page: http://github.com/chrisjbillington/zprocess
|
|
6
6
|
Author: Chris Billington
|
|
7
7
|
Author-email: chrisjbillington@gmail.com
|
|
8
8
|
License: BSD
|
|
9
|
-
Platform: UNKNOWN
|
|
10
9
|
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5
|
|
11
10
|
Description-Content-Type: text/markdown
|
|
12
11
|
License-File: LICENSE.txt
|
|
@@ -29,5 +28,3 @@ and a process-tree-wide event system.
|
|
|
29
28
|
|
|
30
29
|
* Install `python setup.py install`.
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|