1111import sys
1212import tempfile
1313import unittest
14- import warnings
1514
1615import pytest
1716import _pytest .doctest
@@ -108,7 +107,15 @@ def __init__(self, stub=None, **attrs):
108107
109108 attrs .setdefault ("user_properties" , [])
110109
111- self .__dict__ .update (attrs )
110+ slots = getattr (type (self ), "__slots__" , None )
111+ if slots :
112+ for name , value in attrs .items ():
113+ if name in self .__slots__ :
114+ setattr (self , name , value )
115+ else :
116+ self .__dict__ [name ] = value
117+ else :
118+ self .__dict__ .update (attrs )
112119
113120 if "own_markers" not in attrs :
114121 self .own_markers = ()
@@ -130,6 +137,14 @@ def func(*args, **kwargs):
130137
131138
132139class StubSubtypedItem (StubPytestItem ):
140+ @classmethod
141+ def from_args (cls , * args , ** kwargs ):
142+ if not hasattr (cls , "from_parent" ):
143+ return cls (* args , ** kwargs )
144+ self = cls .from_parent (None , name = kwargs ["name" ], runner = None , dtest = None )
145+ self .__init__ (* args , ** kwargs )
146+ return self
147+
133148 def __init__ (self , * args , ** kwargs ):
134149 super (StubSubtypedItem , self ).__init__ (* args , ** kwargs )
135150 if "nodeid" in self .__dict__ :
@@ -147,27 +162,15 @@ def function(self):
147162
148163
149164def create_stub_function_item (* args , ** kwargs ):
150- # StubFunctionItem should not be calling __init__(), but instead from_parent().
151- # Unfortunately the detangling is massive due to the complexity of the test
152- # harness, so we are punting in hopes that we rewrite test discovery before
153- # pytest removes this functionality.
154- with warnings .catch_warnings ():
155- warnings .simplefilter ("ignore" )
156- return StubFunctionItem (* args , ** kwargs )
165+ return StubFunctionItem .from_args (* args , ** kwargs )
157166
158167
159168class StubDoctestItem (StubSubtypedItem , _pytest .doctest .DoctestItem ):
160169 pass
161170
162171
163172def create_stub_doctest_item (* args , ** kwargs ):
164- # StubDoctestItem should not be calling __init__(), but instead from_parent().
165- # Unfortunately the detangling is massive due to the complexity of the test
166- # harness, so we are punting in hopes that we rewrite test discovery before
167- # pytest removes this functionality.
168- with warnings .catch_warnings ():
169- warnings .simplefilter ("ignore" )
170- return StubDoctestItem (* args , ** kwargs )
173+ return StubDoctestItem .from_args (* args , ** kwargs )
171174
172175
173176class StubPytestSession (util .StubProxy ):
@@ -210,6 +213,7 @@ def _fix_fileid(*args):
210213 return adapter_util .fix_fileid (
211214 * args ,
212215 ** dict (
216+ # dependency injection
213217 _normcase = normcase ,
214218 _pathsep = pathsep ,
215219 )
@@ -219,6 +223,7 @@ def _normalize_test_id(*args):
219223 return pytest_item ._normalize_test_id (
220224 * args ,
221225 ** dict (
226+ # dependency injection
222227 _fix_fileid = _fix_fileid ,
223228 _pathsep = pathsep ,
224229 )
@@ -228,6 +233,7 @@ def _iter_nodes(*args):
228233 return pytest_item ._iter_nodes (
229234 * args ,
230235 ** dict (
236+ # dependency injection
231237 _normalize_test_id = _normalize_test_id ,
232238 _normcase = normcase ,
233239 _pathsep = pathsep ,
@@ -238,6 +244,7 @@ def _parse_node_id(*args):
238244 return pytest_item ._parse_node_id (
239245 * args ,
240246 ** dict (
247+ # dependency injection
241248 _iter_nodes = _iter_nodes ,
242249 )
243250 )
@@ -247,6 +254,7 @@ def _split_fspath(*args):
247254 return pytest_item ._split_fspath (
248255 * args ,
249256 ** dict (
257+ # dependency injection
250258 _normcase = normcase ,
251259 )
252260 )
@@ -256,6 +264,7 @@ def _matches_relfile(*args):
256264 return pytest_item ._matches_relfile (
257265 * args ,
258266 ** dict (
267+ # dependency injection
259268 _normcase = normcase ,
260269 _pathsep = pathsep ,
261270 )
@@ -265,6 +274,7 @@ def _is_legacy_wrapper(*args):
265274 return pytest_item ._is_legacy_wrapper (
266275 * args ,
267276 ** dict (
277+ # dependency injection
268278 _pathsep = pathsep ,
269279 )
270280 )
@@ -273,6 +283,7 @@ def _get_location(*args):
273283 return pytest_item ._get_location (
274284 * args ,
275285 ** dict (
286+ # dependency injection
276287 _matches_relfile = _matches_relfile ,
277288 _is_legacy_wrapper = _is_legacy_wrapper ,
278289 _pathsep = pathsep ,
@@ -284,6 +295,7 @@ def _parse_item(item):
284295 return pytest_item .parse_item (
285296 item ,
286297 ** dict (
298+ # dependency injection
287299 _parse_node_id = _parse_node_id ,
288300 _split_fspath = _split_fspath ,
289301 _get_location = _get_location ,
@@ -352,6 +364,7 @@ def test_failure(self):
352364 self .assertEqual (
353365 stub .calls ,
354366 [
367+ # There's only one call.
355368 ("pytest.main" , None , {"args" : self .DEFAULT_ARGS , "plugins" : [plugin ]}),
356369 ],
357370 )
0 commit comments