Skip to content

Commit b130aee

Browse files
committed
Standard: Modules: Proper depth-first traversal for module reclassification.
1 parent 296d796 commit b130aee

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

sources/classcore/standard/modules.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,13 @@ def _reclassify_module(
172172
for value in attributes.values( ):
173173
if not __.inspect.ismodule( value ): continue
174174
if not value.__name__.startswith( f"{package_name}." ): continue
175+
if isinstance( value, replacement_class ): continue
175176
if recursive:
176177
_reclassify_module(
177178
value,
178179
attributes_namer = attributes_namer,
179180
recursive = True,
180181
replacement_class = replacement_class )
181-
if isinstance( value, replacement_class ): continue
182-
_seal_module( value, attributes_namer, replacement_class )
183182
if module and not isinstance( module, replacement_class ):
184183
_seal_module( module, attributes_namer, replacement_class )
185184

tests/test_000_classcore/test_350_standard_modules.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
MODULE_QNAME = f"{PACKAGE_NAME}.standard.modules"
3030

3131

32-
def test_200_reclassification_of_package_module( ):
33-
''' Reclassifies package module directly. '''
32+
def test_200_reclassification_of_independent_module( ):
33+
''' Reclassifies independent module directly. '''
3434
module = cache_import_module( MODULE_QNAME )
3535
exceptions_module = cache_import_module( f"{PACKAGE_NAME}.exceptions" )
3636
module_class = module.Module
@@ -65,7 +65,50 @@ def test_201_reclassification_of_normal_module( ):
6565
module.foo = 1
6666

6767

68-
def test_202_reclassification_of_incomplete_module( ):
68+
def test_202_reclassification_of_package( ):
69+
''' Reclassifies package directly. '''
70+
module = cache_import_module( MODULE_QNAME )
71+
exceptions_module = cache_import_module( f"{PACKAGE_NAME}.exceptions" )
72+
module_class = module.Module
73+
package_module = types.ModuleType( 'foobarnotreal' )
74+
package_module.__package__ = 'foobarnotreal'
75+
member_module = types.ModuleType( 'foobarnotreal.member' )
76+
member_module.__package__ = 'foobarnotreal'
77+
package_module.member = member_module
78+
assert package_module.__class__ is not module_class
79+
assert member_module.__class__ is not module_class
80+
with warnings.catch_warnings( ):
81+
warnings.simplefilter( 'ignore', DeprecationWarning )
82+
module.reclassify_modules( package_module )
83+
assert package_module.__class__ is module_class
84+
module.reclassify_modules( package_module ) # idempotence
85+
assert package_module.__class__ is module_class
86+
with pytest.raises( exceptions_module.AttributeImmutability ):
87+
module.foo = 1
88+
89+
90+
def test_203_reclassification_of_package_recursive( ):
91+
''' Reclassifies package recursively. '''
92+
module = cache_import_module( MODULE_QNAME )
93+
exceptions_module = cache_import_module( f"{PACKAGE_NAME}.exceptions" )
94+
module_class = module.Module
95+
package_module = types.ModuleType( 'foobarnotreal' )
96+
package_module.__package__ = 'foobarnotreal'
97+
member_module = types.ModuleType( 'foobarnotreal.member' )
98+
member_module.__package__ = 'foobarnotreal'
99+
package_module.member = member_module
100+
assert package_module.__class__ is not module_class
101+
assert member_module.__class__ is not module_class
102+
with warnings.catch_warnings( ):
103+
warnings.simplefilter( 'ignore', DeprecationWarning )
104+
module.reclassify_modules( package_module, recursive = True )
105+
assert package_module.__class__ is module_class
106+
assert member_module.__class__ is module_class
107+
with pytest.raises( exceptions_module.AttributeImmutability ):
108+
module.foo = 1
109+
110+
111+
def test_204_reclassification_of_incomplete_module( ):
69112
''' Reclassification ignores incomplete module. '''
70113
module = cache_import_module( MODULE_QNAME )
71114
module_class = module.Module
@@ -89,9 +132,9 @@ def test_205_reclassification_via_module_globals( ):
89132
assert module_.__class__ is not module_class
90133
with warnings.catch_warnings( ):
91134
warnings.simplefilter( 'ignore', DeprecationWarning )
92-
module.reclassify_modules( module_dict )
135+
module.reclassify_modules( module_dict, recursive = True )
93136
assert module_.__class__ is module_class
94-
module.reclassify_modules( module_dict ) # idempotence
137+
module.reclassify_modules( module_dict, recursive = True ) # idempotent
95138
assert module_.__class__ is module_class
96139
with pytest.raises( exceptions_module.AttributeImmutability ):
97140
module.foo = 1

0 commit comments

Comments
 (0)