merge conftesthandle into config.py
--HG-- branch : trunk
This commit is contained in:
parent
09a9ce1da1
commit
98bdf022d3
|
@ -1,8 +1,126 @@
|
||||||
import py, os
|
import py, os
|
||||||
from py._test.conftesthandle import Conftest
|
|
||||||
from py._test.pluginmanager import PluginManager
|
from py._test.pluginmanager import PluginManager
|
||||||
from py._test import parseopt
|
from py._test import parseopt
|
||||||
|
|
||||||
|
class Conftest(object):
|
||||||
|
""" the single place for accessing values and interacting
|
||||||
|
towards conftest modules from py.test objects.
|
||||||
|
"""
|
||||||
|
def __init__(self, onimport=None, confcutdir=None):
|
||||||
|
self._path2confmods = {}
|
||||||
|
self._onimport = onimport
|
||||||
|
self._conftestpath2mod = {}
|
||||||
|
self._confcutdir = confcutdir
|
||||||
|
self._md5cache = {}
|
||||||
|
|
||||||
|
def setinitial(self, args):
|
||||||
|
""" try to find a first anchor path for looking up global values
|
||||||
|
from conftests. This function is usually called _before_
|
||||||
|
argument parsing. conftest files may add command line options
|
||||||
|
and we thus have no completely safe way of determining
|
||||||
|
which parts of the arguments are actually related to options
|
||||||
|
and which are file system paths. We just try here to get
|
||||||
|
bootstrapped ...
|
||||||
|
"""
|
||||||
|
current = py.path.local()
|
||||||
|
opt = '--confcutdir'
|
||||||
|
for i in range(len(args)):
|
||||||
|
opt1 = str(args[i])
|
||||||
|
if opt1.startswith(opt):
|
||||||
|
if opt1 == opt:
|
||||||
|
if len(args) > i:
|
||||||
|
p = current.join(args[i+1], abs=True)
|
||||||
|
elif opt1.startswith(opt + "="):
|
||||||
|
p = current.join(opt1[len(opt)+1:], abs=1)
|
||||||
|
self._confcutdir = p
|
||||||
|
break
|
||||||
|
for arg in args + [current]:
|
||||||
|
if hasattr(arg, 'startswith') and arg.startswith("--"):
|
||||||
|
continue
|
||||||
|
anchor = current.join(arg, abs=1)
|
||||||
|
if anchor.check(): # we found some file object
|
||||||
|
self._path2confmods[None] = self.getconftestmodules(anchor)
|
||||||
|
# let's also consider test* dirs
|
||||||
|
if anchor.check(dir=1):
|
||||||
|
for x in anchor.listdir("test*"):
|
||||||
|
if x.check(dir=1):
|
||||||
|
self.getconftestmodules(x)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert 0, "no root of filesystem?"
|
||||||
|
|
||||||
|
def getconftestmodules(self, path):
|
||||||
|
""" return a list of imported conftest modules for the given path. """
|
||||||
|
try:
|
||||||
|
clist = self._path2confmods[path]
|
||||||
|
except KeyError:
|
||||||
|
if path is None:
|
||||||
|
raise ValueError("missing default confest.")
|
||||||
|
dp = path.dirpath()
|
||||||
|
clist = []
|
||||||
|
if dp != path:
|
||||||
|
cutdir = self._confcutdir
|
||||||
|
if cutdir and path != cutdir and not path.relto(cutdir):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
conftestpath = path.join("conftest.py")
|
||||||
|
if conftestpath.check(file=1):
|
||||||
|
key = conftestpath.computehash()
|
||||||
|
# XXX logging about conftest loading
|
||||||
|
if key not in self._md5cache:
|
||||||
|
clist.append(self.importconftest(conftestpath))
|
||||||
|
self._md5cache[key] = conftestpath
|
||||||
|
else:
|
||||||
|
# use some kind of logging
|
||||||
|
print ("WARN: not loading %s" % conftestpath)
|
||||||
|
clist[:0] = self.getconftestmodules(dp)
|
||||||
|
self._path2confmods[path] = clist
|
||||||
|
# be defensive: avoid changes from caller side to
|
||||||
|
# affect us by always returning a copy of the actual list
|
||||||
|
return clist[:]
|
||||||
|
|
||||||
|
def rget(self, name, path=None):
|
||||||
|
mod, value = self.rget_with_confmod(name, path)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def rget_with_confmod(self, name, path=None):
|
||||||
|
modules = self.getconftestmodules(path)
|
||||||
|
modules.reverse()
|
||||||
|
for mod in modules:
|
||||||
|
try:
|
||||||
|
return mod, getattr(mod, name)
|
||||||
|
except AttributeError:
|
||||||
|
continue
|
||||||
|
raise KeyError(name)
|
||||||
|
|
||||||
|
def importconftest(self, conftestpath):
|
||||||
|
assert conftestpath.check(), conftestpath
|
||||||
|
try:
|
||||||
|
return self._conftestpath2mod[conftestpath]
|
||||||
|
except KeyError:
|
||||||
|
if not conftestpath.dirpath('__init__.py').check(file=1):
|
||||||
|
# HACK: we don't want any "globally" imported conftest.py,
|
||||||
|
# prone to conflicts and subtle problems
|
||||||
|
modname = str(conftestpath).replace('.', conftestpath.sep)
|
||||||
|
mod = conftestpath.pyimport(modname=modname)
|
||||||
|
else:
|
||||||
|
mod = conftestpath.pyimport()
|
||||||
|
self._conftestpath2mod[conftestpath] = mod
|
||||||
|
dirpath = conftestpath.dirpath()
|
||||||
|
if dirpath in self._path2confmods:
|
||||||
|
for path, mods in self._path2confmods.items():
|
||||||
|
if path and path.relto(dirpath) or path == dirpath:
|
||||||
|
assert mod not in mods
|
||||||
|
mods.append(mod)
|
||||||
|
self._postimport(mod)
|
||||||
|
return mod
|
||||||
|
|
||||||
|
def _postimport(self, mod):
|
||||||
|
if self._onimport:
|
||||||
|
self._onimport(mod)
|
||||||
|
return mod
|
||||||
|
|
||||||
|
|
||||||
def ensuretemp(string, dir=1):
|
def ensuretemp(string, dir=1):
|
||||||
""" (deprecated) return temporary directory path with
|
""" (deprecated) return temporary directory path with
|
||||||
the given string as the trailing part. It is usually
|
the given string as the trailing part. It is usually
|
||||||
|
@ -196,3 +314,5 @@ def onpytestaccess():
|
||||||
|
|
||||||
# a default per-process instance of py.test configuration
|
# a default per-process instance of py.test configuration
|
||||||
config_per_process = Config()
|
config_per_process = Config()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
import py
|
|
||||||
|
|
||||||
class Conftest(object):
|
|
||||||
""" the single place for accessing values and interacting
|
|
||||||
towards conftest modules from py.test objects.
|
|
||||||
|
|
||||||
(deprecated)
|
|
||||||
Note that triggering Conftest instances to import
|
|
||||||
conftest.py files may result in added cmdline options.
|
|
||||||
"""
|
|
||||||
def __init__(self, onimport=None, confcutdir=None):
|
|
||||||
self._path2confmods = {}
|
|
||||||
self._onimport = onimport
|
|
||||||
self._conftestpath2mod = {}
|
|
||||||
self._confcutdir = confcutdir
|
|
||||||
self._md5cache = {}
|
|
||||||
|
|
||||||
def setinitial(self, args):
|
|
||||||
""" try to find a first anchor path for looking up global values
|
|
||||||
from conftests. This function is usually called _before_
|
|
||||||
argument parsing. conftest files may add command line options
|
|
||||||
and we thus have no completely safe way of determining
|
|
||||||
which parts of the arguments are actually related to options
|
|
||||||
and which are file system paths. We just try here to get
|
|
||||||
bootstrapped ...
|
|
||||||
"""
|
|
||||||
current = py.path.local()
|
|
||||||
opt = '--confcutdir'
|
|
||||||
for i in range(len(args)):
|
|
||||||
opt1 = str(args[i])
|
|
||||||
if opt1.startswith(opt):
|
|
||||||
if opt1 == opt:
|
|
||||||
if len(args) > i:
|
|
||||||
p = current.join(args[i+1], abs=True)
|
|
||||||
elif opt1.startswith(opt + "="):
|
|
||||||
p = current.join(opt1[len(opt)+1:], abs=1)
|
|
||||||
self._confcutdir = p
|
|
||||||
break
|
|
||||||
for arg in args + [current]:
|
|
||||||
if hasattr(arg, 'startswith') and arg.startswith("--"):
|
|
||||||
continue
|
|
||||||
anchor = current.join(arg, abs=1)
|
|
||||||
if anchor.check(): # we found some file object
|
|
||||||
self._path2confmods[None] = self.getconftestmodules(anchor)
|
|
||||||
# let's also consider test* dirs
|
|
||||||
if anchor.check(dir=1):
|
|
||||||
for x in anchor.listdir("test*"):
|
|
||||||
if x.check(dir=1):
|
|
||||||
self.getconftestmodules(x)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
assert 0, "no root of filesystem?"
|
|
||||||
|
|
||||||
def getconftestmodules(self, path):
|
|
||||||
""" return a list of imported conftest modules for the given path. """
|
|
||||||
try:
|
|
||||||
clist = self._path2confmods[path]
|
|
||||||
except KeyError:
|
|
||||||
if path is None:
|
|
||||||
raise ValueError("missing default confest.")
|
|
||||||
dp = path.dirpath()
|
|
||||||
clist = []
|
|
||||||
if dp != path:
|
|
||||||
cutdir = self._confcutdir
|
|
||||||
if cutdir and path != cutdir and not path.relto(cutdir):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
conftestpath = path.join("conftest.py")
|
|
||||||
if conftestpath.check(file=1):
|
|
||||||
key = conftestpath.computehash()
|
|
||||||
# XXX logging about conftest loading
|
|
||||||
if key not in self._md5cache:
|
|
||||||
clist.append(self.importconftest(conftestpath))
|
|
||||||
self._md5cache[key] = conftestpath
|
|
||||||
else:
|
|
||||||
# use some kind of logging
|
|
||||||
print ("WARN: not loading %s" % conftestpath)
|
|
||||||
clist[:0] = self.getconftestmodules(dp)
|
|
||||||
self._path2confmods[path] = clist
|
|
||||||
# be defensive: avoid changes from caller side to
|
|
||||||
# affect us by always returning a copy of the actual list
|
|
||||||
return clist[:]
|
|
||||||
|
|
||||||
def rget(self, name, path=None):
|
|
||||||
mod, value = self.rget_with_confmod(name, path)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def rget_with_confmod(self, name, path=None):
|
|
||||||
modules = self.getconftestmodules(path)
|
|
||||||
modules.reverse()
|
|
||||||
for mod in modules:
|
|
||||||
try:
|
|
||||||
return mod, getattr(mod, name)
|
|
||||||
except AttributeError:
|
|
||||||
continue
|
|
||||||
raise KeyError(name)
|
|
||||||
|
|
||||||
def importconftest(self, conftestpath):
|
|
||||||
assert conftestpath.check(), conftestpath
|
|
||||||
try:
|
|
||||||
return self._conftestpath2mod[conftestpath]
|
|
||||||
except KeyError:
|
|
||||||
if not conftestpath.dirpath('__init__.py').check(file=1):
|
|
||||||
# HACK: we don't want any "globally" imported conftest.py,
|
|
||||||
# prone to conflicts and subtle problems
|
|
||||||
modname = str(conftestpath).replace('.', conftestpath.sep)
|
|
||||||
mod = conftestpath.pyimport(modname=modname)
|
|
||||||
else:
|
|
||||||
mod = conftestpath.pyimport()
|
|
||||||
self._conftestpath2mod[conftestpath] = mod
|
|
||||||
dirpath = conftestpath.dirpath()
|
|
||||||
if dirpath in self._path2confmods:
|
|
||||||
for path, mods in self._path2confmods.items():
|
|
||||||
if path and path.relto(dirpath) or path == dirpath:
|
|
||||||
assert mod not in mods
|
|
||||||
mods.append(mod)
|
|
||||||
self._postimport(mod)
|
|
||||||
return mod
|
|
||||||
|
|
||||||
def _postimport(self, mod):
|
|
||||||
if self._onimport:
|
|
||||||
self._onimport(mod)
|
|
||||||
return mod
|
|
|
@ -1,5 +1,5 @@
|
||||||
import py
|
import py
|
||||||
from py._test.conftesthandle import Conftest
|
from py._test.config import Conftest
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
if "basedir" in metafunc.funcargnames:
|
if "basedir" in metafunc.funcargnames:
|
Loading…
Reference in New Issue