diff --git a/CHANGELOG b/CHANGELOG index 42d7dc4fb..f8d01a63b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ Changes between 2.3.0 and 2.3.dev ----------------------------------- +- fix issue202 - fix regression: using "self" from fixture functions now + works as expected (it's the same "self" instance that a test method + which uses the fixture sees) + - skip pexpect using tests (test_pdb.py mostly) on freebsd* systems due to pexpect not supporting it properly (hanging) diff --git a/_pytest/__init__.py b/_pytest/__init__.py index 684f25d27..11fc2d964 100644 --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.1.dev1' +__version__ = '2.3.1.dev2' diff --git a/_pytest/python.py b/_pytest/python.py index f716c1938..568f7250a 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -12,6 +12,16 @@ cutdir = py.path.local(_pytest.__file__).dirpath() callable = py.builtin.callable +def getimfunc(func): + try: + return func.__func__ + except AttributeError: + try: + return func.im_func + except AttributeError: + return func + + class FixtureFunctionMarker: def __init__(self, scope, params, autouse=False): self.scope = scope @@ -1621,7 +1631,19 @@ class FixtureDef: if self.unittest: result = self.func(request.instance, **kwargs) else: - result = self.func(**kwargs) + fixturefunc = self.func + # the fixture function needs to be bound to the actual + # request.instance so that code working with "self" behaves + # as expected. XXX request.instance should maybe return None + # instead of raising AttributeError + try: + if request.instance is not None: + fixturefunc = getimfunc(self.func) + if fixturefunc != self.func: + fixturefunc = fixturefunc.__get__(request.instance) + except AttributeError: + pass + result = fixturefunc(**kwargs) self.active = True self.cached_result = result return result diff --git a/doc/en/example/index.txt b/doc/en/example/index.txt index 73459fdc5..7af2a3cac 100644 --- a/doc/en/example/index.txt +++ b/doc/en/example/index.txt @@ -16,7 +16,7 @@ For basic examples, see - :doc:`../getting-started` for basic introductory examples - :ref:`assert` for basic assertion examples - :ref:`fixtures` for basic fixture/setup examples -- :ref:`parametrize` for basic fixture/setup examples +- :ref:`parametrize` for basic test function parametrization - :doc:`../unittest` for basic unittest integration - :doc:`../nose` for basic nosetests integration diff --git a/setup.py b/setup.py index d5e0327b7..d6288280c 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def main(): name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.1.dev1', + version='2.3.1.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff --git a/testing/test_python.py b/testing/test_python.py index 0227870b5..d2ee7e3f2 100644 --- a/testing/test_python.py +++ b/testing/test_python.py @@ -2037,6 +2037,21 @@ class TestFixtureUsages: reprec = testdir.inline_run() reprec.assertoutcome(passed=2) + def test_request_instance_issue203(self, testdir): + testdir.makepyfile(""" + import pytest + + class TestClass: + @pytest.fixture + def setup1(self, request): + assert self == request.instance + self.arg1 = 1 + def test_hello(self, setup1): + assert self.arg1 == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + class TestFixtureManager: def pytest_funcarg__testdir(self, request): testdir = request.getfuncargvalue("testdir")