From 12de92cd2b818906d342dbdfaf96999887bc9658 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Fri, 28 Aug 2020 09:55:26 +0300 Subject: [PATCH] fixture: remove `@scopeproperty` I think the straight code is easier to understand. --- src/_pytest/fixtures.py | 47 ++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 47a7ac225..d2a08d57b 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -117,29 +117,6 @@ def pytest_sessionstart(session: "Session") -> None: scopename2class = {} # type: Dict[str, Type[nodes.Node]] -scope2props = dict(session=()) # type: Dict[str, Tuple[str, ...]] -scope2props["package"] = ("fspath",) -scope2props["module"] = ("fspath", "module") -scope2props["class"] = scope2props["module"] + ("cls",) -scope2props["instance"] = scope2props["class"] + ("instance",) -scope2props["function"] = scope2props["instance"] + ("function", "keywords") - - -def scopeproperty(name=None, doc=None): - def decoratescope(func): - scopename = name or func.__name__ - - def provide(self): - if func.__name__ in scope2props[self.scope]: - return func(self) - raise AttributeError( - "{} not available in {}-scoped context".format(scopename, self.scope) - ) - - return property(provide, None, None, func.__doc__) - - return decoratescope - def get_scope_package(node, fixturedef: "FixtureDef[object]"): import pytest @@ -484,14 +461,22 @@ class FixtureRequest: """The pytest config object associated with this request.""" return self._pyfuncitem.config # type: ignore[no-any-return] # noqa: F723 - @scopeproperty() + @property def function(self): """Test function object if the request has a per-function scope.""" + if self.scope != "function": + raise AttributeError( + "function not available in {}-scoped context".format(self.scope) + ) return self._pyfuncitem.obj - @scopeproperty("class") + @property def cls(self): """Class (can be None) where the test function was collected.""" + if self.scope not in ("class", "function"): + raise AttributeError( + "cls not available in {}-scoped context".format(self.scope) + ) clscol = self._pyfuncitem.getparent(_pytest.python.Class) if clscol: return clscol.obj @@ -506,14 +491,22 @@ class FixtureRequest: function = getattr(self, "function", None) return getattr(function, "__self__", None) - @scopeproperty() + @property def module(self): """Python module object where the test function was collected.""" + if self.scope not in ("function", "class", "module"): + raise AttributeError( + "module not available in {}-scoped context".format(self.scope) + ) return self._pyfuncitem.getparent(_pytest.python.Module).obj - @scopeproperty() + @property def fspath(self) -> py.path.local: """The file system path of the test module which collected this test.""" + if self.scope not in ("function", "class", "module", "package"): + raise AttributeError( + "module not available in {}-scoped context".format(self.scope) + ) # TODO: Remove ignore once _pyfuncitem is properly typed. return self._pyfuncitem.fspath # type: ignore