-
-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Script/Main.py so it uses importlib #3552
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,9 @@ | |
|
||
import SCons.compat | ||
|
||
import importlib.util | ||
import os | ||
import re | ||
import sys | ||
import time | ||
import traceback | ||
|
@@ -65,7 +67,6 @@ | |
import SCons.Taskmaster | ||
import SCons.Util | ||
import SCons.Warnings | ||
|
||
import SCons.Script.Interactive | ||
|
||
# Global variables | ||
|
@@ -698,80 +699,87 @@ def _create_path(plist): | |
return path | ||
|
||
def _load_site_scons_dir(topdir, site_dir_name=None): | ||
"""Load the site_scons dir under topdir. | ||
Prepends site_scons to sys.path, imports site_scons/site_init.py, | ||
and prepends site_scons/site_tools to default toolpath.""" | ||
"""Load the site directory under topdir. | ||
|
||
If a site dir name is supplied use it, else use default "site_scons" | ||
Prepend site dir to sys.path. | ||
If a "site_tools" subdir exists, prepend to toolpath. | ||
Import "site_init.py" from site dir if it exists. | ||
""" | ||
if site_dir_name: | ||
err_if_not_found = True # user specified: err if missing | ||
else: | ||
site_dir_name = "site_scons" | ||
err_if_not_found = False | ||
|
||
err_if_not_found = False # scons default: okay to be missing | ||
site_dir = os.path.join(topdir, site_dir_name) | ||
|
||
if not os.path.exists(site_dir): | ||
if err_if_not_found: | ||
raise SCons.Errors.UserError("site dir %s not found."%site_dir) | ||
raise SCons.Errors.UserError("site dir %s not found." % site_dir) | ||
return | ||
sys.path.insert(0, os.path.abspath(site_dir)) | ||
|
||
site_init_filename = "site_init.py" | ||
site_init_modname = "site_init" | ||
site_tools_dirname = "site_tools" | ||
# prepend to sys.path | ||
sys.path = [os.path.abspath(site_dir)] + sys.path | ||
site_init_file = os.path.join(site_dir, site_init_filename) | ||
site_tools_dir = os.path.join(site_dir, site_tools_dirname) | ||
if os.path.exists(site_init_file): | ||
import imp, re | ||
try: | ||
try: | ||
fp, pathname, description = imp.find_module(site_init_modname, | ||
[site_dir]) | ||
# Load the file into SCons.Script namespace. This is | ||
# opaque and clever; m is the module object for the | ||
# SCons.Script module, and the exec ... in call executes a | ||
# file (or string containing code) in the context of the | ||
# module's dictionary, so anything that code defines ends | ||
# up adding to that module. This is really short, but all | ||
# the error checking makes it longer. | ||
try: | ||
m = sys.modules['SCons.Script'] | ||
except Exception as e: | ||
fmt = 'cannot import site_init.py: missing SCons.Script module %s' | ||
raise SCons.Errors.InternalError(fmt % repr(e)) | ||
try: | ||
sfx = description[0] | ||
modname = os.path.basename(pathname)[:-len(sfx)] | ||
site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} | ||
re_special = re.compile("__[^_]+__") | ||
for k, v in m.__dict__.items(): | ||
if not re_special.match(k): | ||
site_m[k] = v | ||
|
||
# This is the magic. | ||
exec(compile(fp.read(), fp.name, 'exec'), site_m) | ||
except KeyboardInterrupt: | ||
raise | ||
except Exception as e: | ||
fmt = '*** Error loading site_init file %s:\n' | ||
sys.stderr.write(fmt % repr(site_init_file)) | ||
raise | ||
else: | ||
for k in site_m: | ||
if not re_special.match(k): | ||
m.__dict__[k] = site_m[k] | ||
except KeyboardInterrupt: | ||
raise | ||
except ImportError as e: | ||
fmt = '*** cannot import site init file %s:\n' | ||
sys.stderr.write(fmt % repr(site_init_file)) | ||
raise | ||
finally: | ||
if fp: | ||
fp.close() | ||
|
||
if os.path.exists(site_tools_dir): | ||
# prepend to DefaultToolpath | ||
SCons.Tool.DefaultToolpath.insert(0, os.path.abspath(site_tools_dir)) | ||
|
||
if not os.path.exists(site_init_file): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the impact of moving this below the site_tools_dir if above? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just grouping, flow matches the reworded docstring. |
||
return | ||
|
||
# "import" the site_init.py file into the SCons.Script namespace. | ||
# This is a variant on the basic Python import flow in that the globals | ||
# dict for the compile step is prepopulated from the SCons.Script | ||
# module object; on success the SCons.Script globals are refilled | ||
# from the site_init globals so it all appears in SCons.Script | ||
# instead of as a separate module. | ||
try: | ||
try: | ||
m = sys.modules['SCons.Script'] | ||
except KeyError: | ||
fmt = 'cannot import {}: missing SCons.Script module' | ||
raise SCons.Errors.InternalError(fmt.format(site_init_file)) | ||
|
||
spec = importlib.util.spec_from_file_location(site_init_modname, site_init_file) | ||
site_m = { | ||
"__file__": spec.origin, | ||
"__name__": spec.name, | ||
"__doc__": None, | ||
} | ||
re_dunder = re.compile(r"__[^_]+__") | ||
# update site dict with all but magic (dunder) methods | ||
for k, v in m.__dict__.items(): | ||
if not re_dunder.match(k): | ||
site_m[k] = v | ||
|
||
with open(spec.origin, 'r') as f: | ||
code = f.read() | ||
try: | ||
codeobj = compile(code, spec.name, "exec") | ||
exec(codeobj, site_m) | ||
except KeyboardInterrupt: | ||
raise | ||
except Exception: | ||
fmt = "*** Error loading site_init file {}:\n" | ||
sys.stderr.write(fmt.format(site_init_file)) | ||
raise | ||
else: | ||
# now refill globals with site_init's symbols | ||
for k, v in site_m.items(): | ||
if not re_dunder.match(k): | ||
m.__dict__[k] = v | ||
except KeyboardInterrupt: | ||
raise | ||
except Exception: | ||
fmt = "*** cannot import site init file {}:\n" | ||
sys.stderr.write(fmt.format(site_init_file)) | ||
raise | ||
|
||
|
||
def _load_all_site_scons_dirs(topdir, verbose=None): | ||
"""Load all of the predefined site_scons dir. | ||
Order is significant; we load them in order from most generic | ||
|
@@ -810,7 +818,7 @@ def homedir(d): | |
sysdirs=['/usr/share/scons', | ||
homedir('.scons')] | ||
|
||
dirs=sysdirs + [topdir] | ||
dirs = sysdirs + [topdir] | ||
for d in dirs: | ||
if verbose: # this is used by unit tests. | ||
print("Loading site dir ", d) | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth adding motivation.. imp deprecated and will be removed in Py#.#?
Are we still using imp elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to insert the word "deprecated" when you decide to push it that's fine. I don't think there's a timeline, they're still dickering about deprecation (sounds familiar!).
If you want me to update it from here I will.