monkeypatch, doc, apiwarn, deprecation fixes
--HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									29d437489d
								
							
						
					
					
						commit
						0f29b503ef
					
				|  | @ -148,7 +148,7 @@ def getrealname(username): | ||||||
|      |      | ||||||
| 
 | 
 | ||||||
| class Project: | class Project: | ||||||
|     mydir = py.magic.autopath().dirpath() |     mydir = py.path.local(__file__).dirpath() | ||||||
|     title = "py lib" |     title = "py lib" | ||||||
|     prefix_title = ""  # we have a logo already containing "py lib" |     prefix_title = ""  # we have a logo already containing "py lib" | ||||||
|     encoding = 'latin1'  |     encoding = 'latin1'  | ||||||
|  |  | ||||||
|  | @ -10,7 +10,8 @@ | ||||||
| using easy_install  | using easy_install  | ||||||
| =================================================== | =================================================== | ||||||
| 
 | 
 | ||||||
| With a working `setuptools installation`_ you can type:: | With a working `setuptools installation`_ or `distribute installation`_  | ||||||
|  | you can type:: | ||||||
| 
 | 
 | ||||||
|     easy_install -U py  |     easy_install -U py  | ||||||
| 
 | 
 | ||||||
|  | @ -19,19 +20,11 @@ will trigger an upgrade if you already have an older version installed. | ||||||
| On Linux systems you may need to execute the command as superuser and | On Linux systems you may need to execute the command as superuser and | ||||||
| on Windows you might need to write down the full path to ``easy_install``.  | on Windows you might need to write down the full path to ``easy_install``.  | ||||||
| The py lib and its tools are expected to work well on Linux, | The py lib and its tools are expected to work well on Linux, | ||||||
| Windows and OSX, Python versions 2.3, 2.4, 2.5 and 2.6. | Windows and OSX, Python versions 2.4, 2.5, 2.6 through to | ||||||
| 
 | the Python3 versions 3.0 and 3.1.  | ||||||
| **IMPORTANT NOTE**: if you are using Windows and have  |  | ||||||
| 0.8 versions of the py lib on your system, please download  |  | ||||||
| and execute http://codespeak.net/svn/py/build/winpathclean.py |  | ||||||
| This will check that no previous files are getting in the way.  |  | ||||||
| You can find out the py lib version with:: |  | ||||||
| 
 |  | ||||||
|     import py |  | ||||||
|     print py.version |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| .. _mercurial: http://mercurial.selenic.com/wiki/ | .. _mercurial: http://mercurial.selenic.com/wiki/ | ||||||
|  | .. _`distribute installation`: http://pypi.python.org/pypi/distribute | ||||||
| .. _checkout: | .. _checkout: | ||||||
| .. _tarball: | .. _tarball: | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -74,8 +74,7 @@ per-test capturing.  Here is an example test function: | ||||||
| 
 | 
 | ||||||
|     def test_myoutput(capsys): |     def test_myoutput(capsys): | ||||||
|         print ("hello") |         print ("hello") | ||||||
|         sys.stderr.write("world |         sys.stderr.write("world\n") | ||||||
| ") |  | ||||||
|         out, err = capsys.readouterr() |         out, err = capsys.readouterr() | ||||||
|         assert out == "hello\n" |         assert out == "hello\n" | ||||||
|         assert err == "world\n" |         assert err == "world\n" | ||||||
|  |  | ||||||
|  | @ -10,46 +10,51 @@ safely patch object attributes, dicts and environment variables. | ||||||
| Usage  | Usage  | ||||||
| ---------------- | ---------------- | ||||||
| 
 | 
 | ||||||
| Use the `monkeypatch funcarg`_ to safely modify or delete environment | Use the `monkeypatch funcarg`_ to tweak your global test environment  | ||||||
| variables, object attributes or dictionary values.  For example, if you want | for running a particular test.  You can safely set/del an attribute,  | ||||||
| to set the environment variable ``ENV1`` and patch the | dictionary item or environment variable by respective methods | ||||||
| ``os.path.abspath`` function to return a particular value during a test | on the monkeypatch funcarg.  If you want e.g. to set an ENV1 variable  | ||||||
| function execution you can write it down like this: | and have os.path.expanduser return a particular directory, you can  | ||||||
|  | write it down like this: | ||||||
| 
 | 
 | ||||||
| .. sourcecode:: python  | .. sourcecode:: python  | ||||||
| 
 | 
 | ||||||
|     def test_mytest(monkeypatch): |     def test_mytest(monkeypatch): | ||||||
|         monkeypatch.setenv('ENV1', 'myval') |         monkeypatch.setenv('ENV1', 'myval') | ||||||
|         monkeypatch.setattr(os.path, 'abspath', lambda x: '/') |         monkeypatch.setattr(os.path, 'expanduser', lambda x: '/tmp/xyz') | ||||||
|         ... # your test code  |         ... # your test code that uses those patched values implicitely | ||||||
| 
 | 
 | ||||||
| The function argument will do the modifications and memorize the  | After the test function finished all modifications will be undone,  | ||||||
| old state.  After the test function finished execution all  | because the ``monkeypatch.undo()`` method is registered as a finalizer.  | ||||||
| modifications will be reverted.  See the `monkeypatch blog post`_  |  | ||||||
| for an extensive discussion.   |  | ||||||
| 
 | 
 | ||||||
| To add to a possibly existing environment parameter you | ``monkeypatch.setattr/delattr/delitem/delenv()`` all  | ||||||
| can use this example:  | by default raise an Exception if the target does not exist.  | ||||||
|  | Pass ``raising=False`` if you want to skip this check.  | ||||||
|  | 
 | ||||||
|  | prepending to PATH or other environment variables  | ||||||
|  | --------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | To prepend a value to an already existing environment parameter: | ||||||
| 
 | 
 | ||||||
| .. sourcecode:: python  | .. sourcecode:: python  | ||||||
| 
 | 
 | ||||||
|     def test_mypath_finding(monkeypatch): |     def test_mypath_finding(monkeypatch): | ||||||
|         monkeypatch.setenv('PATH', 'x/y', prepend=":") |         monkeypatch.setenv('PATH', 'x/y', prepend=":") | ||||||
|         #  x/y will be at the beginning of $PATH  |         # in bash language: export PATH=x/y:$PATH  | ||||||
| 
 | 
 | ||||||
| calling "undo" finalization explicitely | calling "undo" finalization explicitely | ||||||
| ----------------------------------------- | ----------------------------------------- | ||||||
| 
 | 
 | ||||||
| Usually at the end of function execution py.test will invoke | At the end of function execution py.test invokes | ||||||
| a teardown hook which undoes the changes.  If you cannot wait | a teardown hook which undoes all monkeypatch changes.  | ||||||
| that long you can also call finalization explicitely:: | If you do not want to wait that long you can call  | ||||||
|  | finalization explicitely:: | ||||||
| 
 | 
 | ||||||
|     monkeypatch.undo()   |     monkeypatch.undo()   | ||||||
| 
 | 
 | ||||||
| This will undo previous changes.  This call consumes the | This will undo previous changes.  This call consumes the | ||||||
| undo stack.  Calling it a second time has no effect.  | undo stack.  Calling it a second time has no effect unless | ||||||
| Within a test you can continue to use the monkeypatch  | you  start monkeypatching after the undo call.  | ||||||
| object, however.  |  | ||||||
| 
 | 
 | ||||||
| .. _`monkeypatch blog post`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/ | .. _`monkeypatch blog post`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/ | ||||||
| 
 | 
 | ||||||
|  | @ -62,7 +67,7 @@ the 'monkeypatch' test function argument | ||||||
| The returned ``monkeypatch`` funcarg provides these  | The returned ``monkeypatch`` funcarg provides these  | ||||||
| helper methods to modify objects, dictionaries or os.environ:: | helper methods to modify objects, dictionaries or os.environ:: | ||||||
| 
 | 
 | ||||||
|     monkeypatch.setattr(obj, name, value)   |     monkeypatch.setattr(obj, name, value, raising=True)   | ||||||
|     monkeypatch.delattr(obj, name, raising=True) |     monkeypatch.delattr(obj, name, raising=True) | ||||||
|     monkeypatch.setitem(mapping, name, value)  |     monkeypatch.setitem(mapping, name, value)  | ||||||
|     monkeypatch.delitem(obj, name, raising=True) |     monkeypatch.delitem(obj, name, raising=True) | ||||||
|  |  | ||||||
|  | @ -10,11 +10,11 @@ class Warning(DeprecationWarning): | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return self.msg  |         return self.msg  | ||||||
| 
 | 
 | ||||||
| def _apiwarn(startversion, msg, stacklevel=1, function=None): | def _apiwarn(startversion, msg, stacklevel=2, function=None): | ||||||
|     # below is mostly COPIED from python2.4/warnings.py's def warn() |     # below is mostly COPIED from python2.4/warnings.py's def warn() | ||||||
|     # Get context information |     # Get context information | ||||||
|     if stacklevel == "initpkg": |     if stacklevel == "initpkg": | ||||||
|         frame = sys._getframe(1) |         frame = sys._getframe(stacklevel == "initpkg" and 1 or stacklevel) | ||||||
|         level = 2 |         level = 2 | ||||||
|         while frame: |         while frame: | ||||||
|             co = frame.f_code |             co = frame.f_code | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ per-test capturing.  Here is an example test function: | ||||||
| 
 | 
 | ||||||
|     def test_myoutput(capsys): |     def test_myoutput(capsys): | ||||||
|         print ("hello") |         print ("hello") | ||||||
|         sys.stderr.write("world\n") |         sys.stderr.write("world\\n") | ||||||
|         out, err = capsys.readouterr() |         out, err = capsys.readouterr() | ||||||
|         assert out == "hello\\n" |         assert out == "hello\\n" | ||||||
|         assert err == "world\\n" |         assert err == "world\\n" | ||||||
|  |  | ||||||
|  | @ -4,46 +4,51 @@ safely patch object attributes, dicts and environment variables. | ||||||
| Usage  | Usage  | ||||||
| ---------------- | ---------------- | ||||||
| 
 | 
 | ||||||
| Use the `monkeypatch funcarg`_ to safely modify or delete environment | Use the `monkeypatch funcarg`_ to tweak your global test environment  | ||||||
| variables, object attributes or dictionary values.  For example, if you want | for running a particular test.  You can safely set/del an attribute,  | ||||||
| to set the environment variable ``ENV1`` and patch the | dictionary item or environment variable by respective methods | ||||||
| ``os.path.abspath`` function to return a particular value during a test | on the monkeypatch funcarg.  If you want e.g. to set an ENV1 variable  | ||||||
| function execution you can write it down like this: | and have os.path.expanduser return a particular directory, you can  | ||||||
|  | write it down like this: | ||||||
| 
 | 
 | ||||||
| .. sourcecode:: python  | .. sourcecode:: python  | ||||||
| 
 | 
 | ||||||
|     def test_mytest(monkeypatch): |     def test_mytest(monkeypatch): | ||||||
|         monkeypatch.setenv('ENV1', 'myval') |         monkeypatch.setenv('ENV1', 'myval') | ||||||
|         monkeypatch.setattr(os.path, 'abspath', lambda x: '/') |         monkeypatch.setattr(os.path, 'expanduser', lambda x: '/tmp/xyz') | ||||||
|         ... # your test code  |         ... # your test code that uses those patched values implicitely | ||||||
| 
 | 
 | ||||||
| The function argument will do the modifications and memorize the  | After the test function finished all modifications will be undone,  | ||||||
| old state.  After the test function finished execution all  | because the ``monkeypatch.undo()`` method is registered as a finalizer.  | ||||||
| modifications will be reverted.  See the `monkeypatch blog post`_  |  | ||||||
| for an extensive discussion.   |  | ||||||
| 
 | 
 | ||||||
| To add to a possibly existing environment parameter you | ``monkeypatch.setattr/delattr/delitem/delenv()`` all  | ||||||
| can use this example:  | by default raise an Exception if the target does not exist.  | ||||||
|  | Pass ``raising=False`` if you want to skip this check.  | ||||||
|  | 
 | ||||||
|  | prepending to PATH or other environment variables  | ||||||
|  | --------------------------------------------------------- | ||||||
|  | 
 | ||||||
|  | To prepend a value to an already existing environment parameter: | ||||||
| 
 | 
 | ||||||
| .. sourcecode:: python  | .. sourcecode:: python  | ||||||
| 
 | 
 | ||||||
|     def test_mypath_finding(monkeypatch): |     def test_mypath_finding(monkeypatch): | ||||||
|         monkeypatch.setenv('PATH', 'x/y', prepend=":") |         monkeypatch.setenv('PATH', 'x/y', prepend=":") | ||||||
|         #  x/y will be at the beginning of $PATH  |         # in bash language: export PATH=x/y:$PATH  | ||||||
| 
 | 
 | ||||||
| calling "undo" finalization explicitely | calling "undo" finalization explicitely | ||||||
| ----------------------------------------- | ----------------------------------------- | ||||||
| 
 | 
 | ||||||
| Usually at the end of function execution py.test will invoke | At the end of function execution py.test invokes | ||||||
| a teardown hook which undoes the changes.  If you cannot wait | a teardown hook which undoes all monkeypatch changes.  | ||||||
| that long you can also call finalization explicitely:: | If you do not want to wait that long you can call  | ||||||
|  | finalization explicitely:: | ||||||
| 
 | 
 | ||||||
|     monkeypatch.undo()   |     monkeypatch.undo()   | ||||||
| 
 | 
 | ||||||
| This will undo previous changes.  This call consumes the | This will undo previous changes.  This call consumes the | ||||||
| undo stack.  Calling it a second time has no effect.  | undo stack.  Calling it a second time has no effect unless | ||||||
| Within a test you can continue to use the monkeypatch  | you  start monkeypatching after the undo call.  | ||||||
| object, however.  |  | ||||||
| 
 | 
 | ||||||
| .. _`monkeypatch blog post`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/ | .. _`monkeypatch blog post`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/ | ||||||
| """ | """ | ||||||
|  | @ -54,7 +59,7 @@ def pytest_funcarg__monkeypatch(request): | ||||||
|     """The returned ``monkeypatch`` funcarg provides these  |     """The returned ``monkeypatch`` funcarg provides these  | ||||||
|     helper methods to modify objects, dictionaries or os.environ:: |     helper methods to modify objects, dictionaries or os.environ:: | ||||||
| 
 | 
 | ||||||
|         monkeypatch.setattr(obj, name, value)   |         monkeypatch.setattr(obj, name, value, raising=True)   | ||||||
|         monkeypatch.delattr(obj, name, raising=True) |         monkeypatch.delattr(obj, name, raising=True) | ||||||
|         monkeypatch.setitem(mapping, name, value)  |         monkeypatch.setitem(mapping, name, value)  | ||||||
|         monkeypatch.delitem(obj, name, raising=True) |         monkeypatch.delitem(obj, name, raising=True) | ||||||
|  | @ -79,8 +84,11 @@ class MonkeyPatch: | ||||||
|         self._setattr = [] |         self._setattr = [] | ||||||
|         self._setitem = [] |         self._setitem = [] | ||||||
| 
 | 
 | ||||||
|     def setattr(self, obj, name, value): |     def setattr(self, obj, name, value, raising=True): | ||||||
|         self._setattr.insert(0, (obj, name, getattr(obj, name, notset))) |         oldval = getattr(obj, name, notset) | ||||||
|  |         if raising and oldval is notset: | ||||||
|  |             raise AttributeError("%r has no attribute %r" %(obj, name)) | ||||||
|  |         self._setattr.insert(0, (obj, name, oldval)) | ||||||
|         setattr(obj, name, value) |         setattr(obj, name, value) | ||||||
| 
 | 
 | ||||||
|     def delattr(self, obj, name, raising=True): |     def delattr(self, obj, name, raising=True): | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ def test_forwarding_to_warnings_module(): | ||||||
| 
 | 
 | ||||||
| def test_apiwarn_functional(): | def test_apiwarn_functional(): | ||||||
|     capture = py.io.StdCapture() |     capture = py.io.StdCapture() | ||||||
|     py.log._apiwarn("x.y.z", "something") |     py.log._apiwarn("x.y.z", "something", stacklevel=1) | ||||||
|     out, err = capture.reset() |     out, err = capture.reset() | ||||||
|     py.builtin.print_("out", out) |     py.builtin.print_("out", out) | ||||||
|     py.builtin.print_("err", err) |     py.builtin.print_("err", err) | ||||||
|  |  | ||||||
|  | @ -5,6 +5,13 @@ from py.__.test.plugin.pytest_monkeypatch import MonkeyPatch | ||||||
| def test_setattr(): | def test_setattr(): | ||||||
|     class A: |     class A: | ||||||
|         x = 1 |         x = 1 | ||||||
|  |     monkeypatch = MonkeyPatch() | ||||||
|  |     py.test.raises(AttributeError, "monkeypatch.setattr(A, 'notexists', 2)") | ||||||
|  |     monkeypatch.setattr(A, 'y', 2, raising=False) | ||||||
|  |     assert A.y == 2 | ||||||
|  |     monkeypatch.undo() | ||||||
|  |     assert not hasattr(A, 'y') | ||||||
|  | 
 | ||||||
|     monkeypatch = MonkeyPatch() |     monkeypatch = MonkeyPatch() | ||||||
|     monkeypatch.setattr(A, 'x', 2) |     monkeypatch.setattr(A, 'x', 2) | ||||||
|     assert A.x == 2 |     assert A.x == 2 | ||||||
|  | @ -17,11 +24,6 @@ def test_setattr(): | ||||||
|     monkeypatch.undo() # double-undo makes no modification |     monkeypatch.undo() # double-undo makes no modification | ||||||
|     assert A.x == 5 |     assert A.x == 5 | ||||||
| 
 | 
 | ||||||
|     monkeypatch.setattr(A, 'y', 3) |  | ||||||
|     assert A.y == 3 |  | ||||||
|     monkeypatch.undo() |  | ||||||
|     assert not hasattr(A, 'y') |  | ||||||
|       |  | ||||||
| def test_delattr(): | def test_delattr(): | ||||||
|     class A: |     class A: | ||||||
|         x = 1 |         x = 1 | ||||||
|  | @ -35,7 +37,7 @@ def test_delattr(): | ||||||
|     monkeypatch.delattr(A, 'x') |     monkeypatch.delattr(A, 'x') | ||||||
|     py.test.raises(AttributeError, "monkeypatch.delattr(A, 'y')") |     py.test.raises(AttributeError, "monkeypatch.delattr(A, 'y')") | ||||||
|     monkeypatch.delattr(A, 'y', raising=False) |     monkeypatch.delattr(A, 'y', raising=False) | ||||||
|     monkeypatch.setattr(A, 'x', 5) |     monkeypatch.setattr(A, 'x', 5, raising=False) | ||||||
|     assert A.x == 5 |     assert A.x == 5 | ||||||
|     monkeypatch.undo() |     monkeypatch.undo() | ||||||
|     assert A.x == 1 |     assert A.x == 1 | ||||||
|  | @ -45,6 +47,7 @@ def test_setitem(): | ||||||
|     monkeypatch = MonkeyPatch() |     monkeypatch = MonkeyPatch() | ||||||
|     monkeypatch.setitem(d, 'x', 2) |     monkeypatch.setitem(d, 'x', 2) | ||||||
|     monkeypatch.setitem(d, 'y', 1700) |     monkeypatch.setitem(d, 'y', 1700) | ||||||
|  |     monkeypatch.setitem(d, 'y', 1700) | ||||||
|     assert d['x'] == 2 |     assert d['x'] == 2 | ||||||
|     assert d['y'] == 1700 |     assert d['y'] == 1700 | ||||||
|     monkeypatch.setitem(d, 'x', 3) |     monkeypatch.setitem(d, 'x', 3) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue