@@ -1652,26 +1652,44 @@ def pipe(self):
1652
1652
os .set_blocking (r , False )
1653
1653
return (r , w )
1654
1654
1655
- def import_script (self , name , fd , check_override = None ):
1655
+ def import_script (self , name , fd , filename = None , check_override = None ):
1656
1656
override_text = ''
1657
1657
if check_override is not None :
1658
1658
override_text = f'''
1659
- import _imp
1660
- _imp._override_multi_interp_extensions_check({ check_override } )
1661
- '''
1662
- return textwrap .dedent (f'''
1663
- import os, sys
1664
- { override_text }
1665
- try:
1666
- import { name }
1667
- except ImportError as exc:
1668
- text = 'ImportError: ' + str(exc)
1669
- else:
1670
- text = 'okay'
1671
- os.write({ fd } , text.encode('utf-8'))
1672
- ''' )
1659
+ import _imp
1660
+ _imp._override_multi_interp_extensions_check({ check_override } )
1661
+ '''
1662
+ if filename :
1663
+ return textwrap .dedent (f'''
1664
+ from importlib.util import spec_from_loader, module_from_spec
1665
+ from importlib.machinery import ExtensionFileLoader
1666
+ import os, sys
1667
+ { override_text }
1668
+ loader = ExtensionFileLoader({ name !r} , { filename !r} )
1669
+ spec = spec_from_loader({ name !r} , loader)
1670
+ try:
1671
+ module = module_from_spec(spec)
1672
+ loader.exec_module(module)
1673
+ except ImportError as exc:
1674
+ text = 'ImportError: ' + str(exc)
1675
+ else:
1676
+ text = 'okay'
1677
+ os.write({ fd } , text.encode('utf-8'))
1678
+ ''' )
1679
+ else :
1680
+ return textwrap .dedent (f'''
1681
+ import os, sys
1682
+ { override_text }
1683
+ try:
1684
+ import { name }
1685
+ except ImportError as exc:
1686
+ text = 'ImportError: ' + str(exc)
1687
+ else:
1688
+ text = 'okay'
1689
+ os.write({ fd } , text.encode('utf-8'))
1690
+ ''' )
1673
1691
1674
- def run_here (self , name , * ,
1692
+ def run_here (self , name , filename = None , * ,
1675
1693
check_singlephase_setting = False ,
1676
1694
check_singlephase_override = None ,
1677
1695
isolated = False ,
@@ -1700,26 +1718,30 @@ def run_here(self, name, *,
1700
1718
)
1701
1719
1702
1720
r , w = self .pipe ()
1703
- script = self .import_script (name , w , check_singlephase_override )
1721
+ script = self .import_script (name , w , filename ,
1722
+ check_singlephase_override )
1704
1723
1705
1724
ret = run_in_subinterp_with_config (script , ** kwargs )
1706
1725
self .assertEqual (ret , 0 )
1707
1726
return os .read (r , 100 )
1708
1727
1709
- def check_compatible_here (self , name , * , strict = False , isolated = False ):
1728
+ def check_compatible_here (self , name , filename = None , * ,
1729
+ strict = False ,
1730
+ isolated = False ,
1731
+ ):
1710
1732
# Verify that the named module may be imported in a subinterpreter.
1711
1733
# (See run_here() for more info.)
1712
- out = self .run_here (name ,
1734
+ out = self .run_here (name , filename ,
1713
1735
check_singlephase_setting = strict ,
1714
1736
isolated = isolated ,
1715
1737
)
1716
1738
self .assertEqual (out , b'okay' )
1717
1739
1718
- def check_incompatible_here (self , name , * , isolated = False ):
1740
+ def check_incompatible_here (self , name , filename = None , * , isolated = False ):
1719
1741
# Differences from check_compatible_here():
1720
1742
# * verify that import fails
1721
1743
# * "strict" is always True
1722
- out = self .run_here (name ,
1744
+ out = self .run_here (name , filename ,
1723
1745
check_singlephase_setting = True ,
1724
1746
isolated = isolated ,
1725
1747
)
@@ -1820,6 +1842,24 @@ def test_multi_init_extension_compat(self):
1820
1842
with self .subTest (f'{ module } : strict, fresh' ):
1821
1843
self .check_compatible_fresh (module , strict = True )
1822
1844
1845
+ @unittest .skipIf (_testmultiphase is None , "test requires _testmultiphase module" )
1846
+ def test_multi_init_extension_non_isolated_compat (self ):
1847
+ modname = '_test_non_isolated'
1848
+ filename = _testmultiphase .__file__
1849
+ loader = ExtensionFileLoader (modname , filename )
1850
+ spec = importlib .util .spec_from_loader (modname , loader )
1851
+ module = importlib .util .module_from_spec (spec )
1852
+ loader .exec_module (module )
1853
+ sys .modules [modname ] = module
1854
+
1855
+ require_extension (module )
1856
+ with self .subTest (f'{ modname } : isolated' ):
1857
+ self .check_incompatible_here (modname , filename , isolated = True )
1858
+ with self .subTest (f'{ modname } : not isolated' ):
1859
+ self .check_incompatible_here (modname , filename , isolated = False )
1860
+ with self .subTest (f'{ modname } : not strict' ):
1861
+ self .check_compatible_here (modname , filename , strict = False )
1862
+
1823
1863
def test_python_compat (self ):
1824
1864
module = 'threading'
1825
1865
require_pure_python (module )
0 commit comments