diff options
author | William Deegan <bill@baddogconsulting.com> | 2016-08-12 14:13:03 (GMT) |
---|---|---|
committer | William Deegan <bill@baddogconsulting.com> | 2016-08-12 14:13:03 (GMT) |
commit | 8bb44b6de01a456e4027f58af0bb7890b78142cb (patch) | |
tree | 4ed92c72ecc468c82978bec7d2496b33060416e0 /src/engine/SCons | |
parent | 0bc95a1575a1e48b0f27a27c4bc48070c838c484 (diff) | |
parent | 18ed9b715d052ad972940e90e9d83da53216c289 (diff) | |
download | SCons-8bb44b6de01a456e4027f58af0bb7890b78142cb.zip SCons-8bb44b6de01a456e4027f58af0bb7890b78142cb.tar.gz SCons-8bb44b6de01a456e4027f58af0bb7890b78142cb.tar.bz2 |
merge from upstream
Diffstat (limited to 'src/engine/SCons')
-rw-r--r-- | src/engine/SCons/ActionTests.py | 30 | ||||
-rw-r--r-- | src/engine/SCons/Executor.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 30 | ||||
-rw-r--r-- | src/engine/SCons/Scanner/C.py | 5 | ||||
-rw-r--r-- | src/engine/SCons/__main__.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/compat/__init__.py | 47 |
7 files changed, 94 insertions, 32 deletions
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 3eee4b6..9007183 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -231,7 +231,7 @@ def test_positional_args(pos_callback, cmd, **kw): """ act = SCons.Action.Action(cmd, **kw) pos_callback(act) - assert act.varlist is (), act.varlist + assert act.varlist == (), act.varlist if not isinstance(act, SCons.Action._ActionAction): # only valid cmdstrfunc is None @@ -316,7 +316,7 @@ class ActionTestCase(unittest.TestCase): """ a1 = SCons.Action.Action(["x", "y", "z", [ "a", "b", "c"]]) assert isinstance(a1, SCons.Action.ListAction), a1 - assert a1.varlist is (), a1.varlist + assert a1.varlist == (), a1.varlist assert isinstance(a1.list[0], SCons.Action.CommandAction), a1.list[0] assert a1.list[0].cmd_list == "x", a1.list[0].cmd_list assert isinstance(a1.list[1], SCons.Action.CommandAction), a1.list[1] @@ -328,7 +328,7 @@ class ActionTestCase(unittest.TestCase): a2 = SCons.Action.Action("x\ny\nz") assert isinstance(a2, SCons.Action.ListAction), a2 - assert a2.varlist is (), a2.varlist + assert a2.varlist == (), a2.varlist assert isinstance(a2.list[0], SCons.Action.CommandAction), a2.list[0] assert a2.list[0].cmd_list == "x", a2.list[0].cmd_list assert isinstance(a2.list[1], SCons.Action.CommandAction), a2.list[1] @@ -341,7 +341,7 @@ class ActionTestCase(unittest.TestCase): a3 = SCons.Action.Action(["x", foo, "z"]) assert isinstance(a3, SCons.Action.ListAction), a3 - assert a3.varlist is (), a3.varlist + assert a3.varlist == (), a3.varlist assert isinstance(a3.list[0], SCons.Action.CommandAction), a3.list[0] assert a3.list[0].cmd_list == "x", a3.list[0].cmd_list assert isinstance(a3.list[1], SCons.Action.FunctionAction), a3.list[1] @@ -351,7 +351,7 @@ class ActionTestCase(unittest.TestCase): a4 = SCons.Action.Action(["x", "y"], strfunction=foo) assert isinstance(a4, SCons.Action.ListAction), a4 - assert a4.varlist is (), a4.varlist + assert a4.varlist == (), a4.varlist assert isinstance(a4.list[0], SCons.Action.CommandAction), a4.list[0] assert a4.list[0].cmd_list == "x", a4.list[0].cmd_list assert a4.list[0].strfunction == foo, a4.list[0].strfunction @@ -361,7 +361,7 @@ class ActionTestCase(unittest.TestCase): a5 = SCons.Action.Action("x\ny", strfunction=foo) assert isinstance(a5, SCons.Action.ListAction), a5 - assert a5.varlist is (), a5.varlist + assert a5.varlist == (), a5.varlist assert isinstance(a5.list[0], SCons.Action.CommandAction), a5.list[0] assert a5.list[0].cmd_list == "x", a5.list[0].cmd_list assert a5.list[0].strfunction == foo, a5.list[0].strfunction @@ -1533,7 +1533,8 @@ class FunctionActionTestCase(unittest.TestCase): global count count = count + 1 for t in target: - open(t, 'w').write("function1\n") + with open(t, 'w') as f: + f.write("function1\n") return 1 act = SCons.Action.FunctionAction(function1, {}) @@ -1548,7 +1549,8 @@ class FunctionActionTestCase(unittest.TestCase): class class1a(object): def __init__(self, target, source, env): - open(env['out'], 'w').write("class1a\n") + with open(env['out'], 'w') as f: + f.write("class1a\n") act = SCons.Action.FunctionAction(class1a, {}) r = act([], [], Environment(out = outfile)) @@ -1558,7 +1560,8 @@ class FunctionActionTestCase(unittest.TestCase): class class1b(object): def __call__(self, target, source, env): - open(env['out'], 'w').write("class1b\n") + with open(env['out'], 'w') as f: + f.write("class1b\n") return 2 act = SCons.Action.FunctionAction(class1b(), {}) @@ -1710,17 +1713,20 @@ class ListActionTestCase(unittest.TestCase): cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile) def function2(target, source, env): - open(env['out'], 'a').write("function2\n") + with open(env['out'], 'a') as f: + f.write("function2\n") return 0 class class2a(object): def __call__(self, target, source, env): - open(env['out'], 'a').write("class2a\n") + with open(env['out'], 'a') as f: + f.write("class2a\n") return 0 class class2b(object): def __init__(self, target, source, env): - open(env['out'], 'a').write("class2b\n") + with open(env['out'], 'a') as f: + f.write("class2b\n") act = SCons.Action.ListAction([cmd2, function2, class2a(), class2b]) r = act([], [], Environment(out = outfile)) assert isinstance(r.status, class2b), r.status diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 7107fde..dd5088d 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -35,7 +35,7 @@ import SCons.Debug from SCons.Debug import logInstanceCreation import SCons.Errors import SCons.Memoize - +from SCons.compat import with_metaclass, NoSlotsPyPy class Batch(object): """Remembers exact association between targets @@ -154,7 +154,7 @@ _execute_str_map = {0 : execute_null_str, 1 : execute_actions_str} -class Executor(object): +class Executor(object, with_metaclass(NoSlotsPyPy)): """A class for controlling instances of executing an action. This largely exists to hold a single association of an action, @@ -580,7 +580,7 @@ def get_NullEnvironment(): nullenv = NullEnvironment() return nullenv -class Null(object): +class Null(object, with_metaclass(NoSlotsPyPy)): """A null Executor, with a null build Environment, that does nothing when the rest of the methods call it. diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index d19afa9..71511b5 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1211,9 +1211,9 @@ class FS(LocalFS): def getcwd(self): if hasattr(self, "_cwd"): - return self._cwd + return self._cwd else: - return "<no cwd>" + return "<no cwd>" def chdir(self, dir, change_os_dir=0): """Change the current working directory for lookups. diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 1a76b60..00ddf2f 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -57,6 +57,8 @@ import SCons.Util from SCons.Debug import Trace +from SCons.compat import with_metaclass, NoSlotsPyPy + print_duplicate = 0 def classname(obj): @@ -212,7 +214,8 @@ def get_contents_file(node): return '' fname = node.rfile().get_abspath() try: - contents = open(fname, "rb").read() + with open(fname, "rb") as fp: + contents = fp.read() except EnvironmentError as e: if not e.filename: e.filename = fname @@ -489,7 +492,8 @@ class BuildInfoBase(object): if key not in ('__weakref__',): setattr(self, key, value) -class Node(object): + +class Node(object, with_metaclass(NoSlotsPyPy)): """The base Node class, for entities that we know how to build, or use to build other Nodes. """ @@ -926,9 +930,9 @@ class Node(object): scanner's recursive flag says that we should. """ nodes = [self] - seen = {} - seen[self] = 1 + seen = set(nodes) dependencies = [] + path_memo = {} root_node_scanner = self._get_scanner(env, initial_scanner, None, kw) @@ -936,30 +940,32 @@ class Node(object): node = nodes.pop(0) scanner = node._get_scanner(env, initial_scanner, root_node_scanner, kw) - if not scanner: continue - path = path_func(scanner) + try: + path = path_memo[scanner] + except KeyError: + path = path_func(scanner) + path_memo[scanner] = path included_deps = [x for x in node.get_found_includes(env, scanner, path) if x not in seen] if included_deps: dependencies.extend(included_deps) - for dep in included_deps: - seen[dep] = 1 + seen.update(included_deps) nodes.extend(scanner.recurse_nodes(included_deps)) return dependencies def _get_scanner(self, env, initial_scanner, root_node_scanner, kw): - if not initial_scanner: + if initial_scanner: + # handle explicit scanner case + scanner = initial_scanner.select(self) + else: # handle implicit scanner case scanner = self.get_env_scanner(env, kw) if scanner: scanner = scanner.select(self) - else: - # handle explicit scanner case - scanner = initial_scanner.select(self) if not scanner: # no scanner could be found for the given node's scanner key; diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index 3b34b88..c2e50a6 100644 --- a/src/engine/SCons/Scanner/C.py +++ b/src/engine/SCons/Scanner/C.py @@ -58,12 +58,11 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): return result def read_file(self, file): try: - fp = open(str(file.rfile())) + with open(str(file.rfile())) as fp: + return fp.read() except EnvironmentError as e: self.missing.append((file, self.current_file)) return '' - else: - return fp.read() def dictify_CPPDEFINES(env): cppdefines = env.get('CPPDEFINES', {}) diff --git a/src/engine/SCons/__main__.py b/src/engine/SCons/__main__.py new file mode 100644 index 0000000..0dfbb9d --- /dev/null +++ b/src/engine/SCons/__main__.py @@ -0,0 +1,4 @@ +import SCons.Script +# this does all the work, and calls sys.exit +# with the proper exit status when done. +SCons.Script.main() diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 0ddbdd5..6f20b73 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -63,6 +63,8 @@ import os import sys import imp # Use the "imp" module to protect imports from fixers. +PYPY = hasattr(sys, 'pypy_translation_info') + def import_as(module, name): """ Imports the specified module (from our local directory) as the @@ -135,6 +137,51 @@ except AttributeError: del _UserString +def with_metaclass(meta, *bases): + """ + Function from jinja2/_compat.py. License: BSD. + + Use it like this:: + + class BaseForm(object): + pass + + class FormType(type): + pass + + class Form(with_metaclass(FormType, BaseForm)): + pass + + This requires a bit of explanation: the basic idea is to make a + dummy metaclass for one level of class instantiation that replaces + itself with the actual metaclass. Because of internal type checks + we also need to make sure that we downgrade the custom metaclass + for one level to something closer to type (that's why __call__ and + __init__ comes back from type etc.). + + This has the advantage over six.with_metaclass of not introducing + dummy classes into the final MRO. + """ + class metaclass(meta): + __call__ = type.__call__ + __init__ = type.__init__ + def __new__(cls, name, this_bases, d): + if this_bases is None: + return type.__new__(cls, name, (), d) + return meta(name, bases, d) + return metaclass('temporary_class', None, {}) + + +class NoSlotsPyPy(type): + """ + Workaround for PyPy not working well with __slots__ and __class__ assignment. + """ + def __new__(meta, name, bases, dct): + if PYPY and '__slots__' in dct: + dct.pop('__slots__') + return super(NoSlotsPyPy, meta).__new__(meta, name, bases, dct) + + # Local Variables: # tab-width:4 # indent-tabs-mode:nil |