Skip to content

Commit 351fdd3

Browse files
committed
Handling lack of forking on Windows.
On Windows multiprocess.Process() performs a "spawn" instead of "fork" since fork doesn't exist on Windows. The problem with spawn is the child process starts from scratch and the Click context is empty (vs populated on *nix). Moving Config.from_context() call pre-fork so it's passed on via pickle instead. Fixing more tests with os.path.join() instead of hard coded Unix path separator.
1 parent 6dadad5 commit 351fdd3

File tree

2 files changed

+36
-26
lines changed

2 files changed

+36
-26
lines changed

sphinxcontrib/versioning/sphinx_.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,15 @@ def __init__(self, dirname, filename, overrides, tags):
159159
self.extensions.append('sphinxcontrib.versioning.sphinx_')
160160

161161

162-
def _build(argv, versions, current_name, is_root):
162+
def _build(argv, config, versions, current_name, is_root):
163163
"""Build Sphinx docs via multiprocessing for isolation.
164164
165165
:param tuple argv: Arguments to pass to Sphinx.
166+
:param sphinxcontrib.versioning.lib.Config config: Runtime configuration.
166167
:param sphinxcontrib.versioning.versions.Versions versions: Versions class instance.
167168
:param str current_name: The ref name of the current version being built.
168169
:param bool is_root: Is this build in the web root?
169170
"""
170-
config = Config.from_context()
171-
172171
# Patch.
173172
application.Config = ConfigInject
174173
if config.show_banner:
@@ -195,18 +194,19 @@ def _build(argv, versions, current_name, is_root):
195194
raise SphinxError
196195

197196

198-
def _read_config(argv, current_name, queue):
197+
def _read_config(argv, config, current_name, queue):
199198
"""Read the Sphinx config via multiprocessing for isolation.
200199
201200
:param tuple argv: Arguments to pass to Sphinx.
201+
:param sphinxcontrib.versioning.lib.Config config: Runtime configuration.
202202
:param str current_name: The ref name of the current version being built.
203203
:param multiprocessing.queues.Queue queue: Communication channel to parent process.
204204
"""
205205
# Patch.
206206
EventHandlers.ABORT_AFTER_READ = queue
207207

208208
# Run.
209-
_build(argv, Versions(list()), current_name, False)
209+
_build(argv, config, Versions(list()), current_name, False)
210210

211211

212212
def build(source, target, versions, current_name, is_root):
@@ -222,8 +222,10 @@ def build(source, target, versions, current_name, is_root):
222222
"""
223223
log = logging.getLogger(__name__)
224224
argv = ('sphinx-build', source, target)
225+
config = Config.from_context()
226+
225227
log.debug('Running sphinx-build for %s with args: %s', current_name, str(argv))
226-
child = multiprocessing.Process(target=_build, args=(argv, versions, current_name, is_root))
228+
child = multiprocessing.Process(target=_build, args=(argv, config, versions, current_name, is_root))
227229
child.start()
228230
child.join() # Block.
229231
if child.exitcode != 0:
@@ -244,11 +246,12 @@ def read_config(source, current_name):
244246
"""
245247
log = logging.getLogger(__name__)
246248
queue = multiprocessing.Queue()
249+
config = Config.from_context()
247250

248251
with TempDir() as temp_dir:
249252
argv = ('sphinx-build', source, temp_dir)
250253
log.debug('Running sphinx-build for config values with args: %s', str(argv))
251-
child = multiprocessing.Process(target=_read_config, args=(argv, current_name, queue))
254+
child = multiprocessing.Process(target=_read_config, args=(argv, config, current_name, queue))
252255
child.start()
253256
child.join() # Block.
254257
if child.exitcode != 0:

tests/test_routines/test_build_all.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Test function in module."""
22

3+
from os.path import join
4+
35
import pytest
46

57
from sphinxcontrib.versioning.git import export
@@ -30,9 +32,9 @@ def test_single(tmpdir, local_docs, urls):
3032
'_sources',
3133
'_static',
3234
'master',
33-
'master/.doctrees',
34-
'master/_sources',
35-
'master/_static',
35+
join('master', '.doctrees'),
36+
join('master', '_sources'),
37+
join('master', '_static'),
3638
]
3739
assert actual == expected
3840

@@ -76,20 +78,20 @@ def test_multiple(tmpdir, config, local_docs, run, urls, triple, parallel):
7678
'_sources',
7779
'_static',
7880
'master',
79-
'master/.doctrees',
80-
'master/_sources',
81-
'master/_static',
81+
join('master', '.doctrees'),
82+
join('master', '_sources'),
83+
join('master', '_static'),
8284
'v1.0.0',
83-
'v1.0.0/.doctrees',
84-
'v1.0.0/_sources',
85-
'v1.0.0/_static',
85+
join('v1.0.0', '.doctrees'),
86+
join('v1.0.0', '_sources'),
87+
join('v1.0.0', '_static'),
8688
]
8789
if triple:
8890
expected.extend([
8991
'v1.0.1',
90-
'v1.0.1/.doctrees',
91-
'v1.0.1/_sources',
92-
'v1.0.1/_static',
92+
join('v1.0.1', '.doctrees'),
93+
join('v1.0.1', '_sources'),
94+
join('v1.0.1', '_static'),
9395
])
9496
assert actual == expected
9597

@@ -165,8 +167,8 @@ def test_banner_branch(tmpdir, banner, config, local_docs, run, show_banner):
165167
build_all(str(exported_root), str(dst), versions)
166168
actual = sorted(f.relto(dst) for f in dst.visit(lambda p: p.basename in ('contents.html', 'one.html', 'two.html')))
167169
expected = [
168-
'contents.html', 'master/contents.html', 'master/one.html',
169-
'old_build/contents.html', 'old_build/one.html', 'old_build/two.html', 'one.html'
170+
'contents.html', join('master', 'contents.html'), join('master', 'one.html'),
171+
join('old_build', 'contents.html'), join('old_build', 'one.html'), join('old_build', 'two.html'), 'one.html'
170172
]
171173
assert actual == expected
172174

@@ -241,13 +243,18 @@ def test_banner_tag(tmpdir, banner, config, local_docs, run, recent):
241243
build_all(str(exported_root), str(dst), versions)
242244
actual = sorted(f.relto(dst)
243245
for f in dst.visit(lambda p: p.basename in ('contents.html', 'one.html', 'two.html', 'too.html')))
244-
expected = ['contents.html', 'master/contents.html', 'master/one.html', 'master/too.html', 'one.html', 'too.html']
246+
expected = [
247+
'contents.html',
248+
join('master', 'contents.html'), join('master', 'one.html'), join('master', 'too.html'),
249+
'one.html',
250+
'too.html',
251+
]
245252
if recent:
246-
expected = ['201612/contents.html', '201612/one.html', '201612/too.html'] + expected
247-
expected = ['201611/contents.html', '201611/one.html', '201611/two.html'] + expected
253+
expected = [join('201612', 'contents.html'), join('201612', 'one.html'), join('201612', 'too.html')] + expected
254+
expected = [join('201611', 'contents.html'), join('201611', 'one.html'), join('201611', 'two.html')] + expected
248255
else:
249-
expected += ['v1.0.0/contents.html', 'v1.0.0/one.html', 'v1.0.0/two.html']
250-
expected += ['v2.0.0/contents.html', 'v2.0.0/one.html', 'v2.0.0/too.html']
256+
expected += [join('v1.0.0', 'contents.html'), join('v1.0.0', 'one.html'), join('v1.0.0', 'two.html')]
257+
expected += [join('v2.0.0', 'contents.html'), join('v2.0.0', 'one.html'), join('v2.0.0', 'too.html')]
251258
assert actual == expected
252259

253260
# Verify master banner.

0 commit comments

Comments
 (0)