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: Allow doctest to deep copy globals
Type: enhancement Stage: resolved
Components: Tests Versions: Python 3.6
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: DqASe, steven.daprano
Priority: normal Keywords:

Created on 2016-04-28 22:25 by DqASe, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
x.py DqASe, 2016-04-29 10:09
Messages (6)
msg264452 - (view) Author: (DqASe) Date: 2016-04-28 22:25
Currently doctest makes shallow copies of the environment or globs argument.  This is somewhat un-symmetrical: on the one hand, a test cannot see variables created by another, but on the other, it can alter mutable objects.  This is inconvenient e.g. when documenting several methods that change an object (say, obj.append() , then obj.insert() - one would hope that the results are independent on the order tests are executed ).

An option to make deep copies of the variables in the context, instead of shallow ones, would in my opinion solve the issue cleanly.
msg264453 - (view) Author: (DqASe) Date: 2016-04-28 22:41
Alternatively, add an option like deepglobs={...} . The dictionary argument would be deep-copied at each test and added to the environment.
msg264456 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-04-29 00:46
I'm afraid I can't quite see what the problem is. If you're passing your own globs argument, can't you deepcopy it yourself? 

Could you show a minimal, short example demonstrating the issue please?
msg264482 - (view) Author: (DqASe) Date: 2016-04-29 10:09
I'd like each test to see the same environment (including variables contents). Deepcopying extraglobs argument at call time is not sufficient because it is only done once, not before each test.
msg264488 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2016-04-29 11:12
On Fri, Apr 29, 2016 at 10:09:46AM +0000, DqASe wrote:
> Added file: http://bugs.python.org/file42649/x.py

Ah, I see! That makes sense now. Thanks.

Why don't you just set the initial state of the lists in the doctests? 
That makes much better documentation. Imagine a more complex example 
where the function name means nothing to you and the topic is 
unfamiliar:

    >>> piyo(mylist, hogera=12, fuga=7)
    >>> mylist
    [0, 2, 4, 6, 14, 16]

But if I show the initial state of the list, not only is the meaning 
more obvious (which makes it better documentation and a better test), 
but your problem goes away:

    >>> mylist = [0, 2, 4, 6, 8, 10, 12, 14, 16]
    >>> piyo(mylist, hogera=12, fuga=7)
    >>> mylist
    [0, 2, 4, 6, 14, 16]

I fear that this suggested feature will encourage poor doctests that 
rely on global state rather than local state.
msg264492 - (view) Author: (DqASe) Date: 2016-04-29 12:18
I see your point. I thought it can still be useful in these scenarios:

1. when doc/testing tens of methods of a specific class. Instantiation of the class is repetitive (DRY principle).
2. Instantiation can be expensive (e.g. from network)
3. To behave less-surprisingly (why can't I re-use objects created in an earlier test, but I can re-use the internal state of mutable ones?)
4. An aspiration for tests to be forcibly sandboxed from the execution environment (that would require deep copies by default).
5. Relying on an always-equal global state is better (IMHO) than relying on a *mutable* global state, after all.

But I understand it's debatable. Thanks anyways.
History
Date User Action Args
2022-04-11 14:58:30adminsetgithub: 71065
2020-11-24 23:38:14iritkatrielsetstatus: open -> closed
resolution: rejected
stage: resolved
2016-04-29 12:18:39DqASesetmessages: + msg264492
2016-04-29 11:12:06steven.dapranosetmessages: + msg264488
2016-04-29 10:09:46DqASesetfiles: + x.py

messages: + msg264482
2016-04-29 00:46:42steven.dapranosetnosy: + steven.daprano

messages: + msg264456
versions: + Python 3.6
2016-04-28 22:41:40DqASesetmessages: + msg264453
2016-04-28 22:29:03DqASesetcomponents: + Tests, - Library (Lib)
2016-04-28 22:25:26DqASecreate