classification
Title: Shared execution context between doctests in a module
Type: enhancement Stage:
Components: Documentation Versions: Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Mariatta Nosy List: Mariatta, anthonypjshaw, docs@python, kernc
Priority: normal Keywords:

Created on 2016-02-06 15:54 by kernc, last changed 2019-05-06 18:27 by anthonypjshaw.

Messages (3)
msg259731 - (view) Author: kernc (kernc) * Date: 2016-02-06 15:54
The doctest execution context documentation [0] says the tests get shallow *copies* of module's globals, so one test can't mingle with results of another. This makes it impossible to make literate modules such as:


    """
    This module is about reusable doctests context.

    Examples
    --------
    Let's prepare something the later examples can work with:

    >>> import foo
    >>> result = foo.Something()
    2
    
    """
    class Bar:
        """
        Class about something.

        >>> bar = Bar(foo)
        >>> bar.uses(foo)
        True
        
        """
        def baz(self):
            """
            Returns 3.

            >>> result + bar.baz()
            5
            
            """
            return 3


I.e. one has to instantiate everything in every single test. The documentation says one can pass their own globals as `glob=your_dict`, but it doesn't mention the dict is *cleared* after the test run.

Please acknowledge the use case of doctests in a module sharing their environment and results sometimes legitimately exists, and to make it future-compatible, please amend the final paragraph of the relevant part of documentation [0] like so:


    You can force use of your own dict as the execution context by 
    passing `globs=your_dict` to `testmod()` or `testfile()` instead, 
    e.g., to have all doctests in a module use the _same_ execution
    context (sharing variables), define a context like so:
    
        class Context(dict):
            def copy(self):
                return self
            def clear(self):
                pass
    
    and use it, optionally prepopulated with `M`'s globals:
    
        doctest.testmod(module,
                        glob=Context(module.__dict__.copy()))


Thank you!


[0]: https://docs.python.org/3/library/doctest.html#what-s-the-execution-context
msg259732 - (view) Author: kernc (kernc) * Date: 2016-02-06 16:16
The use case is not unpopular [1] and with unambiguous examples like

    >>> arr = np.arange(5)
    >>> my_sum(arr)
    10

(i.e., without importing numpy as np everywhere), it also makes a lot of sense.


[1]: http://stackoverflow.com/questions/13106118/object-reuse-in-python-doctest/35242443
msg341585 - (view) Author: anthony shaw (anthonypjshaw) * (Python triager) Date: 2019-05-06 18:24
this issue would be good for pycon sprints
History
Date User Action Args
2019-05-06 18:27:22anthonypjshawsetassignee: docs@python -> Mariatta
2019-05-06 18:24:29anthonypjshawsetnosy: + Mariatta, anthonypjshaw
messages: + msg341585
2016-02-06 16:16:50kerncsetmessages: + msg259732
2016-02-06 15:54:22kernccreate