[Pytest-commit] commit/pytest: 2 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Fri Sep 27 12:34:52 CEST 2013
2 new commits in pytest:
https://bitbucket.org/hpk42/pytest/commits/23278f23f092/
Changeset: 23278f23f092
User: hpk42
Date: 2013-09-27 12:28:34
Summary: fix some tests wrt to expecting output now that pytest does no
introduce unwanted "buffering" on "-s" calls.
Affected #: 4 files
diff -r 8f4c9f56a90fa62074cc2c52a4158f1f09adb084 -r 23278f23f0923076011f554bb875e332fde21125 _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -1623,7 +1623,7 @@
assert not name.startswith(self._argprefix)
fixturedef = FixtureDef(self, nodeid, name, obj,
marker.scope, marker.params,
- marker.yieldctx,
+ yieldctx=marker.yieldctx,
unittest=unittest)
faclist = self._arg2fixturedefs.setdefault(name, [])
if not fixturedef.has_location:
diff -r 8f4c9f56a90fa62074cc2c52a4158f1f09adb084 -r 23278f23f0923076011f554bb875e332fde21125 testing/python/fixture.py
--- a/testing/python/fixture.py
+++ b/testing/python/fixture.py
@@ -1993,12 +1993,12 @@
""")
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines("""
- setup
- test1 1
- teardown
- setup
- test2 1
- teardown
+ *setup*
+ *test1 1*
+ *teardown*
+ *setup*
+ *test2 1*
+ *teardown*
""")
def test_scoped(self, testdir):
@@ -2016,10 +2016,10 @@
""")
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines("""
- setup
- test1 1
- test2 1
- teardown
+ *setup*
+ *test1 1*
+ *test2 1*
+ *teardown*
""")
def test_setup_exception(self, testdir):
diff -r 8f4c9f56a90fa62074cc2c52a4158f1f09adb084 -r 23278f23f0923076011f554bb875e332fde21125 testing/test_fixture_finalizer.py
--- a/testing/test_fixture_finalizer.py
+++ b/testing/test_fixture_finalizer.py
@@ -28,4 +28,4 @@
"""))
reprec = testdir.runpytest("-s")
for test in ['test_browser']:
- reprec.stdout.fnmatch_lines('Finalized')
+ reprec.stdout.fnmatch_lines('*Finalized*')
diff -r 8f4c9f56a90fa62074cc2c52a4158f1f09adb084 -r 23278f23f0923076011f554bb875e332fde21125 testing/test_terminal.py
--- a/testing/test_terminal.py
+++ b/testing/test_terminal.py
@@ -672,7 +672,7 @@
stdout = k.pop()
stdout.close()
""")
- result = testdir.runpytest("-s")
+ result = testdir.runpytest()
result.stdout.fnmatch_lines([
"*2 passed*"
])
https://bitbucket.org/hpk42/pytest/commits/95a817c87a02/
Changeset: 95a817c87a02
User: hpk42
Date: 2013-09-27 12:33:06
Summary: merge monkeypatch.replace into monkeypatch.setattr, also support monkeypatch.delattr.
Affected #: 4 files
diff -r 23278f23f0923076011f554bb875e332fde21125 -r 95a817c87a020ef2c325244d6f596943eaf5d0ae CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,10 +17,10 @@
- PR27: correctly handle nose.SkipTest during collection. Thanks
Antonio Cuni, Ronny Pfannschmidt.
-- new monkeypatch.replace() to avoid imports and provide a shorter
+- new monkeypatch.setattr() variant to provide a shorter
invocation for patching out classes/functions from modules:
- monkeypatch.replace("requests.get", myfunc
+ monkeypatch.setattr("requests.get", myfunc)
will replace the "get" function of the "requests" module with ``myfunc``.
diff -r 23278f23f0923076011f554bb875e332fde21125 -r 95a817c87a020ef2c325244d6f596943eaf5d0ae _pytest/monkeypatch.py
--- a/_pytest/monkeypatch.py
+++ b/_pytest/monkeypatch.py
@@ -25,6 +25,39 @@
request.addfinalizer(mpatch.undo)
return mpatch
+
+
+def derive_importpath(import_path):
+ if not isinstance(import_path, str) or "." not in import_path:
+ raise TypeError("must be absolute import path string, not %r" %
+ (import_path,))
+ rest = []
+ target = import_path
+ while target:
+ try:
+ obj = __import__(target, None, None, "__doc__")
+ except ImportError:
+ if "." not in target:
+ __tracebackhide__ = True
+ pytest.fail("could not import any sub part: %s" %
+ import_path)
+ target, name = target.rsplit(".", 1)
+ rest.append(name)
+ else:
+ assert rest
+ try:
+ while len(rest) > 1:
+ attr = rest.pop()
+ obj = getattr(obj, attr)
+ attr = rest[0]
+ getattr(obj, attr)
+ except AttributeError:
+ __tracebackhide__ = True
+ pytest.fail("object %r has no attribute %r" % (obj, attr))
+ return attr, obj
+
+
+
notset = object()
class monkeypatch:
@@ -34,70 +67,66 @@
self._setitem = []
self._cwd = None
- def replace(self, import_path, value):
- """ replace the object specified by a dotted ``import_path``
- with the given ``value``.
+ def setattr(self, target, name, value=notset, raising=True):
+ """ set attribute value on target, memorizing the old value.
+ By default raise AttributeError if the attribute did not exist.
- For example ``replace("os.path.abspath", value)`` will
- trigger an ``import os.path`` and a subsequent
- setattr(os.path, "abspath", value). Or to prevent
- the requests library from performing requests you can call
- ``replace("requests.sessions.Session.request", None)``
- which will lead to an import of ``requests.sessions`` and a call
- to ``setattr(requests.sessions.Session, "request", None)``.
+ For convenience you can specify a string as ``target`` which
+ will be interpreted as a dotted import path, with the last part
+ being the attribute name. Example:
+ ``monkeypatch.setattr("os.getcwd", lambda x: "/")``
+ would set the ``getcwd`` function of the ``os`` module.
+
+ The ``raising`` value determines if the setattr should fail
+ if the attribute is not already present (defaults to True
+ which means it will raise).
"""
- if not isinstance(import_path, str) or "." not in import_path:
- raise TypeError("must be absolute import path string, not %r" %
- (import_path,))
- rest = []
- target = import_path
- while target:
- try:
- obj = __import__(target, None, None, "__doc__")
- except ImportError:
- if "." not in target:
- __tracebackhide__ = True
- pytest.fail("could not import any sub part: %s" %
- import_path)
- target, name = target.rsplit(".", 1)
- rest.append(name)
- else:
- assert rest
- try:
- while len(rest) > 1:
- attr = rest.pop()
- obj = getattr(obj, attr)
- attr = rest[0]
- getattr(obj, attr)
- except AttributeError:
- __tracebackhide__ = True
- pytest.fail("object %r has no attribute %r" % (obj, attr))
- return self.setattr(obj, attr, value)
+ __tracebackhide__ = True
- def setattr(self, obj, name, value, raising=True):
- """ set attribute ``name`` on ``obj`` to ``value``, by default
- raise AttributeEror if the attribute did not exist.
+ if value is notset:
+ if not isinstance(target, str):
+ raise TypeError("use setattr(target, name, value) or "
+ "setattr(target, value) with target being a dotted "
+ "import string")
+ value = name
+ name, target = derive_importpath(target)
- """
- oldval = getattr(obj, name, notset)
+ oldval = getattr(target, name, notset)
if raising and oldval is notset:
- raise AttributeError("%r has no attribute %r" %(obj, name))
+ raise AttributeError("%r has no attribute %r" %(target, name))
# avoid class descriptors like staticmethod/classmethod
- if inspect.isclass(obj):
- oldval = obj.__dict__.get(name, notset)
- self._setattr.insert(0, (obj, name, oldval))
- setattr(obj, name, value)
+ if inspect.isclass(target):
+ oldval = target.__dict__.get(name, notset)
+ self._setattr.insert(0, (target, name, oldval))
+ setattr(target, name, value)
- def delattr(self, obj, name, raising=True):
- """ delete attribute ``name`` from ``obj``, by default raise
- AttributeError it the attribute did not previously exist. """
- if not hasattr(obj, name):
+ def delattr(self, target, name=notset, raising=True):
+ """ delete attribute ``name`` from ``target``, by default raise
+ AttributeError it the attribute did not previously exist.
+
+ If no ``name`` is specified and ``target`` is a string
+ it will be interpreted as a dotted import path with the
+ last part being the attribute name.
+
+ If raising is set to false, the attribute is allowed to not
+ pre-exist.
+ """
+ __tracebackhide__ = True
+ if name is notset:
+ if not isinstance(target, str):
+ raise TypeError("use delattr(target, name) or "
+ "delattr(target) with target being a dotted "
+ "import string")
+ name, target = derive_importpath(target)
+
+ if not hasattr(target, name):
if raising:
raise AttributeError(name)
else:
- self._setattr.insert(0, (obj, name, getattr(obj, name, notset)))
- delattr(obj, name)
+ self._setattr.insert(0, (target, name,
+ getattr(target, name, notset)))
+ delattr(target, name)
def setitem(self, dic, name, value):
""" set dictionary entry ``name`` to value. """
diff -r 23278f23f0923076011f554bb875e332fde21125 -r 95a817c87a020ef2c325244d6f596943eaf5d0ae doc/en/monkeypatch.txt
--- a/doc/en/monkeypatch.txt
+++ b/doc/en/monkeypatch.txt
@@ -48,11 +48,28 @@
import pytest
@pytest.fixture(autouse=True)
def no_requests(monkeypatch):
- monkeypatch.replace("requests.session.Session.request", None)
+ monkeypatch.delattr("requests.session.Session.request")
-This autouse fixture will be executed for all test functions and it
-will replace the method ``request.session.Session.request`` with the
-value None so that any attempts to create http requests will fail.
+This autouse fixture will be executed for each test function and it
+will delete the method ``request.session.Session.request``
+so that any attempts within tests to create http requests will fail.
+
+example: setting an attribute on some class
+------------------------------------------------------
+
+If you need to patch out ``os.getcwd()`` to return an artifical
+value::
+
+ def test_some_interaction(monkeypatch):
+ monkeypatch.setattr("os.getcwd", lambda: "/")
+
+which is equivalent to the long form::
+
+ def test_some_interaction(monkeypatch):
+ import os
+ monkeypatch.setattr(os, "getcwd", lambda: "/")
+
+
Method reference of the monkeypatch function argument
-----------------------------------------------------
diff -r 23278f23f0923076011f554bb875e332fde21125 -r 95a817c87a020ef2c325244d6f596943eaf5d0ae testing/test_monkeypatch.py
--- a/testing/test_monkeypatch.py
+++ b/testing/test_monkeypatch.py
@@ -35,26 +35,32 @@
monkeypatch.undo() # double-undo makes no modification
assert A.x == 5
-class TestReplace:
+class TestSetattrWithImportPath:
def test_string_expression(self, monkeypatch):
- monkeypatch.replace("os.path.abspath", lambda x: "hello2")
+ monkeypatch.setattr("os.path.abspath", lambda x: "hello2")
assert os.path.abspath("123") == "hello2"
def test_string_expression_class(self, monkeypatch):
- monkeypatch.replace("_pytest.config.Config", 42)
+ monkeypatch.setattr("_pytest.config.Config", 42)
import _pytest
assert _pytest.config.Config == 42
def test_wrong_target(self, monkeypatch):
- pytest.raises(TypeError, lambda: monkeypatch.replace(None, None))
+ pytest.raises(TypeError, lambda: monkeypatch.setattr(None, None))
def test_unknown_import(self, monkeypatch):
pytest.raises(pytest.fail.Exception,
- lambda: monkeypatch.replace("unkn123.classx", None))
+ lambda: monkeypatch.setattr("unkn123.classx", None))
def test_unknown_attr(self, monkeypatch):
pytest.raises(pytest.fail.Exception,
- lambda: monkeypatch.replace("os.path.qweqwe", None))
+ lambda: monkeypatch.setattr("os.path.qweqwe", None))
+
+ def test_delattr(self, monkeypatch):
+ monkeypatch.delattr("os.path.abspath")
+ assert not hasattr(os.path, "abspath")
+ monkeypatch.undo()
+ assert os.path.abspath
def test_delattr():
class A:
@@ -262,3 +268,5 @@
monkeypatch.undo()
assert Sample.hello()
+
+
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list