From d0605a2fb9da48068c37440f6826b31d23a6805a Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 6 Jun 2023 07:26:31 -0600 Subject: Maint: turn ActionBase into abstract class Align some function sigs that were missing a kwarg. Sorted the imports. Signed-off-by: Mats Wichmann --- CHANGES.txt | 4 ++++ SCons/Action.py | 64 +++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2584583..78cbadf 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -64,6 +64,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER sufficient just to check the build worked. Renamed the fixture dir to follow naming convention in test/MSVC overall, and added a sconstest.skip file, also to follow convention. + - Class ActionBase is now an abstract base class to more accurately + reflect its usage. Derived _ActionAction inherits the ABC, so it + now declares (actually raises NotImplementedError) two methods it + doesn't use so it can be instantiated by unittests and others. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Action.py b/SCons/Action.py index fcc6f3f..8748985 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -100,21 +100,22 @@ way for wrapping up the functions. """ +import inspect import os import pickle import re -import sys import subprocess -from subprocess import DEVNULL -import inspect +import sys +from abc import ABC, abstractmethod from collections import OrderedDict +from subprocess import DEVNULL +from typing import Union import SCons.Debug -import SCons.Util -from SCons.Debug import logInstanceCreation import SCons.Errors -import SCons.Util import SCons.Subst +import SCons.Util +from SCons.Debug import logInstanceCreation # we use these a lot, so try to optimize them from SCons.Util import is_String, is_List @@ -441,7 +442,7 @@ def _do_create_action(act, kw): This handles the fact that passing lists to :func:`Action` itself has different semantics than passing lists as elements of lists. The former will create a :class:`ListAction`, the latter will create a - :class:`CommandAction by converting the inner list elements to strings. + :class:`CommandAction` by converting the inner list elements to strings. """ if isinstance(act, ActionBase): return act @@ -518,11 +519,26 @@ def Action(act, *args, **kw): return _do_create_action(act, kw) -class ActionBase: +class ActionBase(ABC): """Base class for all types of action objects that can be held by other objects (Builders, Executors, etc.) This provides the common methods for manipulating and combining those actions.""" + @abstractmethod + def __call__( + self, + target, + source, + env, + exitstatfunc=_null, + presub=_null, + show=_null, + execute=_null, + chdir=_null, + executor=None, + ): + raise NotImplementedError + def __eq__(self, other): return self.__dict__ == other @@ -534,6 +550,14 @@ class ActionBase: def genstring(self, target, source, env): return str(self) + @abstractmethod + def get_presig(self, target, source, env, executor=None): + raise NotImplementedError + + @abstractmethod + def get_implicit_deps(self, target, source, env, executor=None): + raise NotImplementedError + def get_contents(self, target, source, env): result = self.get_presig(target, source, env) @@ -722,6 +746,16 @@ class _ActionAction(ActionBase): return stat + # Stub these two only so _ActionAction can be instantiated. It's really + # an ABC like parent ActionBase, but things reach in and use it. It's + # not just unittests or we could fix it up with a concrete subclass there. + + def get_presig(self, target, source, env, executor=None): + raise NotImplementedError + + def get_implicit_deps(self, target, source, env, executor=None): + raise NotImplementedError + def _string_from_cmd_list(cmd_list): """Takes a list of command line arguments and returns a pretty @@ -1223,10 +1257,14 @@ class LazyAction(CommandGeneratorAction, CommandAction): c = self.get_parent_class(env) return c.__call__(self, target, source, env, *args, **kw) - def get_presig(self, target, source, env): + def get_presig(self, target, source, env, executor=None): c = self.get_parent_class(env) return c.get_presig(self, target, source, env) + def get_implicit_deps(self, target, source, env, executor=None): + c = self.get_parent_class(env) + return c.get_implicit_deps(self, target, source, env) + def get_varlist(self, target, source, env, executor=None): c = self.get_parent_class(env) return c.get_varlist(self, target, source, env, executor) @@ -1345,14 +1383,14 @@ class FunctionAction(_ActionAction): # more information about this issue. del exc_info - def get_presig(self, target, source, env): + def get_presig(self, target, source, env, executor=None): """Return the signature contents of this callable action.""" try: return self.gc(target, source, env) except AttributeError: return self.funccontents - def get_implicit_deps(self, target, source, env): + def get_implicit_deps(self, target, source, env, executor=None): return [] class ListAction(ActionBase): @@ -1379,7 +1417,7 @@ class ListAction(ActionBase): return SCons.Util.flatten_sequence( [a.presub_lines(env) for a in self.list]) - def get_presig(self, target, source, env): + def get_presig(self, target, source, env, executor=None): """Return the signature contents of this action list. Simple concatenation of the signatures of the elements. @@ -1398,7 +1436,7 @@ class ListAction(ActionBase): return stat return 0 - def get_implicit_deps(self, target, source, env): + def get_implicit_deps(self, target, source, env, executor=None): result = [] for act in self.list: result.extend(act.get_implicit_deps(target, source, env)) -- cgit v0.12 From eb440a02930e3aff35b6dcc85462a4035e764aee Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 8 Jun 2023 07:51:50 -0700 Subject: [ci skip] Add blurb to RELEASE.txt --- RELEASE.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASE.txt b/RELEASE.txt index e71e2b6..865ae30 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -72,7 +72,10 @@ DEVELOPMENT to test files, which allows test lists, exclude lists, and tests on the command line to "not care" about the OS convention for pathname separators. - +- Class ActionBase is now an abstract base class to more accurately + reflect its usage. Derived _ActionAction inherits the ABC, so it + now declares (actually raises NotImplementedError) two methods it + doesn't use so it can be instantiated by unittests and others. Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== -- cgit v0.12