3
3
import errno
4
4
import glob
5
5
import importlib .util
6
+ import inspect
6
7
from importlib ._bootstrap_external import _get_sourcefile
7
8
import marshal
8
9
import os
26
27
temp_dir , DirsOnSysPath )
27
28
from test .support import script_helper
28
29
from test .test_importlib .util import uncache
29
-
30
+ from types import ModuleType
30
31
31
32
skip_if_dont_write_bytecode = unittest .skipIf (
32
33
sys .dont_write_bytecode ,
@@ -49,6 +50,8 @@ def _ready_to_import(name=None, source=""):
49
50
# reverts or removes the module when cleaning up
50
51
name = name or "spam"
51
52
with temp_dir () as tempdir :
53
+ if os .sep in name :
54
+ os .makedirs (os .path .join (tempdir , name .rpartition (os .sep )[0 ]))
52
55
path = script_helper .make_script (tempdir , name , source )
53
56
old_module = sys .modules .pop (name , None )
54
57
try :
@@ -1339,6 +1342,39 @@ def test_circular_from_import(self):
1339
1342
str (cm .exception ),
1340
1343
)
1341
1344
1345
+ def test_unwritable_module (self ):
1346
+ package = inspect .cleandoc ('''
1347
+ import sys
1348
+
1349
+ class MyMod(object):
1350
+ __slots__ = ['__builtins__', '__cached__', '__doc__',
1351
+ '__file__', '__loader__', '__name__',
1352
+ '__package__', '__path__', '__spec__']
1353
+ def __init__(self):
1354
+ for attr in self.__slots__:
1355
+ setattr(self, attr, globals()[attr])
1356
+
1357
+
1358
+ sys.modules['spam'] = MyMod()
1359
+ ''' )
1360
+
1361
+ init = os .path .join ('spam' , '__init__' )
1362
+ with _ready_to_import (init , package ) as (name , path ):
1363
+ with open (os .path .join (os .path .dirname (path ), 'x.py' ), 'w+' ):
1364
+ pass
1365
+
1366
+ try :
1367
+ import spam
1368
+ with self .assertWarns (ImportWarning ):
1369
+ from spam import x
1370
+
1371
+ self .assertNotEqual (type (spam ), ModuleType )
1372
+ self .assertEqual (type (x ), ModuleType )
1373
+ with self .assertRaises (AttributeError ):
1374
+ spam .x = 42
1375
+ finally :
1376
+ del sys .modules ['spam.x' ]
1377
+
1342
1378
1343
1379
if __name__ == '__main__' :
1344
1380
# Test needs to be a package, so we can do relative imports.
0 commit comments