New submission from Samuel Freilich <sfreil...@google.com>:

Currently, it's an error to call the stop() method of a patcher object created 
by mock.patch repeatedly:

>>> patch = mock.patch.object(Foo, 'BAR', 'x')
>>> patch.start()
'x'
>>> patch.stop()
>>> patch.stop()
RuntimeError: stop called on unstarted patcher

This causes unnecessary problems when test classes using mock.patch.stopall for 
cleanup are mixed with those cleaning up patches individually:

class TestA(unittest.TestCase):

  def setUp():
    patcher = mock.patch.object(...)
    self.mock_a = patcher.start()
    self.addCleanup(patcher.stop)

  ...


class TestB(TestA):

  def setUp():
    super().setUp()
    self.addCleanup(mock.patch.stopall)
    self.mock_b = mock.patch.object(...).start()

  ...


This fails because mock.patch.stopall stops the patch set up in TestA.setUp(), 
then that raises an exception when it's stopped again.

But why does patcher.stop() enforce that precondition? Wouldn't it be 
sufficient for it to just enforce the postcondition, that after stop() is 
called the patch is stopped()? That would make it easier to write test code 
which makes use of mock.patch.stopall, which allows the proper cleanup of 
patches to be configured much more concisely.

----------
messages: 338371
nosy: sfreilich
priority: normal
severity: normal
status: open
title: Patcher stop method should be idempotent

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue36366>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to