|
14 | 14 | getfslineno, get_real_func, |
15 | 15 | is_generator, isclass, getimfunc, |
16 | 16 | getlocation, getfuncargnames, |
| 17 | + safe_getattr, |
17 | 18 | ) |
18 | 19 |
|
19 | 20 | def pytest_sessionstart(session): |
@@ -124,8 +125,6 @@ def getfixturemarker(obj): |
124 | 125 | exceptions.""" |
125 | 126 | try: |
126 | 127 | return getattr(obj, "_pytestfixturefunction", None) |
127 | | - except KeyboardInterrupt: |
128 | | - raise |
129 | 128 | except Exception: |
130 | 129 | # some objects raise errors like request (from flask import request) |
131 | 130 | # we don't expect them to be fixture functions |
@@ -1068,7 +1067,9 @@ def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False): |
1068 | 1067 | self._holderobjseen.add(holderobj) |
1069 | 1068 | autousenames = [] |
1070 | 1069 | for name in dir(holderobj): |
1071 | | - obj = getattr(holderobj, name, None) |
| 1070 | + # The attribute can be an arbitrary descriptor, so the attribute |
| 1071 | + # access below can raise. safe_getatt() ignores such exceptions. |
| 1072 | + obj = safe_getattr(holderobj, name, None) |
1072 | 1073 | # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style) |
1073 | 1074 | # or are "@pytest.fixture" marked |
1074 | 1075 | marker = getfixturemarker(obj) |
|
0 commit comments