SCons.Util package

Contents

SCons.Util package#

Module contents#

SCons utility functions

This package contains routines for use by other parts of SCons. Candidates for inclusion here are routines that do not need other parts of SCons (other than Util), and have a reasonable chance of being useful in multiple places, rather then being topical only to one module/package.

class SCons.Util.CLVar(initlist=None)[source]#

Bases: UserList

A container for command-line construction variables.

Forces the use of a list of strings intended as command-line arguments. Like collections.UserList, but the argument passed to the initializter will be processed by the Split() function, which includes special handling for string types: they will be split into a list of words, not coereced directly to a list. The same happens if a string is added to a CLVar, which allows doing the right thing with both Append()/Prepend() methods, as well as with pure Python addition, regardless of whether adding a list or a string to a construction variable.

Side effect: spaces will be stripped from individual string arguments. If you need spaces preserved, pass strings containing spaces inside a list argument.

>>> u = UserList("--some --opts and args")
>>> print(len(u), repr(u))
22 ['-', '-', 's', 'o', 'm', 'e', ' ', '-', '-', 'o', 'p', 't', 's', ' ', 'a', 'n', 'd', ' ', 'a', 'r', 'g', 's']
>>> c = CLVar("--some --opts and args")
>>> print(len(c), repr(c))
4 ['--some', '--opts', 'and', 'args']
>>> c += "   strips spaces   "
>>> print(len(c), repr(c))
6 ['--some', '--opts', 'and', 'args', 'strips', 'spaces']
>>> c += ["   does not split or strip   "]
7 ['--some', '--opts', 'and', 'args', 'strips', 'spaces', '   does not split or strip   ']
_abc_impl = <_abc._abc_data object>#
append(item)#

S.append(value) – append value to the end of the sequence

clear() None -- remove all items from S#
copy()#
count(value) integer -- return number of occurrences of value#
extend(other)#

S.extend(iterable) – extend sequence by appending elements from the iterable

index(value[, start[, stop]]) integer -- return first index of value.#

Raises ValueError if the value is not present.

Supporting start and stop arguments is optional, but recommended.

insert(i, item)#

S.insert(index, value) – insert value before index

pop([index]) item -- remove and return item at index (default last).#

Raise IndexError if list is empty or index is out of range.

remove(item)#

S.remove(value) – remove first occurrence of value. Raise ValueError if the value is not present.

reverse()#

S.reverse() – reverse IN PLACE

sort(*args, **kwds)#
class SCons.Util.Delegate(attribute)[source]#

Bases: object

A Python Descriptor class that delegates attribute fetches to an underlying wrapped subject of a Proxy. Typical use:

class Foo(Proxy):
    __str__ = Delegate('__str__')
class SCons.Util.DispatchingFormatter(formatters, default_formatter)[source]#

Bases: Formatter

Logging formatter which dispatches to various formatters.

converter()#
localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,

tm_sec,tm_wday,tm_yday,tm_isdst)

Convert seconds since the Epoch to a time tuple expressing local time. When ‘seconds’ is not passed in, convert the current time instead.

default_msec_format = '%s,%03d'#
default_time_format = '%Y-%m-%d %H:%M:%S'#
format(record)[source]#

Format the specified record as text.

The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

formatException(ei)#

Format and return the specified exception information as a string.

This default implementation just uses traceback.print_exception()

formatMessage(record)#
formatStack(stack_info)#

This method is provided as an extension point for specialized formatting of stack information.

The input data is a string as returned from a call to traceback.print_stack(), but with the last trailing newline removed.

The base implementation just returns the value passed in.

formatTime(record, datefmt=None)#

Return the creation time of the specified LogRecord as formatted text.

This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the ‘converter’ attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the ‘converter’ attribute in the Formatter class.

usesTime()#

Check if the format uses the creation time of the record.

class SCons.Util.DisplayEngine[source]#

Bases: object

A callable class used to display SCons messages.

print_it = True#
set_mode(mode) None[source]#
SCons.Util.IDX(n) bool[source]#

Generate in index into strings from the tree legends.

These are always a choice between two, so bool works fine.

class SCons.Util.LogicalLines(fileobj)[source]#

Bases: object

Wrapper class for the logical_lines() function.

Allows us to read all “logical” lines at once from a given file object.

readlines()[source]#
class SCons.Util.NodeList(initlist=None)[source]#

Bases: UserList

A list of Nodes with special attribute retrieval.

Unlike an ordinary list, access to a member’s attribute returns a NodeList containing the same attribute for each member. Although this can hold any object, it is intended for use when processing Nodes, where fetching an attribute of each member is very commone, for example getting the content signature of each node. The term “attribute” here includes the string representation.

>>> someList = NodeList(['  foo  ', '  bar  '])
>>> someList.strip()
['foo', 'bar']
__getattr__(name) NodeList[source]#

Returns a NodeList of name from each member.

__getitem__(index)[source]#

Returns one item, forces a NodeList if index is a slice.

_abc_impl = <_abc._abc_data object>#
append(item)#

S.append(value) – append value to the end of the sequence

clear() None -- remove all items from S#
copy()#
count(value) integer -- return number of occurrences of value#
extend(other)#

S.extend(iterable) – extend sequence by appending elements from the iterable

index(value[, start[, stop]]) integer -- return first index of value.#

Raises ValueError if the value is not present.

Supporting start and stop arguments is optional, but recommended.

insert(i, item)#

S.insert(index, value) – insert value before index

pop([index]) item -- remove and return item at index (default last).#

Raise IndexError if list is empty or index is out of range.

remove(item)#

S.remove(value) – remove first occurrence of value. Raise ValueError if the value is not present.

reverse()#

S.reverse() – reverse IN PLACE

sort(*args, **kwds)#
class SCons.Util.Proxy(subject)[source]#

Bases: object

A simple generic Proxy class, forwarding all calls to subject.

This means you can take an object, let’s call it ‘obj_a`, and wrap it in this Proxy class, with a statement like this:

proxy_obj = Proxy(obj_a)

Then, if in the future, you do something like this:

x = proxy_obj.var1

since the Proxy class does not have a var1 attribute (but presumably obj_a does), the request actually is equivalent to saying:

x = obj_a.var1

Inherit from this class to create a Proxy.

With Python 3.5+ this does not work transparently for Proxy subclasses that use special dunder method names, because those names are now bound to the class, not the individual instances. You now need to know in advance which special method names you want to pass on to the underlying Proxy object, and specifically delegate their calls like this:

class Foo(Proxy):
    __str__ = Delegate('__str__')
__getattr__(name)[source]#

Retrieve an attribute from the wrapped object.

Raises:

AttributeError – if attribute name doesn’t exist.

get()[source]#

Retrieve the entire wrapped object

SCons.Util.RegError#

alias of _NoError

SCons.Util.RegGetValue(root, key)[source]#
SCons.Util.RegOpenKeyEx(root, key)[source]#
class SCons.Util.Selector[source]#

Bases: dict

A callable dict for file suffix lookup.

Often used to associate actions or emitters with file types.

Depends on insertion order being preserved so that get_suffix() calls always return the first suffix added.

clear() None.  Remove all items from D.#
copy() a shallow copy of D#
fromkeys(value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items() a set-like object providing a view on D's items#
keys() a set-like object providing a view on D's keys#
pop(k[, d]) v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) None.  Update D from dict/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values() an object providing a view on D's values#
SCons.Util.Split(arg) list[source]#

Returns a list of file names or other objects.

If arg is a string, it will be split on whitespace within the string. If arg is already a list, the list will be returned untouched. If arg is any other type of object, it will be returned in a single-item list.

>>> print(Split(" this  is  a  string  "))
['this', 'is', 'a', 'string']
>>> print(Split(["stringlist", " preserving ", " spaces "]))
['stringlist', ' preserving ', ' spaces ']
class SCons.Util.Unbuffered(file)[source]#

Bases: object

A proxy that wraps a file object, flushing after every write.

Delegates everything else to the wrapped object.

write(arg) None[source]#
writelines(arg) None[source]#
class SCons.Util.UniqueList(initlist=None)[source]#

Bases: UserList

A list which maintains uniqueness.

Uniquing is lazy: rather than being enforced on list changes, it is fixed up on access by those methods which need to act on a unique list to be correct. That means things like membership tests don’t have to eat the uniquing time.

__make_unique() None#
_abc_impl = <_abc._abc_data object>#
append(item) None[source]#

S.append(value) – append value to the end of the sequence

clear() None -- remove all items from S#
copy()#
count(value) integer -- return number of occurrences of value[source]#
extend(other) None[source]#

S.extend(iterable) – extend sequence by appending elements from the iterable

index(value[, start[, stop]]) integer -- return first index of value.[source]#

Raises ValueError if the value is not present.

Supporting start and stop arguments is optional, but recommended.

insert(i, item) None[source]#

S.insert(index, value) – insert value before index

pop([index]) item -- remove and return item at index (default last).#

Raise IndexError if list is empty or index is out of range.

remove(item)#

S.remove(value) – remove first occurrence of value. Raise ValueError if the value is not present.

reverse() None[source]#

S.reverse() – reverse IN PLACE

sort(*args, **kwds)[source]#
SCons.Util.WhereIs(file, path=None, pathext=None, reject=None) str | None[source]#

Return the path to an executable that matches file.

Searches the given path for file, considering any filename extensions in pathext (on the Windows platform only), and returns the full path to the matching command of the first match, or None if there are no matches. Will not select any path name or names in the optional reject list.

If path is None (the default), os.environ[PATH] is used. On Windows, If pathext is None (the default), os.environ[PATHEXT] is used.

The construction environment method of the same name wraps a call to this function by filling in path from the execution environment if it is None (and for pathext on Windows, if necessary), so if called from there, this function will not backfill from os.environ.

Note

Finding things in os.environ may answer the question “does file exist on the system”, but not the question “can SCons use that executable”, unless the path element that yields the match is also in the the Execution Environment (e.g. env['ENV']['PATH']). Since this utility function has no environment reference, it cannot make that determination.

exception SCons.Util._NoError[source]#

Bases: Exception

add_note()#

Exception.add_note(note) – add a note to the exception

args#
with_traceback()#

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

SCons.Util._semi_deepcopy_list(obj) list[source]#
SCons.Util._semi_deepcopy_tuple(obj) tuple[source]#
SCons.Util.adjustixes(fname, pre, suf, ensure_suffix: bool = False) str[source]#

Adjust filename prefixes and suffixes as needed.

Add prefix to fname if specified. Add suffix to fname if specified and if ensure_suffix is True

SCons.Util.case_sensitive_suffixes(s1: str, s2: str) bool[source]#

Returns whether platform distinguishes case in file suffixes.

SCons.Util.cmp(a, b) bool[source]#

A cmp function because one is no longer available in Python3.

SCons.Util.containsAll(s, pat) bool[source]#

Check whether string s contains ALL of the items in pat.

SCons.Util.containsAny(s, pat) bool[source]#

Check whether string s contains ANY of the items in pat.

SCons.Util.containsOnly(s, pat) bool[source]#

Check whether string s contains ONLY items in pat.

SCons.Util.dictify(keys, values, result=None) dict[source]#
SCons.Util.do_flatten(sequence, result, isinstance=<built-in function isinstance>, StringTypes=(<class 'str'>, <class 'collections.UserString'>), SequenceTypes=(<class 'list'>, <class 'tuple'>, <class 'collections.deque'>, <class 'collections.UserList'>, <class 'collections.abc.MappingView'>)) None[source]#
SCons.Util.flatten(obj, isinstance=<built-in function isinstance>, StringTypes=(<class 'str'>, <class 'collections.UserString'>), SequenceTypes=(<class 'list'>, <class 'tuple'>, <class 'collections.deque'>, <class 'collections.UserList'>, <class 'collections.abc.MappingView'>), do_flatten=<function do_flatten>) list[source]#

Flatten a sequence to a non-nested list.

Converts either a single scalar or a nested sequence to a non-nested list. Note that flatten() considers strings to be scalars instead of sequences like pure Python would.

SCons.Util.flatten_sequence(sequence, isinstance=<built-in function isinstance>, StringTypes=(<class 'str'>, <class 'collections.UserString'>), SequenceTypes=(<class 'list'>, <class 'tuple'>, <class 'collections.deque'>, <class 'collections.UserList'>, <class 'collections.abc.MappingView'>), do_flatten=<function do_flatten>) list[source]#

Flatten a sequence to a non-nested list.

Same as flatten(), but it does not handle the single scalar case. This is slightly more efficient when one knows that the sequence to flatten can not be a scalar.

SCons.Util.get_native_path(path: str) str[source]#

Transform an absolute path into a native path for the system.

In Cygwin, this converts from a Cygwin path to a Windows path, without regard to whether path refers to an existing file system object. For other platforms, path is unchanged.

SCons.Util.logical_lines(physical_lines, joiner=<built-in method join of str object>)[source]#
SCons.Util.make_path_relative(path) str[source]#

Converts an absolute path name to a relative pathname.

SCons.Util.print_time()[source]#

Hack to return a value from Main if can’t import Main.

SCons.Util.print_tree(root, child_func, prune: bool = False, showtags: int = 0, margin: List[bool] = [False], visited: dict | None = None, lastChild: bool = False, singleLineDraw: bool = False) None[source]#

Print a tree of nodes.

This is like func:render_tree, except it prints lines directly instead of creating a string representation in memory, so that huge trees can be handled.

Parameters:
  • root – the root node of the tree

  • child_func – the function called to get the children of a node

  • prune – don’t visit the same node twice

  • showtags – print status information to the left of each node line The default is false (value 0). A value of 2 will also print a legend for the margin tags.

  • margin – the format of the left margin to use for children of root. Each entry represents a column, where a true value will display a vertical bar and a false one a blank.

  • visited – a dictionary of visited nodes in the current branch if prune is false, or in the whole tree if prune is true.

  • lastChild – this is the last leaf of a branch

  • singleLineDraw – use line-drawing characters rather than ASCII.

SCons.Util.render_tree(root, child_func, prune: bool = False, margin: List[bool] = [False], visited: dict | None = None) str[source]#

Render a tree of nodes into an ASCII tree view.

Parameters:
  • root – the root node of the tree

  • child_func – the function called to get the children of a node

  • prune – don’t visit the same node twice

  • margin – the format of the left margin to use for children of root. Each entry represents a column where a true value will display a vertical bar and a false one a blank.

  • visited – a dictionary of visited nodes in the current branch if prune is false, or in the whole tree if prune is true.

SCons.Util.rightmost_separator(path, sep)[source]#
SCons.Util.sanitize_shell_env(execution_env: dict) dict[source]#

Sanitize all values in execution_env

The execution environment (typically comes from env['ENV']) is propagated to the shell, and may need to be cleaned first.

Parameters:
  • execution_env – The shell environment variables to be propagated

  • shell. (to the spawned)

Returns:

sanitized dictionary of env variables (similar to what you’d get from os.environ)

SCons.Util.semi_deepcopy(obj)[source]#
SCons.Util.semi_deepcopy_dict(obj, exclude=None) dict[source]#
SCons.Util.silent_intern(__string: Any) str[source]#

Intern a string without failing.

Perform sys.intern on the passed argument and return the result. If the input is ineligible for interning the original argument is returned and no exception is thrown.

SCons.Util.splitext(path) tuple[source]#

Split path into a (root, ext) pair.

Same as os.path.splitext but faster.

SCons.Util.unique(seq)[source]#

Return a list of the elements in seq without duplicates, ignoring order.

For best speed, all sequence elements should be hashable. Then unique() will usually work in linear time.

If not possible, the sequence elements should enjoy a total ordering, and if list(s).sort() doesn’t raise TypeError it is assumed that they do enjoy a total ordering. Then unique() will usually work in O(N*log2(N)) time.

If that’s not possible either, the sequence elements must support equality-testing. Then unique() will usually work in quadratic time.

>>> mylist = unique([1, 2, 3, 1, 2, 3])
>>> print(sorted(mylist))
[1, 2, 3]
>>> mylist = unique("abcabc")
>>> print(sorted(mylist))
['a', 'b', 'c']
>>> mylist = unique(([1, 2], [2, 3], [1, 2]))
>>> print(sorted(mylist))
[[1, 2], [2, 3]]
SCons.Util.uniquer_hashables(seq)[source]#
SCons.Util.updrive(path) str[source]#

Make the drive letter (if any) upper case.

This is useful because Windows is inconsistent on the case of the drive letter, which can cause inconsistencies when calculating command signatures.

SCons.Util.wait_for_process_to_die(pid) None[source]#

Wait for specified process to die, or alternatively kill it NOTE: This function operates best with psutil pypi package TODO: Add timeout which raises exception

Submodules#

SCons.Util.envs module#

SCons environment utility functions.

Routines for working with environments and construction variables that don’t need the specifics of the Environment class.

SCons.Util.envs.AddMethod(obj, function: Callable, name: str | None = None) None[source]#

Add a method to an object.

Adds function to obj if obj is a class object. Adds function as a bound method if obj is an instance object. If obj looks like an environment instance, use MethodWrapper to add it. If name is supplied it is used as the name of function.

Although this works for any class object, the intent as a public API is to be used on Environment, to be able to add a method to all construction environments; it is preferred to use env.AddMethod to add to an individual environment.

>>> class A:
...    ...
>>> a = A()
>>> def f(self, x, y):
...    self.z = x + y
>>> AddMethod(A, f, "add")
>>> a.add(2, 4)
>>> print(a.z)
6
>>> a.data = ['a', 'b', 'c', 'd', 'e', 'f']
>>> AddMethod(a, lambda self, i: self.data[i], "listIndex")
>>> print(a.listIndex(3))
d
SCons.Util.envs.AddPathIfNotExists(env_dict, key, path, sep: str = ':') None[source]#

Add a path element to a construction variable.

key is looked up in env_dict, and path is added to it if it is not already present. env_dict[key] is assumed to be in the format of a PATH variable: a list of paths separated by sep tokens.

>>> env = {'PATH': '/bin:/usr/bin:/usr/local/bin'}
>>> AddPathIfNotExists(env, 'PATH', '/opt/bin')
>>> print(env['PATH'])
/opt/bin:/bin:/usr/bin:/usr/local/bin
SCons.Util.envs.AppendPath(oldpath, newpath, sep=':', delete_existing: bool = True, canonicalize: Callable | None = None) list | str[source]#

Append newpath path elements to oldpath.

Will only add any particular path once (leaving the last one it encounters and ignoring the rest, to preserve path order), and will os.path.normpath and os.path.normcase all paths to help assure this. This can also handle the case where oldpath is a list instead of a string, in which case a list will be returned instead of a string. For example:

>>> p = AppendPath("/foo/bar:/foo", "/biz/boom:/foo")
>>> print(p)
/foo/bar:/biz/boom:/foo

If delete_existing is False, then adding a path that exists will not move it to the end; it will stay where it is in the list.

>>> p = AppendPath("/foo/bar:/foo", "/biz/boom:/foo", delete_existing=False)
>>> print(p)
/foo/bar:/foo:/biz/boom

If canonicalize is not None, it is applied to each element of newpath before use.

class SCons.Util.envs.MethodWrapper(obj: Any, method: Callable, name: str | None = None)[source]#

Bases: object

A generic Wrapper class that associates a method with an object.

As part of creating this MethodWrapper object an attribute with the specified name (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).

clone(new_object)[source]#

Returns an object that re-binds the underlying “method” to the specified new object.

SCons.Util.envs.PrependPath(oldpath, newpath, sep=':', delete_existing: bool = True, canonicalize: Callable | None = None) list | str[source]#

Prepend newpath path elements to oldpath.

Will only add any particular path once (leaving the first one it encounters and ignoring the rest, to preserve path order), and will os.path.normpath and os.path.normcase all paths to help assure this. This can also handle the case where oldpath is a list instead of a string, in which case a list will be returned instead of a string. For example:

>>> p = PrependPath("/foo/bar:/foo", "/biz/boom:/foo")
>>> print(p)
/biz/boom:/foo:/foo/bar

If delete_existing is False, then adding a path that exists will not move it to the beginning; it will stay where it is in the list.

>>> p = PrependPath("/foo/bar:/foo", "/biz/boom:/foo", delete_existing=False)
>>> print(p)
/biz/boom:/foo/bar:/foo

If canonicalize is not None, it is applied to each element of newpath before use.

SCons.Util.envs.is_valid_construction_var(varstr: str) bool[source]#

Return True if varstr is a legitimate name of a construction variable.

SCons.Util.filelock module#

SCons file locking functions.

Simple-minded filesystem-based locking. Provides a context manager which acquires a lock (or at least, permission) on entry and releases it on exit.

Usage:

from SCons.Util.filelock import FileLock

with FileLock("myfile.txt", writer=True) as lock:
    print(f"Lock on {lock.file} acquired.")
    # work with the file as it is now locked
class SCons.Util.filelock.FileLock(file: str, timeout: int | None = None, delay: float | None = 0.05, writer: bool = False)[source]#

Bases: object

Lock a file using a lockfile.

Basic locking for when multiple processes may hit an externally shared resource that cannot depend on locking within a single SCons process. SCons does not have a lot of those, but caches come to mind.

Cross-platform safe, does not use any OS-specific features. Provides context manager support, or can be called with acquire_lock() and release_lock().

Lock can be a write lock, which is held until released, or a read lock, which releases immediately upon aquisition - we want to not read a file which somebody else may be writing, but not create the writers starvation problem of the classic readers/writers lock.

TODO: Should default timeout be None (non-blocking), or 0 (block forever),

or some arbitrary number?

Parameters:
  • file – name of file to lock. Only used to build the lockfile name.

  • timeout – optional time (sec) to give up trying. If None, quit now if we failed to get the lock (non-blocking). If 0, block forever (well, a long time).

  • delay – optional delay between tries [default 0.05s]

  • writer – if True, obtain the lock for safe writing. If False (default), just wait till the lock is available, give it back right away.

Raises:

SConsLockFailure – if the operation “timed out”, including the non-blocking mode.

__enter__() FileLock[source]#

Context manager entry: acquire lock if not holding.

__exit__(exc_type, exc_value, exc_tb) None[source]#

Context manager exit: release lock if holding.

__repr__() str[source]#

Nicer display if someone repr’s the lock class.

acquire_lock() None[source]#

Acquire the lock, if possible.

If the lock is in use, check again every delay seconds. Continue until lock acquired or timeout expires.

release_lock() None[source]#

Release the lock by deleting the lockfile.

exception SCons.Util.filelock.SConsLockFailure[source]#

Bases: Exception

Lock failure exception.

add_note()#

Exception.add_note(note) – add a note to the exception

args#
with_traceback()#

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

SCons.Util.hashes module#

SCons hash utility routines.

Routines for working with content and signature hashes.

SCons.Util.hashes.MD5collect(signatures)[source]#

Deprecated. Use hash_collect() instead.

SCons.Util.hashes.MD5filesignature(fname, chunksize: int = 65536)[source]#

Deprecated. Use hash_file_signature() instead.

SCons.Util.hashes.MD5signature(s)[source]#

Deprecated. Use hash_signature() instead.

SCons.Util.hashes._attempt_get_hash_function(hash_name, hashlib_used=<module 'hashlib' from '/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/hashlib.py'>, sys_used=<module 'sys' (built-in)>)[source]#

Wrapper used to try to initialize a hash function given.

If successful, returns the name of the hash function back to the user.

Otherwise returns None.

SCons.Util.hashes._attempt_init_of_python_3_9_hash_object(hash_function_object, sys_used=<module 'sys' (built-in)>)[source]#

Initialize hash function with non-security indicator.

In Python 3.9 and onwards, hashlib constructors accept a keyword argument usedforsecurity, which, if set to False, lets us continue to use algorithms that have been deprecated either by FIPS or by Python itself, as the MD5 algorithm SCons prefers is not being used for security purposes as much as a short, 32 char hash that is resistant to accidental collisions.

In prior versions of python, hashlib returns a native function wrapper, which errors out when it’s queried for the optional parameter, so this function wraps that call.

It can still throw a ValueError if the initialization fails due to FIPS compliance issues, but that is assumed to be the responsibility of the caller.

SCons.Util.hashes._get_hash_object(hash_format, hashlib_used=<module 'hashlib' from '/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/hashlib.py'>, sys_used=<module 'sys' (built-in)>)[source]#

Allocates a hash object using the requested hash format.

Parameters:

hash_format – Hash format to use.

Returns:

hashlib object.

SCons.Util.hashes._set_allowed_viable_default_hashes(hashlib_used, sys_used=<module 'sys' (built-in)>) None[source]#

Check if the default hash algorithms can be called.

This util class is sometimes called prior to setting the user-selected hash algorithm, meaning that on FIPS-compliant systems the library would default-initialize MD5 and throw an exception in set_hash_format. A common case is using the SConf options, which can run prior to main, and thus ignore the options.hash_format variable.

This function checks the DEFAULT_HASH_FORMATS and sets the ALLOWED_HASH_FORMATS to only the ones that can be called. In Python >= 3.9 this will always default to MD5 as in Python 3.9 there is an optional attribute “usedforsecurity” set for the method.

Throws if no allowed hash formats are detected.

SCons.Util.hashes._show_md5_warning(function_name) None[source]#

Shows a deprecation warning for various MD5 functions.

SCons.Util.hashes.get_current_hash_algorithm_used()[source]#

Returns the current hash algorithm name used.

Where the python version >= 3.9, this is expected to return md5. If python’s version is <= 3.8, this returns md5 on non-FIPS-mode platforms, and sha1 or sha256 on FIPS-mode Linux platforms.

This function is primarily useful for testing, where one expects a value to be one of N distinct hashes, and therefore the test needs to know which hash to select.

SCons.Util.hashes.get_hash_format()[source]#

Retrieves the hash format or None if not overridden.

A return value of None does not guarantee that MD5 is being used; instead, it means that the default precedence order documented in SCons.Util.set_hash_format() is respected.

SCons.Util.hashes.hash_collect(signatures, hash_format=None)[source]#

Collects a list of signatures into an aggregate signature.

Parameters:
  • signatures – a list of signatures

  • hash_format – Specify to override default hash format

Returns:

the aggregate signature

SCons.Util.hashes.hash_file_signature(fname, chunksize: int = 65536, hash_format=None)[source]#

Generate the md5 signature of a file

Parameters:
  • fname – file to hash

  • chunksize – chunk size to read

  • hash_format – Specify to override default hash format

Returns:

String of Hex digits representing the signature

SCons.Util.hashes.hash_signature(s, hash_format=None)[source]#

Generate hash signature of a string

Parameters:
  • s – either string or bytes. Normally should be bytes

  • hash_format – Specify to override default hash format

Returns:

String of hex digits representing the signature

SCons.Util.hashes.set_hash_format(hash_format, hashlib_used=<module 'hashlib' from '/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/hashlib.py'>, sys_used=<module 'sys' (built-in)>)[source]#

Sets the default hash format used by SCons.

If hash_format is None or an empty string, the default is determined by this function.

Currently the default behavior is to use the first available format of the following options: MD5, SHA1, SHA256.

SCons.Util.sctypes module#

Various SCons utility functions

Routines which check types and do type conversions.

class SCons.Util.sctypes.Null(*args, **kwargs)[source]#

Bases: object

Null objects always and reliably ‘do nothing’.

class SCons.Util.sctypes.NullSeq(*args, **kwargs)[source]#

Bases: Null

A Null object that can also be iterated over.

SCons.Util.sctypes.get_env_bool(env, name: str, default: bool = False) bool[source]#

Convert a construction variable to bool.

If the value of name in dict-like object env is ‘true’, ‘yes’, ‘y’, ‘on’ (case insensitive) or anything convertible to int that yields non-zero, return True; if ‘false’, ‘no’, ‘n’, ‘off’ (case insensitive) or a number that converts to integer zero return False. Otherwise, or if name is not found, return the value of default.

Parameters:
  • env – construction environment, or any dict-like object.

  • name – name of the variable.

  • default – value to return if name not in env or cannot be converted (default: False).

SCons.Util.sctypes.get_environment_var(varstr) str | None[source]#

Return undecorated construction variable string.

Determine if varstr looks like a reference to a single environment variable, like "$FOO" or "${FOO}". If so, return that variable with no decorations, like "FOO". If not, return None.

SCons.Util.sctypes.get_os_env_bool(name: str, default: bool = False) bool[source]#

Convert an external environment variable to boolean.

Like get_env_bool(), but uses os.environ as the lookup dict.

SCons.Util.sctypes.is_Dict(obj, isinstance=<built-in function isinstance>, DictTypes=(<class 'dict'>, <class 'collections.UserDict'>)) TypeGuard[dict | UserDict][source]#

Check if object is a dict.

SCons.Util.sctypes.is_List(obj, isinstance=<built-in function isinstance>, ListTypes=(<class 'list'>, <class 'collections.UserList'>, <class 'collections.deque'>)) TypeGuard[list | UserList | deque][source]#

Check if object is a list.

SCons.Util.sctypes.is_Scalar(obj, isinstance=<built-in function isinstance>, StringTypes=(<class 'str'>, <class 'collections.UserString'>), Iterable=<class 'collections.abc.Iterable'>) bool[source]#

Check if object is a scalar: not a container or iterable.

SCons.Util.sctypes.is_Sequence(obj, isinstance=<built-in function isinstance>, SequenceTypes=(<class 'list'>, <class 'tuple'>, <class 'collections.deque'>, <class 'collections.UserList'>, <class 'collections.abc.MappingView'>)) TypeGuard[list | tuple | deque | UserList | MappingView][source]#

Check if object is a sequence.

SCons.Util.sctypes.is_String(obj, isinstance=<built-in function isinstance>, StringTypes=(<class 'str'>, <class 'collections.UserString'>)) TypeGuard[str | UserString][source]#

Check if object is a string.

SCons.Util.sctypes.is_Tuple(obj, isinstance=<built-in function isinstance>, tuple=<class 'tuple'>) TypeGuard[tuple][source]#

Check if object is a tuple.

SCons.Util.sctypes.to_String(obj, isinstance=<built-in function isinstance>, str=<class 'str'>, UserString=<class 'collections.UserString'>, BaseStringTypes=<class 'str'>) str[source]#

Return a string version of obj.

Use this for data likely to be well-behaved. Use to_Text() for unknown file data that needs to be decoded.

SCons.Util.sctypes.to_String_for_signature(obj, to_String_for_subst=<function to_String_for_subst>, AttributeError=<class 'AttributeError'>) str[source]#

Return a string version of obj for signature usage.

Like to_String_for_subst() but has special handling for scons objects that have a for_signature() method, and for dicts.

SCons.Util.sctypes.to_String_for_subst(obj, isinstance=<built-in function isinstance>, str=<class 'str'>, BaseStringTypes=<class 'str'>, SequenceTypes=(<class 'list'>, <class 'tuple'>, <class 'collections.deque'>, <class 'collections.UserList'>, <class 'collections.abc.MappingView'>), UserString=<class 'collections.UserString'>) str[source]#

Return a string version of obj for subst usage.

SCons.Util.sctypes.to_Text(data: bytes) str[source]#

Return bytes data converted to text.

Useful for whole-file reads where the data needs some interpretation, particularly for Scanners. Attempts to figure out what the encoding of the text is based upon the BOM bytes, and then decodes the contents so that it’s a valid python string.

SCons.Util.sctypes.to_bytes(s) bytes[source]#

Convert object to bytes.

SCons.Util.sctypes.to_str(s) str[source]#

Convert object to string.

SCons.Util.stats module#

SCons statistics routines.

This package provides a way to gather various statistics during an SCons run and dump that info in several formats

Additionally, it probably makes sense to do stderr/stdout output of those statistics here as well

There are basically two types of stats:

  1. Timer (start/stop/time) for specific event. These events can be hierarchical. So you can record the children events of some parent. Think program compile could contain the total Program builder time, which could include linking, and stripping the executable

  2. Counter. Counting the number of events and/or objects created. This would likely only be reported at the end of a given SCons run, though it might be useful to query during a run.

class SCons.Util.stats.CountStats[source]#

Bases: Stats

_abc_impl = <_abc._abc_data object>#
do_append(label)[source]#
do_nothing(*args, **kw)#
do_print()[source]#
enable(outfp)#
class SCons.Util.stats.MemStats[source]#

Bases: Stats

_abc_impl = <_abc._abc_data object>#
do_append(label)[source]#
do_nothing(*args, **kw)#
do_print()[source]#
enable(outfp)#
class SCons.Util.stats.Stats[source]#

Bases: ABC

_abc_impl = <_abc._abc_data object>#
do_append(label)[source]#
do_nothing(*args, **kw)[source]#
do_print()[source]#
enable(outfp)[source]#
class SCons.Util.stats.TimeStats[source]#

Bases: Stats

_abc_impl = <_abc._abc_data object>#
add_command(command, start_time, finish_time)[source]#
do_append(label)#
do_nothing(*args, **kw)#
do_print()#
enable(outfp)#
total_times(build_time, sconscript_time, scons_exec_time, command_exec_time)[source]#
SCons.Util.stats.add_stat_type(name, stat_object)[source]#

Add a statistic type to the global collection

SCons.Util.stats.write_scons_stats_file()[source]#

Actually write the JSON file with debug information. Depending which of : count, time, action-timestamps,memory their information will be written.