This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Cannot deepcopy unittest.TestCase instances
Type: Stage:
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: gregory.p.smith Nosy List: gregory.p.smith, michael.foord, spiv
Priority: normal Keywords:

Created on 2009-04-02 00:27 by spiv, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg85123 - (view) Author: Andrew Bennetts (spiv) Date: 2009-04-02 00:27
Here's a demonstration of the bug:

>>> from unittest import TestCase
>>> class MyTest(TestCase):
...     def test_foo(self): pass
... 
>>> tc = MyTest('test_foo')
>>> import copy
>>> copy.deepcopy(tc)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 189, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 338, in
_reconstruct
    state = deepcopy(state, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 255, in
_deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 255, in
_deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 189, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/usr/local/stow/py2.7/lib/python2.7/copy.py", line 323, in
_reconstruct
    y = callable(*args)
  File "/usr/local/bin/../stow/py2.7/lib/python2.7/copy_reg.py", line
93, in __newobj__
    return cls.__new__(cls, *args)
TypeError: instancemethod expected at least 2 arguments, got 0


This regression breaks bzr's test suite, which copies test objects to
run the same test against multiple scenarios (e.g. to run all the same
tests against all the implementations of bzrlib.transport.Transport,
such as HTTPTransport and SFTPTransport.) 
<https://launchpad.net/testtools> also implements test parameterisation
in this way, and it is extremely useful.

I suspect the __test_equality_funcs on TestCase is the problem:

>>> tc.__dict__
{'_testMethodDoc': None, '_TestCase__type_equality_funcs': {<type
'dict'>: <bound method MyTest.assertDictEqual of <__main__.MyTest
testMethod=test_foo>>, <type 'tuple'>: <bound method
MyTest.assertTupleEqual of <__main__.MyTest testMethod=test_foo>>, <type
'frozenset'>: <bound method MyTest.assertSetEqual of <__main__.MyTest
testMethod=test_foo>>, <type 'list'>: <bound method
MyTest.assertListEqual of <__main__.MyTest testMethod=test_foo>>, <type
'set'>: <bound method MyTest.assertSetEqual of <__main__.MyTest
testMethod=test_foo>>}, '_testMethodName': 'test_foo'}

copy.deepcopy can't deepcopy bound methods, reasonably enough.
msg85163 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-02 04:55
This is a workaround:

import copy
copy._deepcopy_dispatch[types.MethodType] = copy._deepcopy_atomic
msg85166 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-02 05:19
We can fix this by wrapping the assert functions in our assert register
as deep-copyable objects. (And then unwrapping when we fetch them.)
msg85171 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-04-02 05:52
Fixed in revision 71043.
History
Date User Action Args
2022-04-11 14:56:47adminsetgithub: 49910
2009-04-02 05:52:35michael.foordsetstatus: open -> closed
resolution: fixed
messages: + msg85171
2009-04-02 05:19:20michael.foordsetmessages: + msg85166
2009-04-02 04:55:59michael.foordsetmessages: + msg85163
2009-04-02 04:35:22michael.foordsetnosy: + michael.foord
2009-04-02 00:35:13benjamin.petersonsetassignee: gregory.p.smith

nosy: + gregory.p.smith
2009-04-02 00:27:53spivcreate