@@ -350,11 +350,10 @@ def test_missing_fab_dependencies_are_replaced_by_mock_modules(self, find_spec):
350350
351351 def test_patched_helpers_return_the_mock_substitutes (self ):
352352 """
353- The substitutes are reached through ``wtforms.validators``, not ``sys.modules`` .
353+ Exactly one of the two ``wtforms.validators`` mocks receives the substitute .
354354
355- ``mock.patch`` resolves ``wtforms.validators.any_of`` by attribute lookup on the ``wtforms``
356- mock, which is a different object from the ``sys.modules["wtforms.validators"]`` mock that
357- ``from wtforms.validators import any_of`` would return.
355+ Different Python versions can resolve the dotted patch target to either object, so check
356+ both paths without relying on a particular resolution strategy.
358357 """
359358 captured = {}
360359
@@ -363,14 +362,17 @@ def read_patched_helpers():
363362 import wtforms
364363
365364 captured ["label" ] = flask_babel .lazy_gettext ("Some label" )
366- captured ["validator" ] = wtforms .validators .any_of (["a" , "b" ])
365+ captured ["validators" ] = [
366+ sys .modules ["wtforms.validators" ].any_of (["a" , "b" ]),
367+ wtforms .validators .any_of (["a" , "b" ]),
368+ ]
367369 return mock .MagicMock (spec = ProvidersManager )
368370
369371 self .call_without_fab_modules (find_spec_raises , read_patched_helpers )
370372
371373 assert captured ["label" ] == "Some label"
372- assert isinstance ( captured ["validator" ] , HookMetaService .MockEnum )
373- assert captured [ "validator" ] .allowed_values == ["a" , "b" ]
374+ substitutes = [ v for v in captured ["validators" ] if isinstance ( v , HookMetaService .MockEnum )]
375+ assert [ substitute .allowed_values for substitute in substitutes ] == [[ "a" , "b" ] ]
374376
375377
376378class TestHookMetaData :
0 commit comments