Skip to content

Commit 997ee16

Browse files
Spaceratwillmcgugan
authored andcommitted
Fix multiprocessing hang on FSErrors (PyFilesystem#184)
* Fix multiprocessing hang on FSErrors * Fixed whitespace
1 parent 3d801a0 commit 997ee16

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

fs/errors.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,13 @@ class MissingInfoNamespace(AttributeError):
6060

6161
def __init__(self, namespace):
6262
# type: (Text) -> None
63+
self.namespace = namespace
6364
msg = "namespace '{}' is required for this attribute"
6465
super(MissingInfoNamespace, self).__init__(msg.format(namespace))
6566

67+
def __reduce__(self):
68+
return type(self), (self.namespace,)
69+
6670

6771
@six.python_2_unicode_compatible
6872
class FSError(Exception):
@@ -133,7 +137,10 @@ def new_func(*args, **kwargs):
133137

134138
return new_func # type: ignore
135139

140+
def __reduce__(self):
141+
return type(self), (self._msg, self.exc)
136142

143+
137144
class PathError(FSError):
138145
"""Base exception for errors to do with a path string.
139146
"""
@@ -145,6 +152,9 @@ def __init__(self, path, msg=None):
145152
self.path = path
146153
super(PathError, self).__init__(msg=msg)
147154

155+
def __reduce__(self):
156+
return type(self), (self.path, self._msg)
157+
148158

149159
class NoSysPath(PathError):
150160
"""The filesystem does not provide *sys paths* to the resource.
@@ -164,6 +174,9 @@ def __init__(self, path, purpose, msg=None):
164174
self.purpose = purpose
165175
super(NoURL, self).__init__(path, msg=msg)
166176

177+
def __reduce__(self):
178+
return type(self), (self.path, self.purpose, self._msg)
179+
167180

168181
class InvalidPath(PathError):
169182
"""Path can't be mapped on to the underlaying filesystem.
@@ -198,6 +211,9 @@ def __init__(
198211
self.errno = getattr(exc, "errno", None)
199212
super(OperationFailed, self).__init__(msg=msg)
200213

214+
def __reduce__(self):
215+
return type(self), (self.path, self.exc, self._msg)
216+
201217

202218
class Unsupported(OperationFailed):
203219
"""Operation not supported by the filesystem.
@@ -253,6 +269,9 @@ def __init__(self, path, exc=None, msg=None):
253269
self.exc = exc
254270
super(ResourceError, self).__init__(msg=msg)
255271

272+
def __reduce__(self):
273+
return type(self), (self.path, self.exc, self._msg)
274+
256275

257276
class ResourceNotFound(ResourceError):
258277
"""Required resource not found.
@@ -339,6 +358,11 @@ class IllegalBackReference(ValueError):
339358

340359
def __init__(self, path):
341360
# type: (Text) -> None
342-
_msg = "path '{path}' contains back-references outside of filesystem"
343-
_msg = _msg.format(path=path)
344-
super(IllegalBackReference, self).__init__(_msg)
361+
self.path = path
362+
msg = (
363+
"path '{path}' contains back-references outside of filesystem"
364+
).format(path=path)
365+
super(IllegalBackReference, self).__init__(msg)
366+
367+
def __reduce__(self):
368+
return type(self), (self.path,)

tests/test_errors.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import unicode_literals
22

3+
import multiprocessing
34
import unittest
45

56
from six import text_type
@@ -26,6 +27,27 @@ def test_unsupported(self):
2627
"not supported"
2728
)
2829

30+
def test_raise_in_multiprocessing(self):
31+
# Without the __reduce__ methods in FSError subclasses, this test will hang forever.
32+
tests = [
33+
[errors.ResourceNotFound, 'some_path'],
34+
[errors.FilesystemClosed],
35+
[errors.CreateFailed],
36+
[errors.NoSysPath, 'some_path'],
37+
[errors.NoURL, 'some_path', 'some_purpose'],
38+
[errors.Unsupported]
39+
]
40+
try:
41+
pool = multiprocessing.Pool(1)
42+
for args in tests:
43+
with self.assertRaises(args[0]):
44+
pool.apply(_multiprocessing_test_task, args)
45+
finally:
46+
pool.close()
47+
48+
def _multiprocessing_test_task(err, *args):
49+
raise err(*args)
50+
2951

3052
class TestCreateFailed(unittest.TestCase):
3153

0 commit comments

Comments
 (0)