File tree Expand file tree Collapse file tree 4 files changed +37
-4
lines changed Expand file tree Collapse file tree 4 files changed +37
-4
lines changed Original file line number Diff line number Diff line change
1
+ Correctly handle warnings created with arguments that can't be serialized during the transfer from workers to master node.
Original file line number Diff line number Diff line change @@ -766,6 +766,23 @@ def test_func(request):
766
766
result = testdir .runpytest (n )
767
767
result .stdout .fnmatch_lines (["*MyWarning*" , "*1 passed, 1 warnings*" ])
768
768
769
+ @pytest .mark .parametrize ("n" , ["-n0" , "-n1" ])
770
+ def test_unserializable_arguments (self , testdir , n ):
771
+ """Check that warnings with unserializable arguments are handled correctly (#349)."""
772
+ testdir .makepyfile (
773
+ """
774
+ import warnings, pytest
775
+
776
+ def test_func(tmpdir):
777
+ fn = (tmpdir / 'foo.txt').ensure(file=1)
778
+ with fn.open('r') as f:
779
+ warnings.warn(UserWarning("foo", f))
780
+ """
781
+ )
782
+ testdir .syspathinsert ()
783
+ result = testdir .runpytest (n )
784
+ result .stdout .fnmatch_lines (["*UserWarning*foo.txt*" , "*1 passed, 1 warnings*" ])
785
+
769
786
770
787
class TestNodeFailure :
771
788
def test_load_single (self , testdir ):
Original file line number Diff line number Diff line change 12
12
13
13
import _pytest .hookspec
14
14
import pytest
15
+ from execnet .gateway_base import dumps , DumpError
15
16
16
17
17
18
class WorkerInteractor (object ):
@@ -181,8 +182,15 @@ def serialize_warning_message(warning_message):
181
182
if isinstance (warning_message .message , Warning ):
182
183
message_module = type (warning_message .message ).__module__
183
184
message_class_name = type (warning_message .message ).__name__
184
- message_args = warning_message .message .args
185
185
message_str = str (warning_message .message )
186
+ # check now if we can serialize the warning arguments (#349)
187
+ # if not, we will just use the exception message on the master node
188
+ try :
189
+ dumps (warning_message .message .args )
190
+ except DumpError :
191
+ message_args = None
192
+ else :
193
+ message_args = warning_message .message .args
186
194
else :
187
195
message_str = warning_message .message
188
196
message_module = None
Original file line number Diff line number Diff line change @@ -426,9 +426,16 @@ def unserialize_warning_message(data):
426
426
if data ["message_module" ]:
427
427
mod = importlib .import_module (data ["message_module" ])
428
428
cls = getattr (mod , data ["message_class_name" ])
429
- try :
430
- message = cls (* data ["message_args" ])
431
- except TypeError :
429
+ message = None
430
+ if data ["message_args" ] is not None :
431
+ try :
432
+ message = cls (* data ["message_args" ])
433
+ except TypeError :
434
+ pass
435
+ if message is None :
436
+ # could not recreate the original warning instance;
437
+ # create a generic Warning instance with the original
438
+ # message at least
432
439
message_text = "{mod}.{cls}: {msg}" .format (
433
440
mod = data ["message_module" ],
434
441
cls = data ["message_class_name" ],
You can’t perform that action at this time.
0 commit comments