move the keyword/mark matching to the "legacy" module
This commit is contained in:
parent
de2de00de9
commit
cef0423b27
|
@ -2,7 +2,6 @@
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import keyword
|
|
||||||
import warnings
|
import warnings
|
||||||
import attr
|
import attr
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
@ -174,6 +173,7 @@ pytest_cmdline_main.tryfirst = True
|
||||||
|
|
||||||
|
|
||||||
def pytest_collection_modifyitems(items, config):
|
def pytest_collection_modifyitems(items, config):
|
||||||
|
from .legacy import matchkeyword, matchmark
|
||||||
keywordexpr = config.option.keyword.lstrip()
|
keywordexpr = config.option.keyword.lstrip()
|
||||||
matchexpr = config.option.markexpr
|
matchexpr = config.option.markexpr
|
||||||
if not keywordexpr and not matchexpr:
|
if not keywordexpr and not matchexpr:
|
||||||
|
@ -207,89 +207,6 @@ def pytest_collection_modifyitems(items, config):
|
||||||
items[:] = remaining
|
items[:] = remaining
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
|
||||||
class MarkMapping(object):
|
|
||||||
"""Provides a local mapping for markers where item access
|
|
||||||
resolves to True if the marker is present. """
|
|
||||||
|
|
||||||
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):
|
|
||||||
mark_names.add(key)
|
|
||||||
return cls(mark_names)
|
|
||||||
|
|
||||||
def __getitem__(self, name):
|
|
||||||
return name in self.own_mark_names
|
|
||||||
|
|
||||||
|
|
||||||
class KeywordMapping(object):
|
|
||||||
"""Provides a local mapping for keywords.
|
|
||||||
Given a list of names, map any substring of one of these names to True.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, names):
|
|
||||||
self._names = names
|
|
||||||
|
|
||||||
def __getitem__(self, subname):
|
|
||||||
for name in self._names:
|
|
||||||
if subname in name:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
python_keywords_allowed_list = ["or", "and", "not"]
|
|
||||||
|
|
||||||
|
|
||||||
def matchmark(colitem, markexpr):
|
|
||||||
"""Tries to match on any marker names, attached to the given colitem."""
|
|
||||||
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))
|
|
||||||
|
|
||||||
|
|
||||||
def matchkeyword(colitem, keywordexpr):
|
|
||||||
"""Tries to match given keyword expression to given collector item.
|
|
||||||
|
|
||||||
Will match on the name of colitem, including the names of its parents.
|
|
||||||
Only matches names of items which are either a :class:`Class` or a
|
|
||||||
:class:`Function`.
|
|
||||||
Additionally, matches on names in the 'extra_keyword_matches' set of
|
|
||||||
any item, as well as names directly assigned to test functions.
|
|
||||||
"""
|
|
||||||
mapped_names = set()
|
|
||||||
|
|
||||||
# Add the names of the current item and any parent items
|
|
||||||
import pytest
|
|
||||||
for item in colitem.listchain():
|
|
||||||
if not isinstance(item, pytest.Instance):
|
|
||||||
mapped_names.add(item.name)
|
|
||||||
|
|
||||||
# Add the names added as extra keywords to current or parent items
|
|
||||||
for name in colitem.listextrakeywords():
|
|
||||||
mapped_names.add(name)
|
|
||||||
|
|
||||||
# Add the names attached to the current function through direct assignment
|
|
||||||
if hasattr(colitem, 'function'):
|
|
||||||
for name in colitem.function.__dict__:
|
|
||||||
mapped_names.add(name)
|
|
||||||
|
|
||||||
mapping = KeywordMapping(mapped_names)
|
|
||||||
if " " not in keywordexpr:
|
|
||||||
# special case to allow for simple "-k pass" and "-k 1.3"
|
|
||||||
return mapping[keywordexpr]
|
|
||||||
elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]:
|
|
||||||
return not mapping[keywordexpr[4:]]
|
|
||||||
for kwd in keywordexpr.split():
|
|
||||||
if keyword.iskeyword(kwd) and kwd not in python_keywords_allowed_list:
|
|
||||||
raise UsageError("Python keyword '{}' not accepted in expressions passed to '-k'".format(kwd))
|
|
||||||
try:
|
|
||||||
return eval(keywordexpr, {}, mapping)
|
|
||||||
except SyntaxError:
|
|
||||||
raise UsageError("Wrong expression passed to '-k': {}".format(keywordexpr))
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
config._old_mark_config = MARK_GEN._config
|
config._old_mark_config = MARK_GEN._config
|
||||||
if config.option.strict:
|
if config.option.strict:
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
"""
|
||||||
|
this is a place where we put datastructures used by legacy apis
|
||||||
|
we hope ot remove
|
||||||
|
"""
|
||||||
|
import attr
|
||||||
|
import keyword
|
||||||
|
|
||||||
|
from . import MarkInfo, MarkDecorator
|
||||||
|
|
||||||
|
from _pytest.config import UsageError
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class MarkMapping(object):
|
||||||
|
"""Provides a local mapping for markers where item access
|
||||||
|
resolves to True if the marker is present. """
|
||||||
|
|
||||||
|
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):
|
||||||
|
mark_names.add(key)
|
||||||
|
return cls(mark_names)
|
||||||
|
|
||||||
|
def __getitem__(self, name):
|
||||||
|
return name in self.own_mark_names
|
||||||
|
|
||||||
|
|
||||||
|
class KeywordMapping(object):
|
||||||
|
"""Provides a local mapping for keywords.
|
||||||
|
Given a list of names, map any substring of one of these names to True.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, names):
|
||||||
|
self._names = names
|
||||||
|
|
||||||
|
def __getitem__(self, subname):
|
||||||
|
for name in self._names:
|
||||||
|
if subname in name:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
python_keywords_allowed_list = ["or", "and", "not"]
|
||||||
|
|
||||||
|
|
||||||
|
def matchmark(colitem, markexpr):
|
||||||
|
"""Tries to match on any marker names, attached to the given colitem."""
|
||||||
|
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))
|
||||||
|
|
||||||
|
|
||||||
|
def matchkeyword(colitem, keywordexpr):
|
||||||
|
"""Tries to match given keyword expression to given collector item.
|
||||||
|
|
||||||
|
Will match on the name of colitem, including the names of its parents.
|
||||||
|
Only matches names of items which are either a :class:`Class` or a
|
||||||
|
:class:`Function`.
|
||||||
|
Additionally, matches on names in the 'extra_keyword_matches' set of
|
||||||
|
any item, as well as names directly assigned to test functions.
|
||||||
|
"""
|
||||||
|
mapped_names = set()
|
||||||
|
|
||||||
|
# Add the names of the current item and any parent items
|
||||||
|
import pytest
|
||||||
|
for item in colitem.listchain():
|
||||||
|
if not isinstance(item, pytest.Instance):
|
||||||
|
mapped_names.add(item.name)
|
||||||
|
|
||||||
|
# Add the names added as extra keywords to current or parent items
|
||||||
|
for name in colitem.listextrakeywords():
|
||||||
|
mapped_names.add(name)
|
||||||
|
|
||||||
|
# Add the names attached to the current function through direct assignment
|
||||||
|
if hasattr(colitem, 'function'):
|
||||||
|
for name in colitem.function.__dict__:
|
||||||
|
mapped_names.add(name)
|
||||||
|
|
||||||
|
mapping = KeywordMapping(mapped_names)
|
||||||
|
if " " not in keywordexpr:
|
||||||
|
# special case to allow for simple "-k pass" and "-k 1.3"
|
||||||
|
return mapping[keywordexpr]
|
||||||
|
elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]:
|
||||||
|
return not mapping[keywordexpr[4:]]
|
||||||
|
for kwd in keywordexpr.split():
|
||||||
|
if keyword.iskeyword(kwd) and kwd not in python_keywords_allowed_list:
|
||||||
|
raise UsageError("Python keyword '{}' not accepted in expressions passed to '-k'".format(kwd))
|
||||||
|
try:
|
||||||
|
return eval(keywordexpr, {}, mapping)
|
||||||
|
except SyntaxError:
|
||||||
|
raise UsageError("Wrong expression passed to '-k': {}".format(keywordexpr))
|
Loading…
Reference in New Issue