Skip to content

Commit 6f68dfc

Browse files
authored
Merge pull request #1710 from RonnyPfannschmidt/fixture-split
Fixture split 2nd attempt
2 parents 7a2058e + 8c49561 commit 6f68dfc

File tree

9 files changed

+1348
-1271
lines changed

9 files changed

+1348
-1271
lines changed

_pytest/compat.py

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
"""
2+
python version compatibility code
3+
"""
4+
import sys
5+
import inspect
6+
import types
7+
import re
8+
import functools
9+
10+
import py
11+
12+
import _pytest
13+
14+
15+
16+
try:
17+
import enum
18+
except ImportError: # pragma: no cover
19+
# Only available in Python 3.4+ or as a backport
20+
enum = None
21+
22+
_PY3 = sys.version_info > (3, 0)
23+
_PY2 = not _PY3
24+
25+
26+
NoneType = type(None)
27+
NOTSET = object()
28+
29+
if hasattr(inspect, 'signature'):
30+
def _format_args(func):
31+
return str(inspect.signature(func))
32+
else:
33+
def _format_args(func):
34+
return inspect.formatargspec(*inspect.getargspec(func))
35+
36+
isfunction = inspect.isfunction
37+
isclass = inspect.isclass
38+
# used to work around a python2 exception info leak
39+
exc_clear = getattr(sys, 'exc_clear', lambda: None)
40+
# The type of re.compile objects is not exposed in Python.
41+
REGEX_TYPE = type(re.compile(''))
42+
43+
44+
def is_generator(func):
45+
try:
46+
return _pytest._code.getrawcode(func).co_flags & 32 # generator function
47+
except AttributeError: # builtin functions have no bytecode
48+
# assume them to not be generators
49+
return False
50+
51+
52+
def getlocation(function, curdir):
53+
import inspect
54+
fn = py.path.local(inspect.getfile(function))
55+
lineno = py.builtin._getcode(function).co_firstlineno
56+
if fn.relto(curdir):
57+
fn = fn.relto(curdir)
58+
return "%s:%d" %(fn, lineno+1)
59+
60+
61+
def num_mock_patch_args(function):
62+
""" return number of arguments used up by mock arguments (if any) """
63+
patchings = getattr(function, "patchings", None)
64+
if not patchings:
65+
return 0
66+
mock = sys.modules.get("mock", sys.modules.get("unittest.mock", None))
67+
if mock is not None:
68+
return len([p for p in patchings
69+
if not p.attribute_name and p.new is mock.DEFAULT])
70+
return len(patchings)
71+
72+
73+
def getfuncargnames(function, startindex=None):
74+
# XXX merge with main.py's varnames
75+
#assert not isclass(function)
76+
realfunction = function
77+
while hasattr(realfunction, "__wrapped__"):
78+
realfunction = realfunction.__wrapped__
79+
if startindex is None:
80+
startindex = inspect.ismethod(function) and 1 or 0
81+
if realfunction != function:
82+
startindex += num_mock_patch_args(function)
83+
function = realfunction
84+
if isinstance(function, functools.partial):
85+
argnames = inspect.getargs(_pytest._code.getrawcode(function.func))[0]
86+
partial = function
87+
argnames = argnames[len(partial.args):]
88+
if partial.keywords:
89+
for kw in partial.keywords:
90+
argnames.remove(kw)
91+
else:
92+
argnames = inspect.getargs(_pytest._code.getrawcode(function))[0]
93+
defaults = getattr(function, 'func_defaults',
94+
getattr(function, '__defaults__', None)) or ()
95+
numdefaults = len(defaults)
96+
if numdefaults:
97+
return tuple(argnames[startindex:-numdefaults])
98+
return tuple(argnames[startindex:])
99+
100+
101+
102+
if sys.version_info[:2] == (2, 6):
103+
def isclass(object):
104+
""" Return true if the object is a class. Overrides inspect.isclass for
105+
python 2.6 because it will return True for objects which always return
106+
something on __getattr__ calls (see #1035).
107+
Backport of https://hg.python.org/cpython/rev/35bf8f7a8edc
108+
"""
109+
return isinstance(object, (type, types.ClassType))
110+
111+
112+
if _PY3:
113+
import codecs
114+
115+
STRING_TYPES = bytes, str
116+
117+
def _escape_strings(val):
118+
"""If val is pure ascii, returns it as a str(). Otherwise, escapes
119+
bytes objects into a sequence of escaped bytes:
120+
121+
b'\xc3\xb4\xc5\xd6' -> u'\\xc3\\xb4\\xc5\\xd6'
122+
123+
and escapes unicode objects into a sequence of escaped unicode
124+
ids, e.g.:
125+
126+
'4\\nV\\U00043efa\\x0eMXWB\\x1e\\u3028\\u15fd\\xcd\\U0007d944'
127+
128+
note:
129+
the obvious "v.decode('unicode-escape')" will return
130+
valid utf-8 unicode if it finds them in bytes, but we
131+
want to return escaped bytes for any byte, even if they match
132+
a utf-8 string.
133+
134+
"""
135+
if isinstance(val, bytes):
136+
if val:
137+
# source: http://goo.gl/bGsnwC
138+
encoded_bytes, _ = codecs.escape_encode(val)
139+
return encoded_bytes.decode('ascii')
140+
else:
141+
# empty bytes crashes codecs.escape_encode (#1087)
142+
return ''
143+
else:
144+
return val.encode('unicode_escape').decode('ascii')
145+
else:
146+
STRING_TYPES = bytes, str, unicode
147+
148+
def _escape_strings(val):
149+
"""In py2 bytes and str are the same type, so return if it's a bytes
150+
object, return it unchanged if it is a full ascii string,
151+
otherwise escape it into its binary form.
152+
153+
If it's a unicode string, change the unicode characters into
154+
unicode escapes.
155+
156+
"""
157+
if isinstance(val, bytes):
158+
try:
159+
return val.encode('ascii')
160+
except UnicodeDecodeError:
161+
return val.encode('string-escape')
162+
else:
163+
return val.encode('unicode-escape')
164+
165+
166+
def get_real_func(obj):
167+
""" gets the real function object of the (possibly) wrapped object by
168+
functools.wraps or functools.partial.
169+
"""
170+
while hasattr(obj, "__wrapped__"):
171+
obj = obj.__wrapped__
172+
if isinstance(obj, functools.partial):
173+
obj = obj.func
174+
return obj
175+
176+
def getfslineno(obj):
177+
# xxx let decorators etc specify a sane ordering
178+
obj = get_real_func(obj)
179+
if hasattr(obj, 'place_as'):
180+
obj = obj.place_as
181+
fslineno = _pytest._code.getfslineno(obj)
182+
assert isinstance(fslineno[1], int), obj
183+
return fslineno
184+
185+
def getimfunc(func):
186+
try:
187+
return func.__func__
188+
except AttributeError:
189+
try:
190+
return func.im_func
191+
except AttributeError:
192+
return func
193+
194+
def safe_getattr(object, name, default):
195+
""" Like getattr but return default upon any Exception.
196+
197+
Attribute access can potentially fail for 'evil' Python objects.
198+
See issue214
199+
"""
200+
try:
201+
return getattr(object, name, default)
202+
except Exception:
203+
return default

_pytest/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class UsageError(Exception):
6363
_preinit = []
6464

6565
default_plugins = (
66-
"mark main terminal runner python debugging unittest capture skipping "
66+
"mark main terminal runner python fixtures debugging unittest capture skipping "
6767
"tmpdir monkeypatch recwarn pastebin helpconfig nose assertion "
6868
"junitxml resultlog doctest cacheprovider freeze_support "
6969
"setuponly setupplan").split()

_pytest/doctest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import pytest
77
from _pytest._code.code import TerminalRepr, ReprFileLocation, ExceptionInfo
8-
from _pytest.python import FixtureRequest
8+
from _pytest.fixtures import FixtureRequest
99

1010

1111

0 commit comments

Comments
 (0)