def main(args=None):
if args is None:
args = sys.argv[1:]
# TODO Add help output, --help, etc.
# TODO Handle library-wide options. Eg.:
# --unicodedata
# --verbose / other logging stuff
# TODO Allow a way to run arbitrary modules? Useful for setting
# library-wide options and calling another library. Eg.:
#
# $ fonttools --unicodedata=... fontmake ...
#
# This allows for a git-like command where thirdparty commands
# can be added. Should we just try importing the fonttools
# module first and try without if it fails?
mod = 'fontTools.'+sys.argv[1]
sys.argv[1] = sys.argv[0] + ' ' + sys.argv[1]
del sys.argv[0]
import runpy
runpy.run_module(mod, run_name='__main__')
python类run_module()的实例源码
def run_cli_options(args):
"""
Quick implementation of Python interpreter's -m, -c and file execution.
The resulting dictionary is imported into global namespace, just in case
someone is using interactive mode.
"""
if not in_ipython():
if args.module:
globals().update(runpy.run_module(args.module, run_name="__main__"))
if args.string:
exec(args.string)
if args.command not in ('ipython', 'notebook', None):
oldargv, sys.argv = sys.argv, sys.argv[1:]
globals().update(runpy.run_path(args.command, run_name="__main__"))
sys.argv = oldargv
if _interactive_mode(args.interactive):
os.environ['PYTHONINSPECT'] = '1'
def _check_module(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth))
forget(mod_name)
try:
if verbose: print("Running from source:", mod_name)
d1 = run_module(mod_name) # Read from source
self.assertIn("x", d1)
self.assertEqual(d1["x"], 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
make_legacy_pyc(mod_fname)
unload(mod_name) # In case loader caches paths
if verbose: print("Running from compiled:", mod_name)
d2 = run_module(mod_name) # Read from bytecode
self.assertIn("x", d2)
self.assertEqual(d2["x"], 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, mod_name)
if verbose: print("Module executed successfully")
def _check_package(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth, "__main__"))
pkg_name, _, _ = mod_name.rpartition(".")
forget(mod_name)
try:
if verbose: print("Running from source:", pkg_name)
d1 = run_module(pkg_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
make_legacy_pyc(mod_fname)
unload(mod_name) # In case loader caches paths
if verbose: print("Running from compiled:", pkg_name)
d2 = run_module(pkg_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, pkg_name)
if verbose: print("Package executed successfully")
def _run_exodus(*args):
'''Run a Exodus using runpy
'''
fullpath = path.join(config.addonsdir, config.exodus['id'], config.exodus['entryfile'])
entrypath, entryfile = path.split(fullpath)
if entrypath not in sys.path:
sys.path.insert(0, entrypath)
module, _ = path.splitext(entryfile)
# Exodus assumes thread names start at 1
# and gets provider names from the thread name
c = threading._counter = count().next
c() # consume 0
sys.argv = list(args)
# note: cannot use __import__ because Exodus spawns threads that do import
# so that would cause deadlock
old_modules = set(sys.modules.keys()) # unload the newly added modules after runpy
runpy.run_module(module)
for k in set(sys.modules.keys()) - old_modules:
del sys.modules[k]
def expect_import_error(self, mod_name):
try:
run_module(mod_name)
except ImportError:
pass
else:
self.fail("Expected import error for " + mod_name)
def _check_module(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth))
forget(mod_name)
try:
if verbose: print "Running from source:", mod_name
d1 = run_module(mod_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", mod_name
d2 = run_module(mod_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, mod_name)
if verbose: print "Module executed successfully"
def _check_package(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth, "__main__"))
pkg_name, _, _ = mod_name.rpartition(".")
forget(mod_name)
try:
if verbose: print "Running from source:", pkg_name
d1 = run_module(pkg_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", pkg_name
d2 = run_module(pkg_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, pkg_name)
if verbose: print "Package executed successfully"
def _check_module(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth))
forget(mod_name)
try:
if verbose: print "Running from source:", mod_name
d1 = run_module(mod_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", mod_name
d2 = run_module(mod_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, mod_name)
if verbose: print "Module executed successfully"
def _check_package(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth, "__main__"))
pkg_name, _, _ = mod_name.rpartition(".")
forget(mod_name)
try:
if verbose: print "Running from source:", pkg_name
d1 = run_module(pkg_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", pkg_name
d2 = run_module(pkg_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, pkg_name)
if verbose: print "Package executed successfully"
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--package', action='append')
parser.add_argument('--dir', action='append')
parser.add_argument('-m', action='store', metavar='MODULE')
args, rest = parser.parse_known_args()
if args.package:
PACKAGES.extend(args.package)
if args.dir:
DIRS.extend(os.path.abspath(d) for d in args.dir)
if not PACKAGES and not DIRS:
DIRS.append(os.getcwd())
if args.m:
sys.argv[1:] = rest
runpy.run_module(args.m, run_name='__main__', alter_sys=True)
elif rest:
sys.argv = rest
converted = maybe_2to3(rest[0])
with open(converted) as f:
new_globals = dict(__name__='__main__',
__file__=rest[0])
exec(f.read(), new_globals)
else:
import code
code.interact()
def _check_module(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth))
forget(mod_name)
try:
if verbose: print "Running from source:", mod_name
d1 = run_module(mod_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
if not no_lone_pyc_file:
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", mod_name
d2 = run_module(mod_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, mod_name)
if verbose: print "Module executed successfully"
def _check_package(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth, "__main__"))
pkg_name, _, _ = mod_name.rpartition(".")
forget(mod_name)
try:
if verbose: print "Running from source:", pkg_name
d1 = run_module(pkg_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
if not no_lone_pyc_file:
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", pkg_name
d2 = run_module(pkg_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, pkg_name)
if verbose: print "Package executed successfully"
def _fixup_main_from_name(mod_name):
# __main__.py files for packages, directories, zip archives, etc, run
# their "main only" code unconditionally, so we don't even try to
# populate anything in __main__, nor do we make any changes to
# __main__ attributes
current_main = sys.modules['__main__']
if mod_name == "__main__" or mod_name.endswith(".__main__"):
return
# If this process was forked, __main__ may already be populated
if getattr(current_main.__spec__, "name", None) == mod_name:
return
# Otherwise, __main__ may contain some non-main code where we need to
# support unpickling it properly. We rerun it as __mp_main__ and make
# the normal __main__ an alias to that
old_main_modules.append(current_main)
main_module = types.ModuleType("__mp_main__")
main_content = runpy.run_module(mod_name,
run_name="__mp_main__",
alter_sys=True)
main_module.__dict__.update(main_content)
sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module
def test_run_name(self):
depth = 1
run_name = "And now for something completely different"
pkg_dir, mod_fname, mod_name, mod_spec = (
self._make_pkg(example_source, depth))
forget(mod_name)
expected_ns = example_namespace.copy()
expected_ns.update({
"__name__": run_name,
"__file__": mod_fname,
"__cached__": importlib.util.cache_from_source(mod_fname),
"__package__": mod_name.rpartition(".")[0],
"__spec__": mod_spec,
})
def create_ns(init_globals):
return run_module(mod_name, init_globals, run_name)
try:
self.check_code_execution(create_ns, expected_ns)
finally:
self._del_pkg(pkg_dir, depth, mod_name)
def _check_module(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth))
forget(mod_name)
try:
if verbose: print "Running from source:", mod_name
d1 = run_module(mod_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", mod_name
d2 = run_module(mod_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, mod_name)
if verbose: print "Module executed successfully"
def _check_package(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth, "__main__"))
pkg_name, _, _ = mod_name.rpartition(".")
forget(mod_name)
try:
if verbose: print "Running from source:", pkg_name
d1 = run_module(pkg_name) # Read from source
self.assertIn("x", d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if not sys.dont_write_bytecode:
if verbose: print "Running from compiled:", pkg_name
d2 = run_module(pkg_name) # Read from bytecode
self.assertIn("x", d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, pkg_name)
if verbose: print "Package executed successfully"
def _fixup_main_from_name(mod_name):
# __main__.py files for packages, directories, zip archives, etc, run
# their "main only" code unconditionally, so we don't even try to
# populate anything in __main__, nor do we make any changes to
# __main__ attributes
current_main = sys.modules['__main__']
if mod_name == "__main__" or mod_name.endswith(".__main__"):
return
# If this process was forked, __main__ may already be populated
if getattr(current_main.__spec__, "name", None) == mod_name:
return
# Otherwise, __main__ may contain some non-main code where we need to
# support unpickling it properly. We rerun it as __mp_main__ and make
# the normal __main__ an alias to that
old_main_modules.append(current_main)
main_module = types.ModuleType("__mp_main__")
main_content = runpy.run_module(mod_name,
run_name="__mp_main__",
alter_sys=True)
main_module.__dict__.update(main_content)
sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module
def test_run_name(self):
depth = 1
run_name = "And now for something completely different"
pkg_dir, mod_fname, mod_name, mod_spec = (
self._make_pkg(example_source, depth))
forget(mod_name)
expected_ns = example_namespace.copy()
expected_ns.update({
"__name__": run_name,
"__file__": mod_fname,
"__cached__": importlib.util.cache_from_source(mod_fname),
"__package__": mod_name.rpartition(".")[0],
"__spec__": mod_spec,
})
def create_ns(init_globals):
return run_module(mod_name, init_globals, run_name)
try:
self.check_code_execution(create_ns, expected_ns)
finally:
self._del_pkg(pkg_dir, depth, mod_name)
def exec_module(module, global_variables):
'''Executes the provided module as if it were provided as '-m module'. The
functionality is implemented using `runpy.run_module`, which was added in
Python 2.5.
'''
import runpy
runpy.run_module(module, global_variables, run_name=global_variables.get('__name__'), alter_sys=True)
def execute_module_work_item(self):
new_argv = [''] + _command_line_to_args_list(self.current_args)
old_argv = sys.argv
import runpy
try:
sys.argv = new_argv
runpy.run_module(self.current_code, alter_sys=True)
except Exception:
traceback.print_exc()
finally:
sys.argv = old_argv
def exec_module(module, global_variables):
'''Executes the provided module as if it were provided as '-m module'. The
functionality is implemented using `runpy.run_module`, which was added in
Python 2.5.
'''
import runpy
runpy.run_module(module, global_variables, run_name=global_variables.get('__name__'), alter_sys=True)
def execute_module_work_item(self):
new_argv = [''] + _command_line_to_args_list(self.current_args)
old_argv = sys.argv
import runpy
try:
sys.argv = new_argv
runpy.run_module(self.current_code, alter_sys=True)
except Exception:
traceback.print_exc()
finally:
sys.argv = old_argv
def run_module(name: str, *args, run_name: str = '__main__') -> None:
backup_sys_argv = sys.argv
sys.argv = [name + '.py'] + list(args)
runpy.run_module(name, run_name=run_name)
sys.argv = backup_sys_argv
def test_build_binary(self):
run_module('setup', 'bdist')
self.assertTrue(os.path.isdir('dist'))
def test_build_wheel(self):
run_module('setup', 'bdist_wheel')
self.assertTrue(os.path.isdir('dist'))
def test_build_source(self):
run_module('setup', 'sdist', '--formats=gztar,zip')
self.assertTrue(os.path.isdir('dist'))
def test_clean(self):
run_module('setup', 'bdist')
self.assertTrue(os.path.isdir('build'))
package = import_module_member('setup_boilerplate', 'Package')
package.clean()
os.mkdir('build')
package.clean()
package.clean()
self.assertFalse(os.path.isdir('build'))
def safe_run_module(self, mod_name, where):
"""A safe version of runpy.run_module().
This version will never throw an exception, but instead print
helpful error messages to the screen.
`SystemExit` exceptions with status code 0 or None are ignored.
Parameters
----------
mod_name : string
The name of the module to be executed.
where : dict
The globals namespace.
"""
try:
try:
where.update(
runpy.run_module(str(mod_name), run_name="__main__",
alter_sys=True)
)
except SystemExit as status:
if status.code:
raise
except:
self.showtraceback()
warn('Unknown failure executing module: <%s>' % mod_name)
def expect_import_error(self, mod_name):
try:
run_module(mod_name)
except ImportError:
pass
else:
self.fail("Expected import error for " + mod_name)