Skip to content

Commit

Permalink
Merge babe63a into 083084f
Browse files Browse the repository at this point in the history
  • Loading branch information
RonnyPfannschmidt committed Oct 24, 2017
2 parents 083084f + babe63a commit a5434ea
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 29 deletions.
23 changes: 16 additions & 7 deletions _pytest/fixtures.py
Expand Up @@ -7,6 +7,7 @@
import warnings

import inspect
import attr
import _pytest
from _pytest._code.code import TerminalRepr
from _pytest.compat import (
Expand Down Expand Up @@ -820,13 +821,21 @@ def pytest_fixture_setup(fixturedef, request):
return result


class FixtureFunctionMarker:
def __init__(self, scope, params, autouse=False, ids=None, name=None):
self.scope = scope
self.params = params
self.autouse = autouse
self.ids = ids
self.name = name
def _ensure_immutable_ids(ids):
if ids is None:
return
if callable(ids):
return ids
return tuple(ids)


@attr.s(frozen=True)
class FixtureFunctionMarker(object):
scope = attr.ib()
params = attr.ib(convert=attr.converters.optional(tuple))
autouse = attr.ib(default=False)
ids = attr.ib(default=None, convert=_ensure_immutable_ids)
name = attr.ib(default=None)

def __call__(self, function):
if isclass(function):
Expand Down
50 changes: 29 additions & 21 deletions _pytest/mark.py
Expand Up @@ -3,6 +3,7 @@

import inspect
import warnings
import attr
from collections import namedtuple
from operator import attrgetter
from .compat import imap
Expand Down Expand Up @@ -160,22 +161,26 @@ def pytest_collection_modifyitems(items, config):
items[:] = remaining


class MarkMapping:
@attr.s
class MarkMapping(object):
"""Provides a local mapping for markers where item access
resolves to True if the marker is present. """

def __init__(self, keywords):
mymarks = set()
own_mark_names = attr.ib()

@classmethod
def from_keywords(cls, keywords):
mark_names = set()
for key, value in keywords.items():
if isinstance(value, MarkInfo) or isinstance(value, MarkDecorator):
mymarks.add(key)
self._mymarks = mymarks
mark_names.add(key)
return cls(mark_names)

def __getitem__(self, name):
return name in self._mymarks
return name in self.own_mark_names


class KeywordMapping:
class KeywordMapping(object):
"""Provides a local mapping for keywords.
Given a list of names, map any substring of one of these names to True.
"""
Expand All @@ -192,7 +197,7 @@ def __getitem__(self, subname):

def matchmark(colitem, markexpr):
"""Tries to match on any marker names, attached to the given colitem."""
return eval(markexpr, {}, MarkMapping(colitem.keywords))
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))


def matchkeyword(colitem, keywordexpr):
Expand Down Expand Up @@ -280,7 +285,21 @@ def istestfunc(func):
getattr(func, "__name__", "<lambda>") != "<lambda>"


class MarkDecorator:
@attr.s(frozen=True)
class Mark(object):
name = attr.ib()
args = attr.ib()
kwargs = attr.ib()

def combined_with(self, other):
assert self.name == other.name
return Mark(
self.name, self.args + other.args,
dict(self.kwargs, **other.kwargs))


@attr.s
class MarkDecorator(object):
""" A decorator for test functions and test classes. When applied
it will create :class:`MarkInfo` objects which may be
:ref:`retrieved by hooks as item keywords <excontrolskip>`.
Expand Down Expand Up @@ -314,9 +333,7 @@ def test_function():
"""

def __init__(self, mark):
assert isinstance(mark, Mark), repr(mark)
self.mark = mark
mark = attr.ib(validator=attr.validators.instance_of(Mark))

name = alias('mark.name')
args = alias('mark.args')
Expand Down Expand Up @@ -396,15 +413,6 @@ def store_legacy_markinfo(func, mark):
holder.add_mark(mark)


class Mark(namedtuple('Mark', 'name, args, kwargs')):

def combined_with(self, other):
assert self.name == other.name
return Mark(
self.name, self.args + other.args,
dict(self.kwargs, **other.kwargs))


class MarkInfo(object):
""" Marking object created by :class:`MarkDecorator` instances. """

Expand Down
7 changes: 6 additions & 1 deletion setup.py
Expand Up @@ -43,8 +43,13 @@ def has_environment_marker_support():


def main():
install_requires = ['py>=1.4.34', 'six>=1.10.0', 'setuptools']
extras_require = {}
install_requires = [
'py>=1.4.33',
'six>=1.10.0',
'setuptools',
'attrs>=17.2.0',
]
# if _PYTEST_SETUP_SKIP_PLUGGY_DEP is set, skip installing pluggy;
# used by tox.ini to test with pluggy master
if '_PYTEST_SETUP_SKIP_PLUGGY_DEP' not in os.environ:
Expand Down

0 comments on commit a5434ea

Please sign in to comment.