Open qthequartermasterman opened 3 months ago
This is also probably relevant. If I extend the example to include dill.loads
, and then disable capture with pytest -s
, I get a recursion error. Again, this code works as expected with vanilla doctest and in a script.
class MyClass:
"""Running a file containing this class with `python -m pytest this_file.py --doctest-modules` will fail with `TypeError: cannot pickle 'EncodedFile' object`.
Examples:
>>> def template_function():
... return "Hello, World!"
>>> import dill
>>> string = dill.dumps(template_function)
>>> dill.loads(string)()
'Hello, World!'
"""
010 >>> string = dill.dumps(template_function)
011 >>> dill.loads(string)()
UNEXPECTED EXCEPTION: RecursionError('maximum recursion depth exceeded')
Traceback (most recent call last):
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/doctest.py", line 1350, in __run
exec(compile(example.source, filename, "single",
File "<doctest test_client.MyClass[3]>", line 1, in <module>
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/site-packages/dill/_dill.py", line 286, in loads
return load(file, ignore, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/site-packages/dill/_dill.py", line 272, in load
return Unpickler(file, ignore=ignore, **kwds).load()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/site-packages/dill/_dill.py", line 419, in load
obj = StockUnpickler.load(self)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/site-packages/pluggy/_manager.py", line 74, in __getattr__
return getattr(self._dist, attr, default)
^^^^^^^^^^
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/site-packages/pluggy/_manager.py", line 74, in __getattr__
return getattr(self._dist, attr, default)
^^^^^^^^^^
File "/opt/homebrew/Caskroom/miniforge/base/envs/my-env/lib/python3.11/site-packages/pluggy/_manager.py", line 74, in __getattr__
return getattr(self._dist, attr, default)
^^^^^^^^^^
[Previous line repeated 955 more times]
RecursionError: maximum recursion depth exceeded
Does it work when IO capture is disabled? pytest -s
Does it work when IO capture is disabled?
pytest -s
I get a different error during unpickling that also only occurs with pytest. You can see my second post in this issue for those details.
Based on the traceback dill pickles random objects
We might be able to give better errors but we cant fix dill doing things that are fragile
Facing the same issue. Something's off with module parser: running pytest tests/subdir
passes
whereas running bare pytest
without a path specified - thus project root - will have dill tests fail:
The pickled subject being a function referenced from within a fixture's inner scope
@pytest.fixture
def fn():
def _fn(*args):
import functools
if not args:
return 0
return functools.reduce(lambda x, y: x + y, args)
return _fn
__init__.py
to tests/
and subdirs make tests fail with the same error no mater what path is specifiedYou need to disable assertion rewrite for at least the module
And then hope
It's generally unsafe to serialize inner functions in any way
Dill is playing with fire there and it breaks whenever someone throws in objects that aren't serializable
pip list
from the virtual environment you are usingDescription of the Problem
When I attempt to
dill
a function defined inside of adoctest
,pytest
raises an error, complaining thatTypeError: cannot pickle 'EncodedFile' object
. Best I can tell, this is theEncodedFile
object in pytest.This error only occurs when I run those doctests via pytest. They run just fine via vanilla doctest. The same code also works just fine in a script and as a regular pytest test function.
I fear that this is related to https://github.com/pytest-dev/pytest/issues/10845, which doesn't seem to have a solution.
Minimal Reproducible Example
Using pytest to run those doctests will cause the
TypeError: cannot pickle 'EncodedFile' object
.Using vanilla doctest works fine. (Ignore the fact that the test failed. The expected output did not match. Note that it did successfully dump the function using dill.)
Using a regular pytest function to perform the test also works fine. This is only when attempting to dill a function defined in a doctest run with pytest.
Pytest and Operating System versions
This was run on Pytest 8.2.2, Python 3.11 on an M1 Macbook Air (macOS Sonoma 14.4.1). The same errors were also seen on Python 3.9 on the same Macbook and on Python 3.11 on an amd64 Ubuntu Machine (Ubuntu 22.04 LTS).
Pip list