Implement PEP 366
This commit is contained in:
parent
f19b951126
commit
ef01d822aa
20
Lib/runpy.py
20
Lib/runpy.py
|
@ -23,19 +23,20 @@ __all__ = [
|
||||||
|
|
||||||
def _run_code(code, run_globals, init_globals=None,
|
def _run_code(code, run_globals, init_globals=None,
|
||||||
mod_name=None, mod_fname=None,
|
mod_name=None, mod_fname=None,
|
||||||
mod_loader=None):
|
mod_loader=None, pkg_name=None):
|
||||||
"""Helper for _run_module_code"""
|
"""Helper for _run_module_code"""
|
||||||
if init_globals is not None:
|
if init_globals is not None:
|
||||||
run_globals.update(init_globals)
|
run_globals.update(init_globals)
|
||||||
run_globals.update(__name__ = mod_name,
|
run_globals.update(__name__ = mod_name,
|
||||||
__file__ = mod_fname,
|
__file__ = mod_fname,
|
||||||
__loader__ = mod_loader)
|
__loader__ = mod_loader,
|
||||||
|
__package__ = pkg_name)
|
||||||
exec code in run_globals
|
exec code in run_globals
|
||||||
return run_globals
|
return run_globals
|
||||||
|
|
||||||
def _run_module_code(code, init_globals=None,
|
def _run_module_code(code, init_globals=None,
|
||||||
mod_name=None, mod_fname=None,
|
mod_name=None, mod_fname=None,
|
||||||
mod_loader=None):
|
mod_loader=None, pkg_name=None):
|
||||||
"""Helper for run_module"""
|
"""Helper for run_module"""
|
||||||
# Set up the top level namespace dictionary
|
# Set up the top level namespace dictionary
|
||||||
temp_module = imp.new_module(mod_name)
|
temp_module = imp.new_module(mod_name)
|
||||||
|
@ -49,7 +50,8 @@ def _run_module_code(code, init_globals=None,
|
||||||
sys.modules[mod_name] = temp_module
|
sys.modules[mod_name] = temp_module
|
||||||
try:
|
try:
|
||||||
_run_code(code, mod_globals, init_globals,
|
_run_code(code, mod_globals, init_globals,
|
||||||
mod_name, mod_fname, mod_loader)
|
mod_name, mod_fname,
|
||||||
|
mod_loader, pkg_name)
|
||||||
finally:
|
finally:
|
||||||
sys.argv[0] = saved_argv0
|
sys.argv[0] = saved_argv0
|
||||||
if restore_module:
|
if restore_module:
|
||||||
|
@ -95,11 +97,12 @@ def _run_module_as_main(mod_name, set_argv0=True):
|
||||||
__loader__
|
__loader__
|
||||||
"""
|
"""
|
||||||
loader, code, fname = _get_module_details(mod_name)
|
loader, code, fname = _get_module_details(mod_name)
|
||||||
|
pkg_name = mod_name.rpartition('.')[0]
|
||||||
main_globals = sys.modules["__main__"].__dict__
|
main_globals = sys.modules["__main__"].__dict__
|
||||||
if set_argv0:
|
if set_argv0:
|
||||||
sys.argv[0] = fname
|
sys.argv[0] = fname
|
||||||
return _run_code(code, main_globals, None,
|
return _run_code(code, main_globals, None,
|
||||||
"__main__", fname, loader)
|
"__main__", fname, loader, pkg_name)
|
||||||
|
|
||||||
def run_module(mod_name, init_globals=None,
|
def run_module(mod_name, init_globals=None,
|
||||||
run_name=None, alter_sys=False):
|
run_name=None, alter_sys=False):
|
||||||
|
@ -110,13 +113,14 @@ def run_module(mod_name, init_globals=None,
|
||||||
loader, code, fname = _get_module_details(mod_name)
|
loader, code, fname = _get_module_details(mod_name)
|
||||||
if run_name is None:
|
if run_name is None:
|
||||||
run_name = mod_name
|
run_name = mod_name
|
||||||
|
pkg_name = mod_name.rpartition('.')[0]
|
||||||
if alter_sys:
|
if alter_sys:
|
||||||
return _run_module_code(code, init_globals, run_name,
|
return _run_module_code(code, init_globals, run_name,
|
||||||
fname, loader)
|
fname, loader, pkg_name)
|
||||||
else:
|
else:
|
||||||
# Leave the sys module alone
|
# Leave the sys module alone
|
||||||
return _run_code(code, {}, init_globals,
|
return _run_code(code, {}, init_globals, run_name,
|
||||||
run_name, fname, loader)
|
fname, loader, pkg_name)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -35,15 +35,15 @@ def temp_dir():
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(dirname)
|
shutil.rmtree(dirname)
|
||||||
|
|
||||||
test_source = ("""\
|
test_source = """\
|
||||||
# Script may be run with optimisation enabled, so don't rely on assert
|
# Script may be run with optimisation enabled, so don't rely on assert
|
||||||
# statements being executed
|
# statements being executed
|
||||||
def assertEqual(lhs, rhs):
|
def assertEqual(lhs, rhs):
|
||||||
if lhs != rhs:
|
if lhs != rhs:
|
||||||
raise AssertionError("%r != %r" % (lhs, rhs))
|
raise AssertionError('%r != %r' % (lhs, rhs))
|
||||||
def assertIdentical(lhs, rhs):
|
def assertIdentical(lhs, rhs):
|
||||||
if lhs is not rhs:
|
if lhs is not rhs:
|
||||||
raise AssertionError("%r is not %r" % (lhs, rhs))
|
raise AssertionError('%r is not %r' % (lhs, rhs))
|
||||||
# Check basic code execution
|
# Check basic code execution
|
||||||
result = ['Top level assignment']
|
result = ['Top level assignment']
|
||||||
def f():
|
def f():
|
||||||
|
@ -53,17 +53,18 @@ assertEqual(result, ['Top level assignment', 'Lower level reference'])
|
||||||
# Check population of magic variables
|
# Check population of magic variables
|
||||||
assertEqual(__name__, '__main__')
|
assertEqual(__name__, '__main__')
|
||||||
print '__file__==%r' % __file__
|
print '__file__==%r' % __file__
|
||||||
|
print '__package__==%r' % __package__
|
||||||
# Check the sys module
|
# Check the sys module
|
||||||
import sys
|
import sys
|
||||||
assertIdentical(globals(), sys.modules[__name__].__dict__)
|
assertIdentical(globals(), sys.modules[__name__].__dict__)
|
||||||
print 'sys.argv[0]==%r' % sys.argv[0]
|
print 'sys.argv[0]==%r' % sys.argv[0]
|
||||||
""")
|
"""
|
||||||
|
|
||||||
def _make_test_script(script_dir, script_basename):
|
def _make_test_script(script_dir, script_basename, source=test_source):
|
||||||
script_filename = script_basename+os.extsep+"py"
|
script_filename = script_basename+os.extsep+'py'
|
||||||
script_name = os.path.join(script_dir, script_filename)
|
script_name = os.path.join(script_dir, script_filename)
|
||||||
script_file = open(script_name, "w")
|
script_file = open(script_name, 'w')
|
||||||
script_file.write(test_source)
|
script_file.write(source)
|
||||||
script_file.close()
|
script_file.close()
|
||||||
return script_name
|
return script_name
|
||||||
|
|
||||||
|
@ -76,71 +77,108 @@ def _compile_test_script(script_name):
|
||||||
return compiled_name
|
return compiled_name
|
||||||
|
|
||||||
def _make_test_zip(zip_dir, zip_basename, script_name):
|
def _make_test_zip(zip_dir, zip_basename, script_name):
|
||||||
zip_filename = zip_basename+os.extsep+"zip"
|
zip_filename = zip_basename+os.extsep+'zip'
|
||||||
zip_name = os.path.join(zip_dir, zip_filename)
|
zip_name = os.path.join(zip_dir, zip_filename)
|
||||||
zip_file = zipfile.ZipFile(zip_name, 'w')
|
zip_file = zipfile.ZipFile(zip_name, 'w')
|
||||||
zip_file.write(script_name, os.path.basename(script_name))
|
zip_file.write(script_name, os.path.basename(script_name))
|
||||||
zip_file.close()
|
zip_file.close()
|
||||||
# if verbose:
|
# if verbose:
|
||||||
# zip_file = zipfile.ZipFile(zip_name, 'r')
|
# zip_file = zipfile.ZipFile(zip_name, 'r')
|
||||||
# print "Contents of %r:" % zip_name
|
# print 'Contents of %r:' % zip_name
|
||||||
# zip_file.printdir()
|
# zip_file.printdir()
|
||||||
# zip_file.close()
|
# zip_file.close()
|
||||||
return zip_name
|
return zip_name
|
||||||
|
|
||||||
|
def _make_test_pkg(pkg_dir):
|
||||||
|
os.mkdir(pkg_dir)
|
||||||
|
_make_test_script(pkg_dir, '__init__', '')
|
||||||
|
|
||||||
|
# There's no easy way to pass the script directory in to get
|
||||||
|
# -m to work (avoiding that is the whole point of making
|
||||||
|
# directories and zipfiles executable!)
|
||||||
|
# So we fake it for testing purposes with a custom launch script
|
||||||
|
launch_source = """\
|
||||||
|
import sys, os.path, runpy
|
||||||
|
sys.path[0:0] = os.path.dirname(__file__)
|
||||||
|
runpy._run_module_as_main(%r)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _make_launch_script(script_dir, script_basename, module_name):
|
||||||
|
return _make_test_script(script_dir, script_basename,
|
||||||
|
launch_source % module_name)
|
||||||
|
|
||||||
class CmdLineTest(unittest.TestCase):
|
class CmdLineTest(unittest.TestCase):
|
||||||
def _check_script(self, script_name, expected_file, expected_argv0):
|
def _check_script(self, script_name, expected_file,
|
||||||
exit_code, data = _run_python(script_name)
|
expected_argv0, expected_package,
|
||||||
|
*cmd_line_switches):
|
||||||
|
run_args = cmd_line_switches + (script_name,)
|
||||||
|
exit_code, data = _run_python(*run_args)
|
||||||
if verbose:
|
if verbose:
|
||||||
print "Output from test script %r:" % script_name
|
print 'Output from test script %r:' % script_name
|
||||||
print data
|
print data
|
||||||
self.assertEqual(exit_code, 0)
|
self.assertEqual(exit_code, 0)
|
||||||
printed_file = '__file__==%r' % expected_file
|
printed_file = '__file__==%r' % expected_file
|
||||||
printed_argv0 = 'sys.argv[0]==%r' % expected_argv0
|
printed_argv0 = 'sys.argv[0]==%r' % expected_argv0
|
||||||
|
printed_package = '__package__==%r' % expected_package
|
||||||
|
if verbose:
|
||||||
|
print 'Expected output:'
|
||||||
|
print printed_file
|
||||||
|
print printed_package
|
||||||
|
print printed_argv0
|
||||||
self.assert_(printed_file in data)
|
self.assert_(printed_file in data)
|
||||||
|
self.assert_(printed_package in data)
|
||||||
self.assert_(printed_argv0 in data)
|
self.assert_(printed_argv0 in data)
|
||||||
|
|
||||||
def test_basic_script(self):
|
def test_basic_script(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, "script")
|
script_name = _make_test_script(script_dir, 'script')
|
||||||
self._check_script(script_name, script_name, script_name)
|
self._check_script(script_name, script_name, script_name, None)
|
||||||
|
|
||||||
def test_script_compiled(self):
|
def test_script_compiled(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, "script")
|
script_name = _make_test_script(script_dir, 'script')
|
||||||
compiled_name = _compile_test_script(script_name)
|
compiled_name = _compile_test_script(script_name)
|
||||||
os.remove(script_name)
|
os.remove(script_name)
|
||||||
self._check_script(compiled_name, compiled_name, compiled_name)
|
self._check_script(compiled_name, compiled_name, compiled_name, None)
|
||||||
|
|
||||||
def test_directory(self):
|
def test_directory(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, "__main__")
|
script_name = _make_test_script(script_dir, '__main__')
|
||||||
self._check_script(script_dir, script_name, script_dir)
|
self._check_script(script_dir, script_name, script_dir, '')
|
||||||
|
|
||||||
def test_directory_compiled(self):
|
def test_directory_compiled(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, "__main__")
|
script_name = _make_test_script(script_dir, '__main__')
|
||||||
compiled_name = _compile_test_script(script_name)
|
compiled_name = _compile_test_script(script_name)
|
||||||
os.remove(script_name)
|
os.remove(script_name)
|
||||||
self._check_script(script_dir, compiled_name, script_dir)
|
self._check_script(script_dir, compiled_name, script_dir, '')
|
||||||
|
|
||||||
def test_zipfile(self):
|
def test_zipfile(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, "__main__")
|
script_name = _make_test_script(script_dir, '__main__')
|
||||||
zip_name = _make_test_zip(script_dir, "test_zip", script_name)
|
zip_name = _make_test_zip(script_dir, 'test_zip', script_name)
|
||||||
self._check_script(zip_name, None, zip_name)
|
self._check_script(zip_name, None, zip_name, '')
|
||||||
|
|
||||||
def test_zipfile_compiled(self):
|
def test_zipfile_compiled(self):
|
||||||
with temp_dir() as script_dir:
|
with temp_dir() as script_dir:
|
||||||
script_name = _make_test_script(script_dir, "__main__")
|
script_name = _make_test_script(script_dir, '__main__')
|
||||||
compiled_name = _compile_test_script(script_name)
|
compiled_name = _compile_test_script(script_name)
|
||||||
zip_name = _make_test_zip(script_dir, "test_zip", compiled_name)
|
zip_name = _make_test_zip(script_dir, 'test_zip', compiled_name)
|
||||||
self._check_script(zip_name, None, zip_name)
|
self._check_script(zip_name, None, zip_name, '')
|
||||||
|
|
||||||
|
def test_module_in_package(self):
|
||||||
|
with temp_dir() as script_dir:
|
||||||
|
pkg_dir = os.path.join(script_dir, 'test_pkg')
|
||||||
|
_make_test_pkg(pkg_dir)
|
||||||
|
script_name = _make_test_script(pkg_dir, 'script')
|
||||||
|
launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script')
|
||||||
|
self._check_script(launch_name, script_name,
|
||||||
|
script_name, 'test_pkg')
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test.test_support.run_unittest(CmdLineTest)
|
test.test_support.run_unittest(CmdLineTest)
|
||||||
test.test_support.reap_children()
|
test.test_support.reap_children()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
test_main()
|
test_main()
|
||||||
|
|
|
@ -188,11 +188,13 @@ class Test(unittest.TestCase):
|
||||||
import t5
|
import t5
|
||||||
self.assertEqual(fixdir(dir(t5)),
|
self.assertEqual(fixdir(dir(t5)),
|
||||||
['__doc__', '__file__', '__name__',
|
['__doc__', '__file__', '__name__',
|
||||||
'__path__', 'foo', 'string', 't5'])
|
'__package__', '__path__', 'foo', 'string', 't5'])
|
||||||
self.assertEqual(fixdir(dir(t5.foo)),
|
self.assertEqual(fixdir(dir(t5.foo)),
|
||||||
['__doc__', '__file__', '__name__', 'string'])
|
['__doc__', '__file__', '__name__', '__package__',
|
||||||
|
'string'])
|
||||||
self.assertEqual(fixdir(dir(t5.string)),
|
self.assertEqual(fixdir(dir(t5.string)),
|
||||||
['__doc__', '__file__', '__name__', 'spam'])
|
['__doc__', '__file__', '__name__','__package__',
|
||||||
|
'spam'])
|
||||||
|
|
||||||
def test_6(self):
|
def test_6(self):
|
||||||
hier = [
|
hier = [
|
||||||
|
@ -208,14 +210,14 @@ class Test(unittest.TestCase):
|
||||||
import t6
|
import t6
|
||||||
self.assertEqual(fixdir(dir(t6)),
|
self.assertEqual(fixdir(dir(t6)),
|
||||||
['__all__', '__doc__', '__file__',
|
['__all__', '__doc__', '__file__',
|
||||||
'__name__', '__path__'])
|
'__name__', '__package__', '__path__'])
|
||||||
s = """
|
s = """
|
||||||
import t6
|
import t6
|
||||||
from t6 import *
|
from t6 import *
|
||||||
self.assertEqual(fixdir(dir(t6)),
|
self.assertEqual(fixdir(dir(t6)),
|
||||||
['__all__', '__doc__', '__file__',
|
['__all__', '__doc__', '__file__',
|
||||||
'__name__', '__path__', 'eggs',
|
'__name__', '__package__', '__path__',
|
||||||
'ham', 'spam'])
|
'eggs', 'ham', 'spam'])
|
||||||
self.assertEqual(dir(), ['eggs', 'ham', 'self', 'spam', 't6'])
|
self.assertEqual(dir(), ['eggs', 'ham', 'self', 'spam', 't6'])
|
||||||
"""
|
"""
|
||||||
self.run_code(s)
|
self.run_code(s)
|
||||||
|
@ -241,17 +243,19 @@ class Test(unittest.TestCase):
|
||||||
t7, sub, subsub = None, None, None
|
t7, sub, subsub = None, None, None
|
||||||
import t7 as tas
|
import t7 as tas
|
||||||
self.assertEqual(fixdir(dir(tas)),
|
self.assertEqual(fixdir(dir(tas)),
|
||||||
['__doc__', '__file__', '__name__', '__path__'])
|
['__doc__', '__file__', '__name__',
|
||||||
|
'__package__', '__path__'])
|
||||||
self.failIf(t7)
|
self.failIf(t7)
|
||||||
from t7 import sub as subpar
|
from t7 import sub as subpar
|
||||||
self.assertEqual(fixdir(dir(subpar)),
|
self.assertEqual(fixdir(dir(subpar)),
|
||||||
['__doc__', '__file__', '__name__', '__path__'])
|
['__doc__', '__file__', '__name__',
|
||||||
|
'__package__', '__path__'])
|
||||||
self.failIf(t7)
|
self.failIf(t7)
|
||||||
self.failIf(sub)
|
self.failIf(sub)
|
||||||
from t7.sub import subsub as subsubsub
|
from t7.sub import subsub as subsubsub
|
||||||
self.assertEqual(fixdir(dir(subsubsub)),
|
self.assertEqual(fixdir(dir(subsubsub)),
|
||||||
['__doc__', '__file__', '__name__', '__path__',
|
['__doc__', '__file__', '__name__',
|
||||||
'spam'])
|
'__package__', '__path__', 'spam'])
|
||||||
self.failIf(t7)
|
self.failIf(t7)
|
||||||
self.failIf(sub)
|
self.failIf(sub)
|
||||||
self.failIf(subsub)
|
self.failIf(subsub)
|
||||||
|
|
|
@ -5,7 +5,12 @@ import os.path
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
from test.test_support import verbose, run_unittest, forget
|
from test.test_support import verbose, run_unittest, forget
|
||||||
from runpy import _run_code, _run_module_code, _run_module_as_main, run_module
|
from runpy import _run_code, _run_module_code, run_module
|
||||||
|
|
||||||
|
# Note: This module can't safely test _run_module_as_main as it
|
||||||
|
# runs its tests in the current process, which would mess with the
|
||||||
|
# real __main__ module (usually test.regrtest)
|
||||||
|
# See test_cmd_line_script for a test that executes that code path
|
||||||
|
|
||||||
# Set up the test code and expected results
|
# Set up the test code and expected results
|
||||||
|
|
||||||
|
@ -36,6 +41,7 @@ class RunModuleCodeTest(unittest.TestCase):
|
||||||
self.failUnless(d["__name__"] is None)
|
self.failUnless(d["__name__"] is None)
|
||||||
self.failUnless(d["__file__"] is None)
|
self.failUnless(d["__file__"] is None)
|
||||||
self.failUnless(d["__loader__"] is None)
|
self.failUnless(d["__loader__"] is None)
|
||||||
|
self.failUnless(d["__package__"] is None)
|
||||||
self.failUnless(d["run_argv0"] is saved_argv0)
|
self.failUnless(d["run_argv0"] is saved_argv0)
|
||||||
self.failUnless("run_name" not in d)
|
self.failUnless("run_name" not in d)
|
||||||
self.failUnless(sys.argv[0] is saved_argv0)
|
self.failUnless(sys.argv[0] is saved_argv0)
|
||||||
|
@ -45,13 +51,15 @@ class RunModuleCodeTest(unittest.TestCase):
|
||||||
name = "<Nonsense>"
|
name = "<Nonsense>"
|
||||||
file = "Some other nonsense"
|
file = "Some other nonsense"
|
||||||
loader = "Now you're just being silly"
|
loader = "Now you're just being silly"
|
||||||
|
package = '' # Treat as a top level module
|
||||||
d1 = dict(initial=initial)
|
d1 = dict(initial=initial)
|
||||||
saved_argv0 = sys.argv[0]
|
saved_argv0 = sys.argv[0]
|
||||||
d2 = _run_module_code(self.test_source,
|
d2 = _run_module_code(self.test_source,
|
||||||
d1,
|
d1,
|
||||||
name,
|
name,
|
||||||
file,
|
file,
|
||||||
loader)
|
loader,
|
||||||
|
package)
|
||||||
self.failUnless("result" not in d1)
|
self.failUnless("result" not in d1)
|
||||||
self.failUnless(d2["initial"] is initial)
|
self.failUnless(d2["initial"] is initial)
|
||||||
self.failUnless(d2["result"] == self.expected_result)
|
self.failUnless(d2["result"] == self.expected_result)
|
||||||
|
@ -62,6 +70,7 @@ class RunModuleCodeTest(unittest.TestCase):
|
||||||
self.failUnless(d2["__file__"] is file)
|
self.failUnless(d2["__file__"] is file)
|
||||||
self.failUnless(d2["run_argv0"] is file)
|
self.failUnless(d2["run_argv0"] is file)
|
||||||
self.failUnless(d2["__loader__"] is loader)
|
self.failUnless(d2["__loader__"] is loader)
|
||||||
|
self.failUnless(d2["__package__"] is package)
|
||||||
self.failUnless(sys.argv[0] is saved_argv0)
|
self.failUnless(sys.argv[0] is saved_argv0)
|
||||||
self.failUnless(name not in sys.modules)
|
self.failUnless(name not in sys.modules)
|
||||||
|
|
||||||
|
@ -164,7 +173,7 @@ class RunModuleTest(unittest.TestCase):
|
||||||
self._del_pkg(pkg_dir, depth, mod_name)
|
self._del_pkg(pkg_dir, depth, mod_name)
|
||||||
if verbose: print "Module executed successfully"
|
if verbose: print "Module executed successfully"
|
||||||
|
|
||||||
def _add_relative_modules(self, base_dir, depth):
|
def _add_relative_modules(self, base_dir, source, depth):
|
||||||
if depth <= 1:
|
if depth <= 1:
|
||||||
raise ValueError("Relative module test needs depth > 1")
|
raise ValueError("Relative module test needs depth > 1")
|
||||||
pkg_name = "__runpy_pkg__"
|
pkg_name = "__runpy_pkg__"
|
||||||
|
@ -190,7 +199,7 @@ class RunModuleTest(unittest.TestCase):
|
||||||
if verbose: print " Added nephew module:", nephew_fname
|
if verbose: print " Added nephew module:", nephew_fname
|
||||||
|
|
||||||
def _check_relative_imports(self, depth, run_name=None):
|
def _check_relative_imports(self, depth, run_name=None):
|
||||||
contents = """\
|
contents = r"""\
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from . import sibling
|
from . import sibling
|
||||||
from ..uncle.cousin import nephew
|
from ..uncle.cousin import nephew
|
||||||
|
@ -198,16 +207,21 @@ from ..uncle.cousin import nephew
|
||||||
pkg_dir, mod_fname, mod_name = (
|
pkg_dir, mod_fname, mod_name = (
|
||||||
self._make_pkg(contents, depth))
|
self._make_pkg(contents, depth))
|
||||||
try:
|
try:
|
||||||
self._add_relative_modules(pkg_dir, depth)
|
self._add_relative_modules(pkg_dir, contents, depth)
|
||||||
|
pkg_name = mod_name.rpartition('.')[0]
|
||||||
if verbose: print "Running from source:", mod_name
|
if verbose: print "Running from source:", mod_name
|
||||||
d1 = run_module(mod_name) # Read from source
|
d1 = run_module(mod_name, run_name=run_name) # Read from source
|
||||||
|
self.failUnless("__package__" in d1)
|
||||||
|
self.failUnless(d1["__package__"] == pkg_name)
|
||||||
self.failUnless("sibling" in d1)
|
self.failUnless("sibling" in d1)
|
||||||
self.failUnless("nephew" in d1)
|
self.failUnless("nephew" in d1)
|
||||||
del d1 # Ensure __loader__ entry doesn't keep file open
|
del d1 # Ensure __loader__ entry doesn't keep file open
|
||||||
__import__(mod_name)
|
__import__(mod_name)
|
||||||
os.remove(mod_fname)
|
os.remove(mod_fname)
|
||||||
if verbose: print "Running from compiled:", mod_name
|
if verbose: print "Running from compiled:", mod_name
|
||||||
d2 = run_module(mod_name) # Read from bytecode
|
d2 = run_module(mod_name, run_name=run_name) # Read from bytecode
|
||||||
|
self.failUnless("__package__" in d2)
|
||||||
|
self.failUnless(d2["__package__"] == pkg_name)
|
||||||
self.failUnless("sibling" in d2)
|
self.failUnless("sibling" in d2)
|
||||||
self.failUnless("nephew" in d2)
|
self.failUnless("nephew" in d2)
|
||||||
del d2 # Ensure __loader__ entry doesn't keep file open
|
del d2 # Ensure __loader__ entry doesn't keep file open
|
||||||
|
@ -225,6 +239,11 @@ from ..uncle.cousin import nephew
|
||||||
if verbose: print "Testing relative imports at depth:", depth
|
if verbose: print "Testing relative imports at depth:", depth
|
||||||
self._check_relative_imports(depth)
|
self._check_relative_imports(depth)
|
||||||
|
|
||||||
|
def test_main_relative_import(self):
|
||||||
|
for depth in range(2, 5):
|
||||||
|
if verbose: print "Testing main relative imports at depth:", depth
|
||||||
|
self._check_relative_imports(depth, "__main__")
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
run_unittest(RunModuleCodeTest)
|
run_unittest(RunModuleCodeTest)
|
||||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 2.6 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- PEP 366: Allow explicit relative imports when executing modules
|
||||||
|
inside packages with the -m switch via a new module level
|
||||||
|
__package__ attribute.
|
||||||
|
|
||||||
- Issue #1534: Added ``PyFloat_GetMax()``, ``PyFloat_GetMin()`` and
|
- Issue #1534: Added ``PyFloat_GetMax()``, ``PyFloat_GetMin()`` and
|
||||||
``PyFloat_GetInfo()`` to the float API.
|
``PyFloat_GetInfo()`` to the float API.
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ PyModule_New(const char *name)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
|
if (PyDict_SetItemString(m->md_dict, "__doc__", Py_None) != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
if (PyDict_SetItemString(m->md_dict, "__package__", Py_None) != 0)
|
||||||
|
goto fail;
|
||||||
Py_DECREF(nameobj);
|
Py_DECREF(nameobj);
|
||||||
PyObject_GC_Track(m);
|
PyObject_GC_Track(m);
|
||||||
return (PyObject *)m;
|
return (PyObject *)m;
|
||||||
|
|
|
@ -2106,7 +2106,8 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
|
||||||
{
|
{
|
||||||
static PyObject *namestr = NULL;
|
static PyObject *namestr = NULL;
|
||||||
static PyObject *pathstr = NULL;
|
static PyObject *pathstr = NULL;
|
||||||
PyObject *modname, *modpath, *modules, *parent;
|
static PyObject *pkgstr = NULL;
|
||||||
|
PyObject *pkgname, *modname, *modpath, *modules, *parent;
|
||||||
|
|
||||||
if (globals == NULL || !PyDict_Check(globals) || !level)
|
if (globals == NULL || !PyDict_Check(globals) || !level)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
@ -2121,34 +2122,82 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
|
||||||
if (pathstr == NULL)
|
if (pathstr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (pkgstr == NULL) {
|
||||||
|
pkgstr = PyString_InternFromString("__package__");
|
||||||
|
if (pkgstr == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
*p_buflen = 0;
|
*p_buflen = 0;
|
||||||
|
pkgname = PyDict_GetItem(globals, pkgstr);
|
||||||
|
|
||||||
|
if ((pkgname != NULL) && (pkgname != Py_None)) {
|
||||||
|
/* __package__ is set, so use it */
|
||||||
|
Py_ssize_t len;
|
||||||
|
if (!PyString_Check(pkgname)) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"__package__ set to non-string");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len = PyString_GET_SIZE(pkgname);
|
||||||
|
if (len == 0) {
|
||||||
|
if (level > 0) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Attempted relative import in non-package");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
if (len > MAXPATHLEN) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Package name too long");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strcpy(buf, PyString_AS_STRING(pkgname));
|
||||||
|
} else {
|
||||||
|
/* __package__ not set, so figure it out and set it */
|
||||||
modname = PyDict_GetItem(globals, namestr);
|
modname = PyDict_GetItem(globals, namestr);
|
||||||
if (modname == NULL || !PyString_Check(modname))
|
if (modname == NULL || !PyString_Check(modname))
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
|
||||||
modpath = PyDict_GetItem(globals, pathstr);
|
modpath = PyDict_GetItem(globals, pathstr);
|
||||||
if (modpath != NULL) {
|
if (modpath != NULL) {
|
||||||
|
/* __path__ is set, so modname is already the package name */
|
||||||
Py_ssize_t len = PyString_GET_SIZE(modname);
|
Py_ssize_t len = PyString_GET_SIZE(modname);
|
||||||
|
int error;
|
||||||
if (len > MAXPATHLEN) {
|
if (len > MAXPATHLEN) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Module name too long");
|
"Module name too long");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(buf, PyString_AS_STRING(modname));
|
strcpy(buf, PyString_AS_STRING(modname));
|
||||||
|
error = PyDict_SetItem(globals, pkgstr, modname);
|
||||||
|
if (error) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Could not set __package__");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
|
/* Normal module, so work out the package name if any */
|
||||||
char *start = PyString_AS_STRING(modname);
|
char *start = PyString_AS_STRING(modname);
|
||||||
char *lastdot = strrchr(start, '.');
|
char *lastdot = strrchr(start, '.');
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int error;
|
||||||
if (lastdot == NULL && level > 0) {
|
if (lastdot == NULL && level > 0) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Attempted relative import in non-package");
|
"Attempted relative import in non-package");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (lastdot == NULL)
|
if (lastdot == NULL) {
|
||||||
|
error = PyDict_SetItem(globals, pkgstr, Py_None);
|
||||||
|
if (error) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Could not set __package__");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
}
|
||||||
len = lastdot - start;
|
len = lastdot - start;
|
||||||
if (len >= MAXPATHLEN) {
|
if (len >= MAXPATHLEN) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
@ -2157,8 +2206,19 @@ get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
|
||||||
}
|
}
|
||||||
strncpy(buf, start, len);
|
strncpy(buf, start, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
pkgname = PyString_FromString(buf);
|
||||||
|
if (pkgname == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
error = PyDict_SetItem(globals, pkgstr, pkgname);
|
||||||
|
Py_DECREF(pkgname);
|
||||||
|
if (error) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"Could not set __package__");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (--level > 0) {
|
while (--level > 0) {
|
||||||
char *dot = strrchr(buf, '.');
|
char *dot = strrchr(buf, '.');
|
||||||
if (dot == NULL) {
|
if (dot == NULL) {
|
||||||
|
|
Loading…
Reference in New Issue