summaryrefslogtreecommitdiffstats
path: root/SCons/Environment.py
diff options
context:
space:
mode:
authorMats Wichmann <mats@linux.com>2020-10-12 12:58:44 (GMT)
committerMats Wichmann <mats@linux.com>2020-10-12 16:23:27 (GMT)
commit890041c42ca0a71c5bb9550a97912fc9d9007d43 (patch)
tree4d1e2e7b50a543fea57ed9196a8c10af0c799f66 /SCons/Environment.py
parentfb03ae927e35e9d68f04366e85a08f508dbfb2c9 (diff)
downloadSCons-890041c42ca0a71c5bb9550a97912fc9d9007d43.zip
SCons-890041c42ca0a71c5bb9550a97912fc9d9007d43.tar.gz
SCons-890041c42ca0a71c5bb9550a97912fc9d9007d43.tar.bz2
Fix/update global AddMethod
Fixes #3028 Signed-off-by: Mats Wichmann <mats@linux.com>
Diffstat (limited to 'SCons/Environment.py')
-rw-r--r--SCons/Environment.py46
1 files changed, 8 insertions, 38 deletions
diff --git a/SCons/Environment.py b/SCons/Environment.py
index 3040427..cc62679 100644
--- a/SCons/Environment.py
+++ b/SCons/Environment.py
@@ -54,6 +54,7 @@ import SCons.SConsign
import SCons.Subst
import SCons.Tool
import SCons.Util
+from SCons.Util import MethodWrapper
import SCons.Warnings
class _Null:
@@ -180,48 +181,17 @@ def _delete_duplicates(l, keep_last):
# Shannon at the following page (there called the "transplant" class):
#
# ASPN : Python Cookbook : Dynamically added methods to a class
-# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732
+# https://code.activestate.com/recipes/81732/
#
# We had independently been using the idiom as BuilderWrapper, but
# factoring out the common parts into this base class, and making
# BuilderWrapper a subclass that overrides __call__() to enforce specific
# Builder calling conventions, simplified some of our higher-layer code.
+#
+# Note: MethodWrapper moved to SCons.Util as it was needed there
+# and otherwise we had a circular import problem.
-class MethodWrapper:
- """
- A generic Wrapper class that associates a method (which can
- actually be any callable) with an object. As part of creating this
- MethodWrapper object an attribute with the specified (by default,
- the name of the supplied method) is added to the underlying object.
- When that new "method" is called, our __call__() method adds the
- object as the first argument, simulating the Python behavior of
- supplying "self" on method calls.
-
- We hang on to the name by which the method was added to the underlying
- base class so that we can provide a method to "clone" ourselves onto
- a new underlying object being copied (without which we wouldn't need
- to save that info).
- """
- def __init__(self, object, method, name=None):
- if name is None:
- name = method.__name__
- self.object = object
- self.method = method
- self.name = name
- setattr(self.object, name, self)
-
- def __call__(self, *args, **kwargs):
- nargs = (self.object,) + args
- return self.method(*nargs, **kwargs)
-
- def clone(self, new_object):
- """
- Returns an object that re-binds the underlying "method" to
- the specified new object.
- """
- return self.__class__(new_object, self.method, self.name)
-
-class BuilderWrapper(MethodWrapper):
+class BuilderWrapper(SCons.Util.MethodWrapper):
"""
A MethodWrapper subclass that that associates an environment with
a Builder.
@@ -248,7 +218,7 @@ class BuilderWrapper(MethodWrapper):
target = [target]
if source is not None and not SCons.Util.is_List(source):
source = [source]
- return MethodWrapper.__call__(self, target, source, *args, **kw)
+ return super().__call__(target, source, *args, **kw)
def __repr__(self):
return '<BuilderWrapper %s>' % repr(self.name)
@@ -2377,7 +2347,7 @@ class OverrideEnvironment(Base):
# Environment they are being constructed with and so will not
# have access to overrided values. So we rebuild them with the
# OverrideEnvironment so they have access to overrided values.
- if isinstance(attr, (MethodWrapper, BuilderWrapper)):
+ if isinstance(attr, MethodWrapper):
return attr.clone(self)
else:
return attr