Welcome to CLU’s documentation!
clu.abstract
- class clu.abstract.AppName(*args, **kwargs)
- class clu.abstract.AsyncManagedContext
- class clu.abstract.BaseDescriptor
- class clu.abstract.BasePath(name, bases, attributes, basepath='/', **kwargs)
A metaclass to assign a “basepath” class property, extracted from a “basepath” class keyword, to a new slotted type.
- class clu.abstract.Cloneable
An abstract class representing something “clonable.” A cloneable subclass need only implement the one method, “clone()” – taking no arguments and returning a new instance of said class, populated as a cloned copy of the instance upon which the “clone()” method was called.
Implementors are at liberty to use shallow- or deep-copy methods, or a mixture of the two, in creating these cloned instances.
- abstract clone(deep=False, memo=None)
Return a cloned copy of this instance
- class clu.abstract.DataDescriptor
- class clu.abstract.Descriptor(value, name=None)
A simple, generic desciptor, wrapping one value, and storing its name
- class clu.abstract.Format
An abstract class representing something that formats something else. It only offers the one abstract method, “render(…)” at this time.
- abstract render(string)
Render a string with respect to the Format instance.
- class clu.abstract.ManagedContext
- class clu.abstract.MappingViewRepr
A ReprWrapper class that simply returns the repr for a “self._mapping” value – of which most MappingView types make use.
- inner_repr()
Return the repr string for “self._mapping”
- class clu.abstract.NamedDescriptor
- class clu.abstract.NonFormat(*args)
A “format” type whose “render(…)” method is a no-op.
- render(string)
Return a string, unchanged
- class clu.abstract.NonSlotted(name, bases, attributes, **kwargs)
A metaclass that ensures its classes, and all subclasses, will •not• use the “__slots__” optimization.
- class clu.abstract.ReprWrapper
ReprWrapper fills in a default template for __repr__ results, based on a standard display including the type name and the hex ID of the instance:
TypeName( ••• ) @ 0xDEADBEEF
… The “ ••• ” string gets filled in by a new abstract method, “inner_repr()”, which subclasses must provide. This new method takes no arguments and should return a string.
Example 1: Return the repr of a relevant sub-instance value:
FlatOrderedSet((‘a’, ‘b’, ‘c’, ‘d’)) @ 0x115299650
… Note that the parenthesized value is the repr of an internal tuple value. The “inner_repr()” method returns something like “repr(self.internal_tuple)”.
Example 2: Return some interesting meta-information:
Env([prefix=“CLU_*”, namespaces=4, keys=13]) @ 0x115373690
… Here the return value of “inner_repr()” is composed freely, like any other repr-string, instead of delegated wholesale to another objects repr value.
- abstract inner_repr()
Return a repr string for instances of this class
- class clu.abstract.Sanitizer
A base format type, with a slot for a compiled regular expression.
- render(string)
Render a string with respect to the Format instance.
- class clu.abstract.Slotted(name, bases, attributes, **kwargs)
A metaclass that ensures its classes, and all subclasses, will be slotted types.
- class clu.abstract.SlottedFormat
A base format type, with a slot for a format-operation string.
- class clu.abstract.SlottedRepr
A simple, default version of a ReprWrapper class that uses its inheritance chain’s value for “__slots__” to build the repr string for its instances
- inner_repr()
Use the union of __slots__, defined across this classes’ inheritance chain, to build the instances’ repr string
- class clu.abstract.Unhashable
- class clu.abstract.UnhashableMeta(name, bases, attributes, **kwargs)
A slotted metaclass that ensures its classes, and all subclasses, will not be hashable types.
- class clu.abstract.ValueDescriptor(value, name=None)
A descriptor whose repr-string tries to be a literal reflection of its wrapped value
clu.all
- clu.all.import_all_modules(basepath, appname, exportername='exporter')
Import all modules that use the “clu.exporting.ExporterBase” mechanism for listing and exporting their module contents, for a given «basepath», «appname», and «exportername» – where:
“basepath” is the root path of a Python package;
“appname” is a valid module name within «basepath»; and
“exportername” is the name of the “Exporter” instances.
- clu.all.import_clu_modules()
Import all CLU modules that use the “clu.exporting.Exporter” mechanism for listing and exporting their module contents
- clu.all.inline_tests(testername='test')
Generator over all CLU modules that contain inline tests
clu.api
clu.application
- class clu.application.AppBase(name, doc=None)
clu.compliation
clu.config
- class clu.config.abc.FlatOrderedSet(*things, predicate=<function always>)
FlatOrderedSet is a structure designed to coalesce any nested elements with which it is initialized into a flat, ordered sequence devoid of None-values. It has both set and sequence properties – membership can be tested as with a set; comparisons can be made with less-than and greater-than operators, as with a set; recombinant operations are performed with binary-and and binary-or operators, as with a set – but like a sequence, iterating a FlatOrderedSet has a stable and deterministic order and items may be retrieved from an instance using subscript indexes (e.g. flat_ordered_set[3]).
Here’s an example of the coalescing behavior:
stuff = FlatOrderedSet(None, “a”, “b”, FlatOrderedSet(“c”, None, “a”, “d”)) summary = FlatOrderedSet(“a”, “b”, “c”, “d”)
assert stuff == summary
One can optionally specify, as a keyword-only argument, a unary boolean function “predicate” that will be used to filter out any of the items used to initialize the FlatOrderedSet for which the predicate returns a Falsey value.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- inner_repr()
Return a repr string for instances of this class
- class clu.config.abc.FrozenKeyMap
The abstract base class for frozen – immutable once created – namespaced mappings, also known as “FrozenKeyMaps”.
Subclasses must implement a bunch of typical Python dunder methods like e.g. ‘__iter__’, ‘__len__’ &c, plus a “namespaces()” method which takes no arguments and then iterates in order over all the THATS RIGHT YOU GUESSED IT namespaces contained in the KeyMap’s keys.
Optionally one may override ‘__missing__’, which can be kind of interesting, and ‘__bool__’ which generally is less so. Q.v. the “FrozenKeyMapBase” source supra. for further deets, my doggie
- get(key, *namespaces, default=<class 'clu.constants.consts.NoDefault'>)
Retrieve a (possibly namespaced) value for a given key.
An optional default value may be specified, to be returned if the key in question is not found in the mapping.
- items(*namespaces, unprefixed=False)
Return a namespaced view over either all key/value pairs in the mapping, or over only those key/value pairs in the mapping whose keys match the specified namespace values.
- keys(*namespaces, unprefixed=False)
Return a namespaced view over either all keys in the mapping, or over only those keys in the mapping matching the specified namespace values.
- namespaces()
Iterate over all of the namespaces defined in the mapping.
- submap(*namespaces, unprefixed=False)
Return a standard dict containing only the namespaced items.
- values(*namespaces, unprefixed=False)
Return a namespaced view over either all values in the mapping, or over only those values in the mapping whose keys match the specified namespace values.
- class clu.config.abc.FrozenKeyMapBase
Abstract sub-base interface class for immutable namespaced mappings. This is the root of the namespaced-mapping (née “KeyMap”) class tower.
Don’t subclass this, it’s just a bunch of abstract dunder methods and other stuff to pass the buck properly from the ‘collections.abc’ bases on up to our own API. You, for your purposes, should employ “FrozenKeyMap” (without the “Base”) – q.v. the class definition below, sub.
- abstract namespaces()
Iterate over all of the namespaces defined in the mapping.
- class clu.config.abc.KeyMap
The abstract base class for mutable namespaced mappings (née “KeyMaps”).
Subclasses must implement all the requisite Python dunder methods required by the ancestor “FrozenKeyMap”, like e.g. ‘__iter__’, ‘__len__’ &c, plus also a “namespaces()” method which takes no arguments and iterates in order over all namespaces contained in the KeyMap’s keys.
OK AND FURTHERMORE for mutability, you also need to do your own ‘__setattr__’ and ‘__delattr__’ (which maybe we’ll make that last one optional as delete methods in Python are totally gauche and a sign of a sort of naïve vulgar un-Pythonicism, I feel like).
Optionally one may override ‘__missing__’, which can be kind of interesting, and ‘__bool__’ which generally is less so. Q.v. the “FrozenKeyMapBase” source supra. for further deets, my doggie
- clear(*namespaces, unprefixed=False)
Remove all items from the mapping – either in totality, or only those matching a specific namespace.
- delete(key, *namespaces)
Delete a (possibly namespaced) value from the mapping.
- pop(key, *namespaces, default=<class 'clu.constants.consts.NoDefault'>)
Pop a (possibly namespaced) value off the mapping and eitehr return it or a default if it doesn’t exist – raising a KeyError if no default is given.
- set(key, value, *namespaces)
Set a (possibly namespaced) value for a given key.
- update([E, ]**F) None.
Update D from dict/iterable E and/or F.
- class clu.config.abc.KeyMapBase
Abstract sub-base interface class for mutable namespaced mappings.
Don’t subclass this anemic vestigial thing. You want “KeyMap” (sans the “Base”) as your ancestor; see below.
- abstract freeze()
Return a “frozen” – or immutable – version of the KeyMap instance.
- class clu.config.abc.NamespaceWalker
A NamespaceWalker type implements a “walk(…)” method for iterating over namespaced key-value items.
In return for furnishing this one method, NamespaceWalkers receive implementations for “__iter__()”, “__len__()”, “__contains__(…)”, and “__getitem__(…)”, plus optimized view-types returned from their “keys(…)”, “items(…)” and “values(…)” calls, a “flatten(…)” method, and an optimized version of the “namespaces()” method, ALL FREE!!
For KeyMap types whose backend mechanics are well-suited to being “walked” (as it were) this is a remarkably good deal, would you not agree??
See the docstring for “NamespaceWalker.walk(…)” for details. The original “walk(…)” output format and model implementation were derived from this StackOverflow answer:
- flatten(cls=None)
Dearticulate an articulated KeyMap instance into one that is flat.
- items(*namespaces, unprefixed=False)
Return a namespaced view over either all key/value pairs in the mapping, or over only those key/value pairs in the mapping whose keys match the specified namespace values.
- keys(*namespaces, unprefixed=False)
Return a namespaced view over either all keys in the mapping, or over only those keys in the mapping matching the specified namespace values.
- values(*namespaces, unprefixed=False)
Return a namespaced view over either all values in the mapping, or over only those values in the mapping whose keys match the specified namespace values.
- abstract walk()
The “walk(…)” method backs all other “NamespaceWalker” methods.
Concrete subclasses must implement “walk(…)” such that it iterates over all items in a given instance, yielding them in a form like:
- for *namespaces, key, value in self.walk():
# …
… So an item with no namespaces would yield “[‘key’, ‘value’]”, but one with three would yield “[‘do’, ‘re’, ‘me’, ‘key’, ‘value’]”.
See the “mapwalk(…)” and “envwalk(…)” function implementations, for practical examples of how this can work. “mapwalk(…)” iterates over nested dictionaries-of-dictionaries, and “envwalk(…)” transforms the values in an environment dictionary (like ‘os.environ’) into the above namespaced-key-value format, as noted.
N.B. Implementors may wish to write their own less-näive versions of “__contains__(…)” and “__getitem__(…)” in their subclasses, depending on how such subclasses work internally – in many cases, implementing these methods using domain-specific logic will be faster and/or less pathological than doing so using only “walk(…)”.
- class clu.config.abc.functional_and(*functions)
The “functional_and” FlatOrderedSet subclass is designed to hold a sequence of functions. Instances of “functional_and” are callable – calling “functional_and_instance(thing)” will apply each item held by the instance to “thing”, returning True only if the instances’ functions all return a Truthy value.
- class clu.config.abc.functional_set(*functions)
The “functional_set” FlatOrderedSet subclass is designed to hold a sequence of functions. Instances of “functional_set” are callable – calling “functional_set_instance(thing)” will successively apply each function to either “thing” or the return value of the previous function – finally returning the last return value when the sequence of functions has been exhausted.
- class clu.config.env.Environ(environment=None, appname=None, **updates)
- freeze()
Return a “frozen” – or immutable – version of the KeyMap instance.
- setenv(envkey, value)
Set the value for a key directly in the backend environment.
- unsetenv(envkey)
Delete a key directly from the backend environment
- class clu.config.env.FrozenEnviron(environment=None, appname=None, **updates)
A concrete immutable – or frozen – KeyMap class wrapping a frozen copy of an environment-variable dictionary.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- envkeys()
Get a view on the dictionary keys from the backend environment.
- getenv(envkey, default=<class 'clu.constants.consts.NoDefault'>)
Retrieve a key directly from the backend environment.
- hasenv(envkey)
Query the backend environment dictionary for a key.
- inner_repr()
Return some readable meta-information about this instance
- walk()
Iteratively walk the backend environment access dictionary.
- clu.config.env.envwalk(appname, mapping)
Iteratively walk an environment-variable mapping, selecting only the variables prefixed for the given appname, and convert environment-variable-packed namespaced key-value pairs into the format expected for a “walk(…)” function.
- class clu.config.keymap.Flat(dictionary=None, **updates)
A concrete mutable KeyMap class with a flat internal topology.
- freeze()
Return a “frozen” – or immutable – version of the KeyMap instance.
- class clu.config.keymap.FrozenFlat(dictionary=None, **updates)
A concrete immutable – or frozen – KeyMap class with a flat internal topology.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- inner_repr()
Return a repr string for instances of this class
- nestify(cls=None)
Articulate a flattened KeyMap instance out into one that is nested.
- class clu.config.keymap.FrozenNested(tree=None, **updates)
A concrete immutable – or frozen – KeyMap class with an articulated – or, if you will, a nested – internal topology.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- inner_repr()
Return a repr string for instances of this class
- submap(*namespaces, unprefixed=False)
Return a standard dict containing only the namespaced items.
- walk()
Iteratively walk the nested KeyMap’s tree of dicts.
- class clu.config.keymap.Nested(tree=None, **updates)
A concrete mutable KeyMap class with an articulated (or nested) internal topology.
- freeze()
Return a “frozen” – or immutable – version of the KeyMap instance.
- clu.config.keymap.mapwalk(mapping, pre=None)
Iteratively walk a nested mapping. Based on https://stackoverflow.com/a/12507546/298171
- class clu.config.keymapview.KeyMapItemsView(mapping, *namespaces)
A KeyMap items view.
- class clu.config.keymapview.KeyMapKeysView(mapping, *namespaces)
A KeyMap key view.
- class clu.config.keymapview.KeyMapValuesView(mapping, *namespaces)
A KeyMap values view.
- class clu.config.keymapview.KeyMapViewBase(mapping, *namespaces)
The base class for KeyMap view classes.
These view classes correspond to, but do not inherit directly from, the descendants of “collections.abc.MappingView”. They have been specially kitted out to deal with KeyMap namespaces: each instance has a ‘mapping’ attribute referring to the parent KeyMap instance, a ‘namespaces’ iterable attribute with the unconcatenated namespace parts for which the instance was allocated, and a ‘prefix’ shortcut attribute containing the concatenated namespace parts as a string prefix.
Each concrete subclass of KeyMapViewBase registers itself as a “virtual subclass” of its corresponding ‘collections.abc’ view class, like for good measure.
- class clu.config.keymapview.NamespaceWalkerItemsView(mapping, *namespaces)
An items view specifically tailored to NamespaceWalker types.
- class clu.config.keymapview.NamespaceWalkerKeysView(mapping, *namespaces)
A keys view specifically tailored to NamespaceWalker types.
- class clu.config.keymapview.NamespaceWalkerValuesView(mapping, *namespaces)
A values view specifically tailored to NamespaceWalker types.
- class clu.config.keymapview.NamespaceWalkerViewBase(mapping, *namespaces)
A view abstract base class tailored to NamespaceWalker types; specifically, it overrides “__len__(…)” to better utilize the underlying mapping types’ “walk(…)” method.
- clu.config.ns.compare_ns(iterone, itertwo)
Boolean predicate to compare a pair of namespace iterables, value-by-value
- clu.config.ns.concatenate_env(*namespaces)
Concatenate and UPPERCASE namespaces, per environment variables.
- clu.config.ns.concatenate_ns(*namespaces)
Return the given namespace(s), concatenated with the namespace separator.
- clu.config.ns.get_ns(nskey)
Get the namespace portion of a namespaced key as a packed string.
- clu.config.ns.nskey_from_env(envkey)
Repack an environment-variable key name as a packed namespace key.
- clu.config.ns.nskey_to_env(appname, nskey)
Repack a packed namespace key, with a given appname, as an environment variable key name.
- clu.config.ns.pack_env(appname, key, *namespaces)
Transform a mapping key, along with optional “namespaces” values and the provided “appname” value, into an environment- variable name. Like e.g., for an appname of “YoDogg” and a namespace value of “iheard”, the environment variable prefix would work out such that a variable with a key value of “youlike” would look like this:
YODOGG_IHEARD_YOULIKE
- ^^^^^^ ^^^^^^ ^^^^^^^
- | || +––––– mapping key (uppercased)+–––––––––––– namespaces (uppercased, one value)
+––––––––––––––––––– app name (uppercased)
- clu.config.ns.pack_ns(key, *namespaces)
Pack a key and a set of (optional) namespaces into a namespaced key.
To wit: if called as “pack_ns(‘i-heard, ‘yo’, ‘dogg’)” the return value will be the string “yo:dogg:i-heard”.
If no namespaces are provided (like e.g. “pack_ns(‘wat’)”) the return value will be the string “wat”.
- clu.config.ns.prefix_env(appname, *namespaces)
Determine the environment-variable prefix based on a given set of namespaces and the provided “appname” value. Like e.g., for an appname of “YoDogg” and a namespace value of “iheard”, the environment variable prefix would work out such that a variable with a key value of “youlike” would look like this:
YODOGG_IHEARD_YOULIKE
- ^^^^^^ ^^^^^^ ^^^^^^^
- | || +––––– mapping key (uppercased)+–––––––––––– namespaces (uppercased, one value)
+––––––––––––––––––– app name (uppercased)
- clu.config.ns.prefix_for(*namespaces)
Return the prefix string for the given namespace(s)
- clu.config.ns.split_ns(namespaced)
Split a namespaced string into its components
- clu.config.ns.startswith_ns(putative, prefix)
Boolean predicate to compare a pair of namespace iterables, returning True if the first starts with the second.
Do not confuse this with the helper function “compare_ns(…)”, defined below, which returns False if the namespace iterables in question aren’t exactly alike.
- clu.config.ns.strip_ns(nskey)
Strip all namespace-related prefixing from a namespaced key
- clu.config.ns.unpack_env(envkey)
Unpack the appname, possible namespaces, and the key from an environment variable key name.
- clu.config.ns.unpack_ns(nskey)
Unpack a namespaced key into a set of namespaces and a key name.
To wit: if the namespaced key is “yo:dogg:i-heard”, calling “unpack_ns(…)” on it will return the tuple (‘i-heard’, (‘yo’, ‘dogg’));
If the key is not namespaced (like e.g. “wat”) the “unpack_ns(…)” call will return the tuple (‘wat’, tuple()).
- clu.config.ns.validate_ns(*namespaces)
Raise a ValueError if any of the given namespaces are invalid.
- class clu.config.proxy.KeyMapProxy(keymap)
-
- freeze()
Return a “frozen” – or immutable – version of the KeyMap instance.
- class clu.config.proxy.KeyMapView(keymap)
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- inner_repr()
Return a repr string for instances of this class
- items(*namespaces, unprefixed=False)
Return a namespaced view over either all key/value pairs in the mapping, or over only those key/value pairs in the mapping whose keys match the specified namespace values.
- keys(*namespaces, unprefixed=False)
Return a namespaced view over either all keys in the mapping, or over only those keys in the mapping matching the specified namespace values.
- namespaces()
Iterate over all of the namespaces defined in the mapping.
- values(*namespaces, unprefixed=False)
Return a namespaced view over either all values in the mapping, or over only those values in the mapping whose keys match the specified namespace values.
- clu.config.proxy.selfcheck(function)
Decorator abstracting a boolean self-check for weakref methods
clu.csv
- clu.csv.max_segments(csv_data)
max_segments(«uneven CSV data») → •largest line segment count•
- clu.csv.pad_csv(csv_data)
pad_csv(«uneven CSV data») → «padded CSV data»
- clu.csv.pad_line(line, padding)
pad_line(«uneven CSV lines») → «padded CSV lines»
- clu.csv.pad_segments(csv_data, padding)
pad_segments(«uneven CSV line fragments») → «padded CSV lines»
- clu.csv.segments(line)
segments(«CSV line») → •line segment count•
clu.constants
- class clu.constants.consts.NoDefault(*a, **k)
A singleton object to signify a lack of an argument.
- clu.constants.consts.pytuple(*attrs) → turns ('do', 're', 'mi') into ('__do__', '__re__', '__mi__')
- class clu.constants.enums.CSIDL(value)
An enumeration encapsulating Windows CSIDLs.
- classmethod for_name(name)
Retrieve a CSIDL by name (case-insensitively)
- property fullname
A CSIDL’s “full name” – which is basically of the form “CSIDL_NAME_STRING”
- to_int()
A given CSIDL’s integer value
- to_string()
A given CSIDL’s full name
- class clu.constants.enums.System(value)
An enumeration class for dealing with the name of the underlying operating system upon which we are running.
- classmethod all()
Get a generator over all System values
- classmethod determine()
Determine the System value for the current platform
- classmethod from_string(string)
Retrieve a System value by name (case-insensitively)
- property is_current
A boolean value expressing if a given System value represents the current running operating system
- property is_unix_based
A boolean value expressing if a given System value represents a UNIX-based operating system
- classmethod match(value)
Match a system to a value – the nature of which can be:
a string (unicode or bytes-type) naming the system;
an existing “System” enum-member value; or
an arbitrary alternative enum-member value.
… The matched system is returned. If no match is found, a ValueError will be raised.
- property os_name
A given System value’s “os_name” (as reported when running within a java-based environment e.g. Jython)
- property sys_name
A given System value’s name, lowercased
- to_string()
A given System value’s name
- classmethod unixes()
Get a generator over the UNIX-based System values
- exception clu.constants.exceptions.BadDotpathWarning
Conversion from a path to a dotpath resulted in a bad dotpath … likely there are invalid characters like dashes in there.
- exception clu.constants.exceptions.CDBError
A problem with a compilation database
- exception clu.constants.exceptions.ConfigurationError
An error that occurred in the course of macro configuration
- exception clu.constants.exceptions.ExecutionError
An error during the execution of a shell command
- exception clu.constants.exceptions.ExportError
An error during the preparation of an item for export
- exception clu.constants.exceptions.ExportWarning
A non-life-threatening condition that occured during an export
- exception clu.constants.exceptions.FilesystemError
An error that occurred while mucking about with the filesystem
- exception clu.constants.exceptions.KeyValueError
An error raised in the clu.keyvalue API
- exception clu.constants.exceptions.Nondeterminism
An error indicating a “heisenbug” – a nondeterministic problem.
- exception clu.constants.exceptions.UnusedValueWarning
A warning issued when an AppDirs instance is initialized using a value or values that aren’t currently utilized on the platform upon which we are currently running
- class clu.constants.polyfills.AutoType
Simple polyfill for enum.auto (which apparently does not exist in PyPy 2 for some reason)
- class clu.constants.polyfills.Enum(value)
Generic enumeration.
Derive from this class to define new enumerations.
- name
The name of the Enum member.
- value
The value of the Enum member.
- class clu.constants.polyfills.EnumMeta(cls, bases, classdict, **kwds)
Metaclass for Enum
- class clu.constants.polyfills.Path(*args, **kwargs)
PurePath subclass that can make system calls.
Path represents a filesystem path but unlike PurePath, also offers methods to do system calls on path objects. Depending on your system, instantiating a Path will return either a PosixPath or a WindowsPath object. You can also instantiate a PosixPath or WindowsPath directly, but cannot instantiate a WindowsPath on a POSIX system or vice versa.
- absolute()
Return an absolute version of this path. This function works even if the path doesn’t point to anything.
No normalization is done, i.e. all ‘.’ and ‘..’ will be kept along. Use resolve() to get the canonical path to a file.
- chmod(mode)
Change the permissions of the path, like os.chmod().
- classmethod cwd()
Return a new path pointing to the current working directory (as returned by os.getcwd()).
- exists()
Whether this path exists.
- expanduser()
Return a new path with expanded ~ and ~user constructs (as returned by os.path.expanduser)
- glob(pattern)
Iterate over this subtree and yield all existing files (of any kind, including directories) matching the given relative pattern.
- group()
Return the group name of the file gid.
- classmethod home()
Return a new path pointing to the user’s home directory (as returned by os.path.expanduser(‘~’)).
- is_block_device()
Whether this path is a block device.
- is_char_device()
Whether this path is a character device.
- is_dir()
Whether this path is a directory.
- is_fifo()
Whether this path is a FIFO.
- is_file()
Whether this path is a regular file (also True for symlinks pointing to regular files).
- is_mount()
Check if this path is a POSIX mount point
- is_socket()
Whether this path is a socket.
- is_symlink()
Whether this path is a symbolic link.
- iterdir()
Iterate over the files in this directory. Does not yield any result for the special paths ‘.’ and ‘..’.
- lchmod(mode)
Like chmod(), except if the path points to a symlink, the symlink’s permissions are changed, rather than its target’s.
- link_to(target)
Make the target path a hard link pointing to this path.
Note this function does not make this path a hard link to target, despite the implication of the function and argument names. The order of arguments (target, link) is the reverse of Path.symlink_to, but matches that of os.link.
- lstat()
Like stat(), except if the path points to a symlink, the symlink’s status information is returned, rather than its target’s.
- mkdir(mode=511, parents=False, exist_ok=False)
Create a new directory at this given path.
- open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
Open the file pointed by this path and return a file object, as the built-in open() function does.
- owner()
Return the login name of the file owner.
- read_bytes()
Open the file in bytes mode, read it, and close the file.
- read_text(encoding=None, errors=None)
Open the file in text mode, read it, and close the file.
- readlink()
Return the path to which the symbolic link points.
- rename(target)
Rename this path to the target path.
The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.
Returns the new Path instance pointing to the target path.
- replace(target)
Rename this path to the target path, overwriting if that path exists.
The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.
Returns the new Path instance pointing to the target path.
- resolve(strict=False)
Make the path absolute, resolving all symlinks on the way and also normalizing it (for example turning slashes into backslashes under Windows).
- rglob(pattern)
Recursively yield all existing files (of any kind, including directories) matching the given relative pattern, anywhere in this subtree.
- rmdir()
Remove this directory. The directory must be empty.
- samefile(other_path)
Return whether other_path is the same or not as this file (as returned by os.path.samefile()).
- stat()
Return the result of the stat() system call on this path, like os.stat() does.
- symlink_to(target, target_is_directory=False)
Make this path a symlink pointing to the target path. Note the order of arguments (link, target) is the reverse of os.symlink.
- touch(mode=438, exist_ok=True)
Create this file with the given access mode, if it doesn’t exist.
- unlink(missing_ok=False)
Remove this file or link. If the path is a directory, use rmdir() instead.
- write_bytes(data)
Open the file in bytes mode, write to it, and close the file.
- write_text(data, encoding=None, errors=None)
Open the file in text mode, write to it, and close the file.
- class clu.constants.polyfills.auto
Instances are replaced with an appropriate value in Enum class suites.
- clu.constants.polyfills.cache_from_source(path, debug_override=None, *, optimization=None)
Given the path to a .py file, return the path to its .pyc file.
The .py file does not need to exist; this simply returns the path to the .pyc file calculated as if the .py file were imported.
The ‘optimization’ parameter controls the presumed optimization level of the bytecode file. If ‘optimization’ is not None, the string representation of the argument is taken and verified to be alphanumeric (else ValueError is raised).
The debug_override parameter is deprecated. If debug_override is not None, a True value is the same as setting ‘optimization’ to the empty string while a False value is equivalent to setting ‘optimization’ to ‘1’.
If sys.implementation.cache_tag is None then NotImplementedError is raised.
- clu.constants.polyfills.lru_cache(maxsize=128, typed=False)
Least-recently-used cache decorator.
If maxsize is set to None, the LRU features are disabled and the cache can grow without bound.
If typed is True, arguments of different types will be cached separately. For example, f(3.0) and f(3) will be treated as distinct calls with distinct results.
Arguments to the cached function must be hashable.
View the cache statistics named tuple (hits, misses, maxsize, currsize) with f.cache_info(). Clear the cache and statistics with f.cache_clear(). Access the underlying function with f.__wrapped__.
See: https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)
- clu.constants.polyfills.reduce(function, sequence[, initial]) value
Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
- clu.constants.polyfills.unique(enumeration)
Class decorator for enumerations ensuring unique member values.
clu.dicts
- class clu.dicts.ChainMap(*dicts, **overrides)
- clear()
Remove all items from the top mapping of the ChainMap.
- clone(deep=False, memo=None)
Return a cloned copy of the ChainMap instance
- flatten()
Dearticulate the ChainMap instances’ internal map stack into a new, single, flat dictionary instance.
- classmethod fromitems(*iterables, **overrides)
Create a new ChainMap instance, using key-value pairs obtained from one or more iterables, with any keyword arguments serving as optional overrides.
- classmethod fromkeys(iterable, *args, **overrides)
Create a new ChainMap instance, using keys plucked from “iterable”, and values harvested from the subsequent variadic arguments.
- get(key, default=<class 'clu.constants.consts.NoDefault'>)
Return the value for “key” if it is in any of the mappings in the ChainMap, else “default”.
If no “default” is specified and the key is not found, a KeyError will be raised.
- classmethod is_a(instance)
Check if an instance is a ChainMap of any sort – this covers:
this class (whichever it may be, derived or otherwise)
the root clu.dicts.ChainMap type, and
the original collections.ChainMap type as well.
- mapchain()
Return a generator over all of the ChainMap’s mappings
- mapcontaining(itx, default=<class 'clu.constants.consts.NoDefault'>)
Search the ChainMap’s internal mappings for an item, by name, and return the first mapping in which an item by this name can be found.
A default value, returned when no mappings are to be found containing an item by the specified name, may optionally be passsed in as well.
- pop(key, default=<class 'clu.constants.consts.NoDefault'>)
chainmap.pop(key[, default]) → v, remove specified “key” from the top mapping of the ChainMap, and return the corresponding value.
If “key” is not found, “default” is returned if given – otherwise a KeyError is raised.
- popitem() → (key, value), remove & return a (key, value)
pair, nondeterministically, as a 2-tuple; but raise a KeyError if the top mapping of the ChainMap (aka ‘self.maps[0]’) is empty.
- property rest
Return all of the mappings behind the first – aka
cdr(maps)
- shift()
Create and return a new ChainMap instance from “maps[1:]” – the “cdr(maps)”, for you Little Lispers out there – as a shallow copy.
- property top
Return the first mapping – aka
car(maps)
- unshift(map=None)
Create and return a new ChainMap with a new map followed by all previous maps.
If no map is provided, an empty dict is used.
If the map provided is a ChainMap – either one from the standard library “collections” module or from CLU, its constituent maps will be torn from it and each gruesomely vivisected into the new instance, as if the subject of a scene deleted from a kind of Pythonic Saw movie.
- class clu.dicts.ChainRepr(*args, maxlevel=10, maxstring=120, maxother=120, **kwargs)
Custom Repr-izer for “clu.dicts.ChainMap” composite mappings, which can recursively self-contain, and not infinitely recurse all over the living-room floor.
q.v. cpython docs, http://bit.ly/2r1GQ4l supra.
- primerepr(mapping, level)
The internal method for “core” repr production of all ChainMaps, and related descendant types.
- shortrepr(thing)
Return the “short” repr of a chainmap instance – all whitespace will be condensed to single spaces without newlines.
- subrepr(thing, level)
An internal “core” repr helper method.
- toprepr(chainmap, level)
The “top-level” ChainMap-specific repr method – this will parse through the individual mappings that comprise the ChainMap instance, and dispatch sub-repr method calls accordingly.
- class clu.dicts.OrderedItemsView(mapping)
An items-view class implementing “collections.abc.Sequence” and “collections.abc.Reversible”
- class clu.dicts.OrderedKeysView(mapping)
A keys-view class implementing “collections.abc.Sequence” and “collections.abc.Reversible”
- class clu.dicts.OrderedMappingView(mapping)
A mapping view class implementing “collections.abc.Sequence” and “collections.abc.Reversible”
- class clu.dicts.OrderedValuesView(mapping)
A values-view class implementing “collections.abc.Sequence” and “collections.abc.Reversible”
- clu.dicts.asdict(thing)
asdict(thing) → returns either thing, thing.__dict__, or dict(thing) as necessary
- clu.dicts.cmrepr(x)
Return the “core” repr for any descendant ChainMap type.
- clu.dicts.cmshortrepr(thing)
Return the “short” repr of a chainmap instance – all whitespace will be condensed to single spaces without newlines.
- clu.dicts.ischainmap(thing)
ischainmap(thing) → boolean predicate, True if the type of “thing” is a ChainMap or a descendant of same – either a “clu.dicts.ChainMap”, a “collections.ChainMap”; anything will do… if this was the last time, then you should tell us what to do.
I was afraid I guess, now I can’t think no more – I was so concentrated on keeping things together; I’ve learned to focus on. I didn’t want to disappoint. Now I miss everybody, is it still light outside?
- clu.dicts.merge(*dicts, **overrides)
Merge all dictionary arguments into a new dict instance, using any keyword arguments as item overrides in the final dict instance returned
- clu.dicts.merge_as(*dicts, cls=<class 'dict'>, **overrides)
Merge all dictionary arguments into a new instance of the specified class, passing all additional keyword arguments to the class constructor as overrides
- clu.dicts.merge_fast(*dicts, **extras)
Merge all dictionary arguments into a new instance of “dict”. passing all additional keyword arguments as an additional dict instance.
- Based on this extremely beloved SO answer:
- clu.dicts.merge_fast_two(one, two)
Merge two dictionaries performantly into an instance of “dict”.
- Based on this extremely beloved SO answer:
- clu.dicts.merge_two(one, two, cls=<class 'dict'>)
Merge two dictionaries into an instance of the specified class.
Based on this docopt example source: https://git.io/fjCZ6
clu.dispatch
- clu.dispatch.exithandle(function)
Register a function with “atexit” and various program-exit signals
- clu.dispatch.nhandles()
Return the number of registered exit-handle functions
- clu.dispatch.shutdown(send=Signals.SIGSTOP, frame=None)
Run all exit handles, and commence an orderly shutdown
- clu.dispatch.signal_for(signum)
Return the signal enum value for a given signal number
- clu.dispatch.trigger(send=Signals.SIGSTOP, frame=None)
Run and unregister all exit handle functions without exiting
- clu.dispatch.unregister(function)
Unregister a previously-registered exit handle function
- clu.dispatch.unregister_all()
Unregister all previously-registered exit handle functions
clu.enums
- class clu.enums.AliasingEnum(value)
An Enum subclass intermediate, suitable for subclassing itself, that uses AliasingEnumMeta as its metaclass.
…Thus, any member aliases that one makes in concrete classes derived from this class will find them registered upon class creation in an __aliases__ directory on the derived class.
- class clu.enums.AliasingEnumMeta(name, bases, attributes, **kwargs)
clu.exporting
- class clu.exporting.Exporter(*args, path=None, dotpath=None, **kwargs)
A class representing a list of things for a module to export.
This class is specifically germane to the CLU project – note that the “basepath” class keyword is used to assign a value from the CLU constants module.
Users of CLU who wish to use the Exporter mechanism in their own projects should create a subclass of ExporterBase of their own. Like this one, it need only assign the “basepath” class keyword; it is unnecessary (but OK!) to define further methods, properties, class constants, and whatnot.
When writing your subclass, if you •do• choose to add methods or other things, it is imperative that you ensure you aren’t accedentally clobbering anything important from ExporterBase, or you risk UNDEFINED BEHAVIOR!!!! Erm.
Also note that all derived subclasses of ExporterBase will automatically be slotted classes – a “__slots__” attribute will be added to the class dict by the “clu.abstract.Slotted” metaclass, if your subclass doesn’t define one – and so if you desire a class with a working “__dict__” attribute for some reason, you’ll need to specify:
>>> __slots__ = tuplize('__dict__')
… in your class (or an equivalent).
- class clu.exporting.ExporterBase(*args, path=None, dotpath=None, **kwargs)
The base class for “clu.exporting.Exporter”. Override this class in your own project to use the CLU exporting mechanism – q.v. “clu.exporting.Exporter” docstring sub.
This class uses the “clu.abstract.BasePath” metaclass, which automatically adds a “basepath” class attribute, as well as the “clu.exporting.Registry” mixin, which keeps a registry containing it and all of its derived subclasses, and furnishes the “instances” weak-value dictionary for instance registration.
- all_and_dir(*additionals)
Assign a modules’ __all__ and __dir__ values, e.g.:
>>> __all__, __dir__ = exporter.all_and_dir()
… This should be done near the end of a module, after all calls to exporter.export(…) (aka @export) have been made – q.v. the “decorator()” method supra.
- all_tuple(*additionals)
For use in module __all__ tuple definitions
- static cache_info()
Shortcut to get the CacheInfo namedtuple from the cached internal search_by_id(…) function, which is used in last-resort name lookups made by determine_name(…) during export(…) calls.
- decorator()
Return a reference to this Exporter instances’ “export” method, suitable for use as a decorator, e.g.:
>>> export = exporter.decorator()
>>> @export >>> def yodogg(): >>> ''' Yo dogg, I heard you like exporting ''' >>> …
… This should be done near the beginning of a module, to facilitate marking functions and other objects to be exported – q.v. the “all_and_dir()” method sub.
- dir_and_all(*additionals)
Assign a modules’ __dir__ and __all__ values, e.g.:
>>> __dir__, __all__ = exporter.dir_and_all()
… This should be done near the end of a module, after all calls to exporter.export(…) (aka @export) have been made – q.v. the “decorator()” method supra.
- dir_function(*additionals)
Return a list containing the exported module names.
- export(thing, name=None, doc=None)
- Add a function – or any object, really – to the export list.
Exported items will end up wih their names in the modules’
- __all__ tuple, and will also be named in the list returned
by the modules’ __dir__() function.
It looks better if this method is decoupled from its parent instance, to wit:
>>> exporter = Exporter() >>> export = exporter.decorator() # q.v. “decorator()” sub.
Use export as a decorator to a function definition:
>>> @export >>> def yo_dogg(i_heard=None): >>> …
… or manually, to export anything that doesn’t have a name:
>>> yo_dogg = lambda i_heard=None: … >>> dogg_heard_index = ( ¬ )
>>> export(yo_dogg, name="yo_dogg") >>> export(dogg_heard_index, name="dogg_heard_index")
- exports()
Get a new dictionary instance filled with the exports.
- get(key, default=<class 'clu.constants.consts.NoDefault'>)
Get and return a value for a key, with an optional default
- inner_repr()
Stringify a subset of the Exporter instances’ fields.
- items()
Get a item view on the exported items dictionary.
- keys()
Get a key view on the exported items dictionary.
- module()
Shortcut to get the parent module for the exporter.
- classmethod modulenames()
Get a generator yielding from a sorted list of module names – keys to the Exporter instance registry – currently available
- classmethod moduleof(thing)
Find and return the module for a thing, if that thing should be found to reside in one of the exported modules
- classmethod modules()
Get a dictionary of actual modules corresponding to the currently registered Exporter instances
- classmethod nameof(thing)
Find and return the name of a thing, if that thing should be found to reside in one of the exported modules
- pop(key, default=<class 'clu.constants.consts.NoDefault'>)
Remove and return a value for a key, with an optional default
- classmethod unregister(dotpath)
Unregister a previously-registered ExporterBase instance, specified by the dotted path (née “dotpath”) of the module in which it is ensconced.
Returns the successfully unregistered instance in question.
- update(dictish=<class 'clu.constants.consts.NoDefault'>, **updates)
Update the exporter with key/value pairs and/or an iterator; q.v. dict.update(…) docstring supra.
- values()
Get a value view on the exported items dictionary.
- class clu.exporting.ExporterTypeRepr(name, bases, attributes, basepath='/', **kwargs)
At the time of writing, type-specific “__repr__(…)” definitions require the use of a metaclass – soooooooo…
- class clu.exporting.Modulespace
Makes top-level python modules available as an attribute, importing them on first access.
- Q.v. pypy/rpython source supra:
- class clu.exporting.Registry
A class-registry mixin ancestor type suitable for use in the ExporterBase inheritance chain – it uses the “clu.abstract.Slotted” metaclass and respects the class keywords already in use.
- static all_appnames()
Return a generator over all currently registered appnames
- abstract exports()
An abstract method, ensuring Registry types can’t be just instantiated willy-nilly. The clu.exporting.ExporterBase descendant class implements this method.
- static for_appname(appname)
Return a subclass for a registered appname
- static has_appname(appname)
Check to see if a given appname has a registered subclass
- classmethod moduleof(thing)
Find and return the module for a thing, if that thing should be found to reside in one of the exported modules
- classmethod nameof(thing)
Find and return the name of a thing, if that thing should be found to reside in one of the exported modules
- static unregister(appname)
Unregister a previously-registered appname, returning the successfully unregistered ExporterBase subclass.
Attempting to unregister the core CLU application’s exporter is not allowed and will raise a KeyError.
- clu.exporting.determine_name(thing, name=None, try_repr=False)
Private module function to find a name for a thing.
- clu.exporting.itermodule(module)
Get an iterable of (name, thing) tuples for all things contained in a given module (although it’ll probably work for classes and instances too – anything dir()-able.)
- clu.exporting.itermoduleids(module)
Internal function to get an iterable of (name, id(thing)) tuples for all things comntained in a given module – q.v. itermodule(…) implementation supra.
- clu.exporting.moduleids(module)
Get a dictionary of (name, thing) tuples from a module, indexed by the id() value of thing
- clu.exporting.path_to_dotpath(path, relative_to=None)
Convert a file path (e.g. “/yo/dogg/iheard/youlike.py”) to a dotpath (á la “yo.dogg.iheard.youlike”) in what I would call a “quick and dirty” fashion.
Issues a BadDotpathWarning if the converted path contains dashes – I don’t quite know what to do about something like that besides warn, so erm. There you go.
- clu.exporting.search_by_id(thingID)
Cached function to find the name of a thing, according to what it is called in the context of a module in which it resides – searching across all currently imported modules in entirely, as indicated from the inspection of sys.modules.values() (which is potentially completely fucking enormous).
This function implements search_for_name(…) – q.v. the calling function code sub., and is also used in the implementation of determine_module(…), - also q.v. the calling function code sub.
Caching courtesy the functools.lru_cache(…) decorator.
- clu.exporting.search_for_module(thing)
Attempt to find the module containing “thing”, using the logic from the search_modules(…) function, applied to all currently imported modules, as indicated from the inspection of sys.modules.values() (which that, as a search space, is potentially fucking enormous).
This function may be called by determine_name(…). Its subordinate internal function, search_by_id(…), uses the LRU cache from functools.
- clu.exporting.search_for_name(thing)
Attempt to find the name for “thing”, using the logic from the search_modules(…) function, applied to all currently imported modules, as indicated from the inspection of sys.modules.values() (which that, as a search space, is potentially fucking enormous).
This function may be called by determine_name(…). Its subordinate internal function, search_by_id(…), uses the LRU cache from functools.
- clu.exporting.search_modules(thing, *modules)
Find the name of a thing, according to what it is called in the context of a module in which it resides
- clu.exporting.thismodule()
thismodule() → return the name of the module in which the thismodule() function was called
clu.extending
- class clu.extending.DoubleDutchRegistry
- inner_repr()
Return a repr string for instances of this class
- class clu.extending.Extensible(name, bases, attributes, **kwargs)
Two magic tricks for classes:
# In one file… class X(metaclass=Extensible):
…
# In some other file… class __extend__(X):
- … # and here you can add new methods
# and class attributes to X!
Mostly useful together with the second trick, which lets you build methods whose “self” is a pair of objects, instead of just one:
- class __extend__(pairtype(X, Y)):
attribute = 42 def method(pair_xy, other, arguments):
x, y = pair_xy …
pair(x, y).attribute pair(x, y).method(other, arguments)
This finds methods and class attributes based on the actual class of both objects that go into the “pair()”, with the usual rules of method/attribute overriding in (pairs of) subclasses.
- clu.extending.doubledutch(function)
Decorator returning a double-dispatch function.
>>> @doubledutch ... def func(x, y): ... return 42 >>> >>> @func.domain(str, str) ... def func(x, y): ... return "42" >>> >>> @func.annotated ... def func(x: int, y: int): ... return x * y >>> >>> func(None, None) 42 >>> func(1, 42) 42 >>> func('x', 'y') "42" --------------------------------
- clu.extending.pair(one, two)
Return a pair object – a descendant of “__builtin__.tuple”
- clu.extending.pairmro(cls0, cls1)
Return the resolution order on pairs of types for double dispatch.
This order is compatible with the mro of pairtype(cls0, cls1)
- clu.extending.pairtype(cls0, cls1)
type(pair(a, b)) is “pairtype(typeof(a), typeof(b))”
- clu.extending.Ω(one, two)
Return a pair object – a descendant of “__builtin__.tuple”
- clu.extending.ΩΩ(cls0, cls1)
type(pair(a, b)) is “pairtype(typeof(a), typeof(b))”
- clu.extending.ω(cls0, cls1)
Return the resolution order on pairs of types for double dispatch.
This order is compatible with the mro of pairtype(cls0, cls1)
clu.fs
- class clu.fs.abc.BaseFSName
- property basename
The basename (aka the name of the instance, like as opposed to the entire fucking absolute path) of the target instance.
- close()
Stub method – always returns True:
- property dirname
The dirname (aka the path of the enclosing directory) of the target instance, wrapped in a new Directory instance.
- property exists
Whether or not the instances’ target path exists as a directory.
- inner_repr()
Return a repr string for instances of this class
- abstract property name
The instances’ target path.
- parent()
Sugar for self.directory(os.path.abspath(os.path.dirname(self.name))) …which, if you are curious, gets you the parent directory of the target instance, wrapped in a new Directory instance.
- realpath(source=None)
Sugar for calling os.path.realpath(self.name) with additional assurances that the path string in question will be UTF-8 Unicode data and not a byte-string type.
- relparent(path)
Relativize a path, relative to its directory parent, and return it as a string.
- relprefix(path, separator='_')
Return a “prefix” string based on a file path – the actual path separators are replaced with underscores, with which individual path segments are joined, creating a single long string that is unique to the original filesystem path.
- split()
Return a two-tuple containing (dirname, basename) – like e.g. for /yo/dogg/i/heard/youlike, your return value will be like (Directory(“/yo/dogg/i/heard”), “youlike”).
- symlink(destination, source=None)
Create a symlink at destination, pointing to this instances’ path location (or an alternative source path, if specified).
The destination argument can be anything path-like: instances of str, unicode, bytes, bytearray, pathlib.Path, os.PathLike, or anything with an __fspath__(…) method – which this includes clu.fs.filesystem.TemporaryName and clu.fs.filesystem.Directory instances and relevant derived-type instances thereof.
- class clu.fs.abc.TemporaryFileWrapper(file, name, delete=True)
Local subclass of tempfile._TemporaryFileWrapper.
We also inherit from both contextlib.AbstractContextManager and the os.PathLike abstract bases – the latter requires that we implement an __fspath__(…) method (q.v. implementation, sub.) – and additionally, clu.fs.abc.TypeLocker is named as the metaclass (q.v. metaclass __new__(…) implementation supra.) to cache its type and register it as an os.PathLike subclass.
… Basically a better deal than the original ancestor, like all-around. Plus it does not have a name prefixed with an underscore, which if it’s not your implementation dogg that can be a bit lexically irritating.
- class clu.fs.abc.TypeLocker(name, bases, attributes, **kwargs)
clu.fs.abc.TypeLocker is a metaclass that does two things with the types for whom it is designated as meta:
It keeps an index of those types in a dictionary member of the TypeLocker metaclass itself; and
During class creation – the call to TypeLocker.__new__(…) – it installs a class method called “directory(…)” that will, when invoked, always return a new Directory instance that has been initialized with the one provided argument “pth” (if one was passed).
… The point of this is to allow any of the classes throughout the “clu.fs” subpackage, regardless of where they are defined or from whom they inherit, to make use of cheaply-constructed Directory instances wherever convenient.
Because the “directory(…)” method installed by TypeLocker performs a lazy-lookup of the Directory class, using its own type index dict, the order of definition does not matter i.e. the TemporaryName class (q.v. definition immediately sub.) can use Directories despite its definition occuring before Directory – in fact TemporaryName itself is utilized within at least one Directory method – sans any issues.
- class clu.fs.appdirectories.AppDirs(*args, **kwargs)
Convenience wrapper for getting application dirs.
- determine_system_string()
Determine upon which system this AppDirs instance has been brought into existence – DEPRECIATED, see the appdirectories.System enum class (and the System.determine() class method in particular) for the replcaement logic
- determine_win_folder_function()
Use successive imports to determine the best folder-finding method to employ on Windows.
These are all dummy imports – they differ from actual (albiet similar and related) modules imported by each of the respective Windows-native functions; that’s why we delete whatever we managed to import before returning the function.
- get_site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
Return full path to the user-shared data dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “multipath” is an optional parameter only applicable to *nix
which indicates that the entire list of config dirs should be returned. By default, the first item from XDG_CONFIG_DIRS is returned, or ‘/etc/xdg/<AppName>’, if XDG_CONFIG_DIRS is not set
- Typical site config directories are:
Mac OS X: same as site_data_dir Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in
$XDG_CONFIG_DIRS
Win : same as site_data_dir Vista: (Fail! “C:ProgramData” is a hidden *system directory on Vista.)
For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False
WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
- get_site_data_dir(appname=None, appauthor=None, version=None, multipath=False)
Return full path to the user-shared data dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “multipath” is an optional parameter only applicable to *nix
which indicates that the entire list of data dirs should be returned. By default, the first item from XDG_DATA_DIRS is returned, or ‘/usr/local/share/<AppName>’, if XDG_DATA_DIRS is not set
- Typical site data directories are:
Mac OS X: /Library/Application Support/<AppName> Unix: /usr/local/share/<AppName> or /usr/share/<AppName> Win XP: C:Documents and SettingsAll UsersApplication Data<AppAuthor><AppName> Vista: (Fail! “C:ProgramData” is a hidden system directory on Vista.) Win 7: C:ProgramData<AppAuthor><AppName> # Hidden, but writeable on Win 7.
For Unix, this is using the $XDG_DATA_DIRS[0] default.
WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
- get_user_cache_dir(appname=None, appauthor=None, version=None, opinion=True)
Return full path to the user-specific cache dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “opinion” (boolean) can be False to disable the appending of
“Cache” to the base app data dir for Windows. See discussion below.
- Typical user cache directories are:
Mac OS X: ~/Library/Caches/<AppName> Unix: ~/.cache/<AppName> (XDG default) Win XP: C:Documents and Settings<username>Local SettingsApplication Data<AppAuthor><AppName>Cache Vista: C:Users<username>AppDataLocal<AppAuthor><AppName>Cache
On Windows the only suggestion in the MSDN docs is that local settings go in the CSIDL_LOCAL_APPDATA directory. This is identical to the non-roaming app data dir (the default returned by user_data_dir above). Apps typically put cache data somewhere under the given dir here. Some examples:
…MozillaFirefoxProfiles<ProfileName>Cache …AcmeSuperAppCache1.0
OPINION: This function appends “Cache” to the CSIDL_LOCAL_APPDATA value. This can be disabled with the opinion=False option.
- get_user_config_dir(appname=None, appauthor=None, version=None, roaming=False)
Return full path to the user-specific config dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “roaming” (boolean, default False) can be set True to use the Windows
roaming appdata directory. That means that for users on a Windows network setup for roaming profiles, this user data will be sync’d on login. See <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> for a discussion of issues.
- Typical user config directories are:
Mac OS X: ~/Library/Preferences/<AppName> Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined Win *: same as user_data_dir
For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. That means, by default “~/.config/<AppName>”.
- get_user_data_dir(appname=None, appauthor=None, version=None, roaming=False)
Return full path to the user-specific data dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “roaming” (boolean, default False) can be set True to use the Windows
roaming appdata directory. That means that for users on a Windows network setup for roaming profiles, this user data will be sync’d on login. See <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> for a discussion of issues.
- Typical user data directories are:
Mac OS X: ~/Library/Application Support/<AppName> Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined Win XP (not roaming): C:Documents and Settings<username>Application Data<AppAuthor><AppName> Win XP (roaming): C:Documents and Settings<username>Local SettingsApplication Data<AppAuthor><AppName> Win 7 (not roaming): C:Users<username>AppDataLocal<AppAuthor><AppName> Win 7 (roaming): C:Users<username>AppDataRoaming<AppAuthor><AppName>
For Unix, we follow the XDG spec and support $XDG_DATA_HOME. That means, by default “~/.local/share/<AppName>”.
- get_user_log_dir(appname=None, appauthor=None, version=None, opinion=True)
Return full path to the user-specific log dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “opinion” (boolean) can be False to disable the appending of
“Logs” to the base app data dir for Windows, and “log” to the base cache dir for Unix. See discussion below.
- Typical user log directories are:
Mac OS X: ~/Library/Logs/<AppName> Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined Win XP: C:Documents and Settings<username>Local SettingsApplication Data<AppAuthor><AppName>Logs Vista: C:Users<username>AppDataLocal<AppAuthor><AppName>Logs
On Windows the only suggestion in the MSDN docs is that local settings go in the CSIDL_LOCAL_APPDATA directory. (Note: I’m interested in examples of what some windows apps use for a logs dir.)
OPINION: This function appends “Logs” to the CSIDL_LOCAL_APPDATA value for Windows and appends “log” to the user cache dir for Unix. This can be disabled with the opinion=False option.
- get_user_state_dir(appname=None, appauthor=None, version=None, roaming=False)
Return full path to the user-specific state dir for this application.
- “appname” is the name of application.
If None, just the system directory is returned.
- “appauthor” (only used on Windows) is the name of the
appauthor or distributing body for this application. Typically it is the owning company name. This falls back to appname. You may pass False to disable it.
- “version” is an optional version path element to append to the
path. You might want to use this if you want multiple versions of your app to be able to run independently. If used, this would typically be “<major>.<minor>”. Only applied when appname is present.
- “roaming” (boolean, default False) can be set True to use the Windows
roaming appdata directory. That means that for users on a Windows network setup for roaming profiles, this user data will be sync’d on login. See <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> for a discussion of issues.
- Typical user state directories are:
Mac OS X: same as user_data_dir Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined Win *: same as user_data_dir
For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> to extend the XDG spec and support $XDG_STATE_HOME.
That means, by default “~/.local/state/<AppName>”.
- get_win_folder(argument)
Retrieve the module-private Win32 API access function from the AppDirs instance (so as not to invoke it as a bound method) before calling it with the supplied argument
- property site_config_dir
The system-wide configuration directory
- property site_data_dir
The system-wide application-specific data directory
- to_string()
Stringify the AppDirs instance.
- property user_cache_dir
The userland cache directory
- property user_config_dir
The userland configuration directory
- property user_data_dir
The userland application-specific data directory
- property user_log_dir
The userland log directory
- property user_state_dir
The userland state-stash directory
- class clu.fs.appdirectories.CSIDL(value)
An enumeration encapsulating Windows CSIDLs.
- classmethod for_name(name)
Retrieve a CSIDL by name (case-insensitively)
- property fullname
A CSIDL’s “full name” – which is basically of the form “CSIDL_NAME_STRING”
- to_int()
A given CSIDL’s integer value
- to_string()
A given CSIDL’s full name
- class clu.fs.appdirectories.System(value)
An enumeration class for dealing with the name of the underlying operating system upon which we are running.
- classmethod all()
Get a generator over all System values
- classmethod determine()
Determine the System value for the current platform
- classmethod from_string(string)
Retrieve a System value by name (case-insensitively)
- property is_current
A boolean value expressing if a given System value represents the current running operating system
- property is_unix_based
A boolean value expressing if a given System value represents a UNIX-based operating system
- classmethod match(value)
Match a system to a value – the nature of which can be:
a string (unicode or bytes-type) naming the system;
an existing “System” enum-member value; or
an arbitrary alternative enum-member value.
… The matched system is returned. If no match is found, a ValueError will be raised.
- property os_name
A given System value’s “os_name” (as reported when running within a java-based environment e.g. Jython)
- property sys_name
A given System value’s name, lowercased
- to_string()
A given System value’s name
- classmethod unixes()
Get a generator over the UNIX-based System values
- clu.fs.appdirectories.clu_appdirs(system=System.LINUX2, versioning=True)
Retrieve an AppDirs instance specific to the CLU project
- class clu.fs.filesystem.Directory(pth=None)
A context-managed directory: change in on enter, change back out on exit. Plus a few convenience functions for listing and whatnot.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- copy_all(destination)
- Copy the entire directory tree, all contents included, to a new
destination path. The destination must not already exist, and
- copy_all(…) will not overwrite existant directories. Like, if
you have yourself an instance of Directory, directory, and you want to copy it to /home/me/myshit, /home/me should already exist but /home/me/myshit should not, as the subdirectory
- myshit gets created by the directory.copy_all(‘/home/me/myshit’)
invocation (like as a side-effect).
Does that make sense to you? Try it, you’ll get a FilesystemError if it evidently did not make sense to you.
The destination path may be specified using a string-like, with another Directory object, or anything deemed path-y enough by
- os.fspath(…). Internally, this method uses shutil.copytree(…)
to tell the filesystem what to copy where.
- ctx_initialize()
Restores the instance to the freshly-allocated state – with one notable exception: if it had been previously prepared (through a call to instance.ctx_prepare()) and thus has a “new” attribute filled in with a target path, ctx_initialize() will preserve the contents of that attribute in the value of the self.target instance member.
The call deletes all other instance attributes from the internal mapping of the instance in question, leaving it in a state ready for either context-managed reëntry, or for reuse in an unmanaged fashion provided one firstly calls instance.ctx_set_targets() or instance.ctx_prepare() in order to reconfigure (the minimal subset of, or the full complement of) the member-variable values needed by the internal workings of a Directory instance.
- ctx_prepare()
Prepares the member values of the Directory instance according to a requisite self.target directory-path value; the primary logic performed by this function determines whether or not it is necessary to switch the process working directory while the Directory instance is actively being used as a context manager in the scope of a while block.
The reason this is done herein is to minimize the number of calls to potentially expensive system-call-wrapping functions such as os.getcwd(), os.path.samefile(…), and especially os.chdir(…) – which the use of the latter affects the state of the process issuing the call in a global fashion, and can cause invincibly undebuggable behavioral oddities to crop up in a variety of circumstances.
- ctx_set_targets(old=None)
Sets the “self.old” and “self.new” instance variable values, using the value of self.target and an (optional) string-like argument to use as the value for “self.old”.
One shouldn’t generally call this or have a need to call this – although one can manually invoke instance.ctx_set_targets(…) to reconfigure a Directory instance to use it again after it has been re-initialized after a call to instance.ctx_initialize() (q.v. ctx_initialize() help supra.) in cases where it isn’t going to be used as part of a managed context; that is to say, outside of a with statement.
(Within a with statement, the call issued upon scope entry to Directory.__enter__(self) will internally make a call to Directory.ctx_prepare(self) (q.v. doctext help sub.) which that will call Directory.ctx_set_targets(self, …) itself.)
- property exists
Whether or not the instances’ target path exists as a directory.
- flatten(destination, suffix=None, new_suffix=None)
- Copy the entire directory tree, all contents included, to a new
destination path – with all files residing within the same directory level.
That is to say, if the directory tree is like:
yo/ yo/dogg/[0..9].jpg yo/dogg/nodogg/[0..99].png
… you end up with a single destination directory, filled with files, all with names like:
yo_dogg_[0..9].jpg yo_dogg_nodogg_[0..99].png
- flatten(…) will not overwrite existant directories. Like, if
you have yourself an instance of Directory, directory, and you want to copy it to /home/me/myshit, /home/me should already exist but /home/me/myshit should not, as the subdirectory
- myshit gets created by the directory.flatten(‘/home/me/myshit’)
invocation (like as a side-effect).
Does that make sense to you? Try it, you’ll get a FilesystemError if it evidently did not make sense to you.
The destination path may be specified using a string-like, with another Directory object, or anything deemed path-y enough by
- os.fspath(…). Internally, this method uses shutil.copy2(…)
to tell the filesystem to copy and rename each file in succession.
- importables(subdir, suffix='py', source=None, excludes=('-', '+', 'pytest', 'legacy', 'obsolete', 'repl.py'))
List the importable file-based modules found within “subdir”, matching the “suffix” string, and not matching any of the “excludes” strings.
- property initialized
Whether or not the instance has been “initialized” – as in, the target instance value has been set (q.v. ctx_initialize(…) help sub.) as it stands immediately after __init__(…) has run.
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- ls(suffix=None, source=None)
List files – defaults to the process’ current working directory. As per the UNIX custom, files whose name begins with a dot are omitted.
Specify an optional “suffix” parameter to filter the list by a particular file suffix (leading dots unnecessary but unharmful).
- ls_la(suffix=None, source=None)
List all files, including files whose name starts with a dot. The default is to use the process’ current working directory.
Specify an optional “suffix” parameter to filter the list by a particular file suffix (leading dots unnecessary but unharmful).
(Technically speaking, ls_la() is a misnomer for this method, as it does not provide any extended meta-info like you get if you use the “-l” flag when invoking the ls command – I just like calling it that because “ls -la” was one of the first shell commands I ever learned, and it reads better than ls_a() which I think looks awkward and goofy.)
- makedirs(subpath=None, mode=493)
Creates any parts of the target directory path that don’t already exist, á la the mkdir -p shell command.
- property name
The instances’ target directory path.
- property prepared
Whether or not the instance has been internally prepared for use (q.v. ctx_prepare() help sub.) and is in a valid state.
- subdirectory(subdir, source=None)
Returns the path to a subpath of the instances’ target path – much like Directory.subpath(…) – as an instance of Directory.
- subpath(subpath, source=None, requisite=False)
Returns the path to a subpath of the instances’ target path.
- suffix_histogram(subdir=None, source=None, excludes=('~', '#', 'ds_store', '.git'))
Return a ‘collections.Counter’ filled with a histogram of the file suffixes for all files found in the given subdirectory, excluding anything matching any of the “excludes” strings.
- suffixes(subdir=None, source=None, excludes=('~', '#', 'ds_store', '.git'))
Return a generator over all the file suffixes of all files found recursively within the given subdirectory, excluding anything matching any of the “excludes” strings.
- property targets_set
Whether or not the instance has had targets set (the new and old instance values, q.v. ctx_set_targets(…) help sub.) and is ready for context-managed use.
- values() an object providing a view on D's values
- walk(followlinks=True)
Sugar for calling os.walk(self.name)
Note that the “followlinks” default here is True, whereas the underlying function defaults to False for that argument.
- zip_archive(destination, compression_mode=8)
Recursively descends through the target directory, stowing all that it finds into a zipfile at the specified destination path.
Use the optional “compression_mode” parameter to specify the compression algorithm, as per the constants found in the zipfile module; the default value is zipfile.ZIP_DEFLATED.
- class clu.fs.filesystem.Intermediate(pth=None, change=False)
clu.fs.filesystem.Intermediate isn’t a class, per se – rather, it is a class factory proxy that normally constructs a new Directory instance in leu of itself, except for when it it is constructed without a pth argument, in which case, it falls back to the construction of a new TemporaryDirectory instance instead.
- clu.fs.filesystem.NamedTemporaryFile(mode='w+b', buffer_size=-1, suffix='tmp', prefix='yo-dogg-', directory=None, delete=True)
Variation on
tempfile.NamedTemporaryFile(…)
, such that suffixes are passed WITHOUT specifying the period in front (versus the standard library version which makes you pass suffixes WITH the fucking period, ugh).
- class clu.fs.filesystem.TemporaryDirectory(prefix='TemporaryDirectory-', suffix='', parent=None, change=True, **kwargs)
It’s funny how this code looks, like, 99 percent exactly like the above TemporaryName class – shit just works out that way. But this actually creates the directory in question; much like filesystem::TemporaryDirectory from libimread, this class wraps tempfile.mkdtemp() and can be used as a context manager (the C++ orig used RAII).
- close()
Delete the directory pointed to by the TemporaryDirectory instance, and everything it contains. USE WITH CAUTION.
- ctx_prepare()
Prepares the member values of the Directory instance according to a requisite self.target directory-path value; the primary logic performed by this function determines whether or not it is necessary to switch the process working directory while the Directory instance is actively being used as a context manager in the scope of a while block.
The reason this is done herein is to minimize the number of calls to potentially expensive system-call-wrapping functions such as os.getcwd(), os.path.samefile(…), and especially os.chdir(…) – which the use of the latter affects the state of the process issuing the call in a global fashion, and can cause invincibly undebuggable behavioral oddities to crop up in a variety of circumstances.
- property destroy
Whether or not the TemporaryDirectory instance has been marked for automatic deletion upon scope exit (q.v __exit__(…) method definition sub.)
- do_not_destroy()
Mark this TemporaryDirectory instance as one that should not be automatically destroyed upon the scope exit for the instance.
This function returns the temporary directory path, and may be called more than once without further side effects.
- property exists
Whether or not the temporary directory exists.
- property name
The temporary directory pathname.
- symlink(*args, **kwargs)
Symlinking to TemporaryDirectory instances is disabled – why do you want to symlink to something that is about to delete itself?? That is just asking for a whole bunch of dangling references dogg.
- class clu.fs.filesystem.TemporaryName(prefix=None, suffix='tmp', parent=None, **kwargs)
This is like NamedTemporaryFile without any of the actual stuff; it just makes up a file name – YOU have to make shit happen with it. But: should you cause such scatalogical events to transpire, this class (when instanced as a context manager) will clean it up for you. Unless you say not to. Really it’s your call dogg, I could give AF
- property binary_mode
Whether or not the mode with which this TemporaryName instance was constructed is a “binary mode” – and as such, requires the operands passed to its write(…) methods of its filehandle (q.v. the “mode” property definition supra., and the “filehandle” property definition sub.) to be of type byte or bytearray, or of a type either derived or compatible with these. Errors will be raised if you try to call a write(…) method with a str-ish operand.
Filehandles constructed through “non-binary” TemporaryName instances are the other way around – their write(…) methods can only be passed instances of str (or, unicode, for those Python-2 diehards still remaining amongst us) or similar; attempt to pass anything byte-y and you’ll get raised on.
- close()
Destroys any existing file at this instances’ file path.
- copy(destination)
Copy the file (if one exists) at the instances’ file path to a new destination.
- property destroy
Whether or not this TemporaryName instance should destroy any file that should happen to exist at its temporary file path (as per its “name” attribute) on scope exit.
- do_not_destroy()
Mark this TemporaryName instance as one that should not be automatically destroyed upon the scope exit for the instance.
This function returns the temporary file path, and may be called more than once without further side effects.
- property filehandle
Access a “clu.fs.abc.TemporaryNamedFile” instance, opened and ready to read and write, for this TemporaryName instances’ file path.
While this is a normal property descriptor – each time it is accessed, its function is called anew – the underlying TemporaryNamedFile call is a cached function and not a class constructor (despite what you might think because of that CamelCased identifier). That means you’ll almost certainly be given the same instance whenever you access the “filehandle” property (which is less fraught with potentially confusing weirdness, I do believe).
Accessing this property delegates the responsibility for destroying the TemporaryName file contents to the TemporaryNamedFile object – saving the TemporaryNamedFile in, like, a variable somewhere and then letting the original TemporaryName go out of scope will keep the file alive and unclosed, for example. THE UPSHOT: be sure to call “close()” on the filehandle instance you use. That’s fair, right? I think that’s totally fair to do it like that, OK.
- property filesize
The filesize for the temporary file
- property flags
A flag value matching the instances’ mode and deletion disposition.
- property mode
Get the mode string for this TemporaryName instance. This is used if and when a filehandle is accessed (q.v. “filehandle” property definition sub.) in the construction of the TemporaryNamedFile that is handed back as the filehandle instance.
- property name
The temporary file path (which initially does not exist).
- read(*, original_position=False)
Read data from the temporary name, if it points to an existing file
- symlink(*args, **kwargs)
Symlinking to TemporaryName instances is disabled – why do you want to symlink to something that is about to delete itself?? That is just asking for a whole bunch of dangling references dogg.
- write(data)
Write data to the temporary name using a context-managed handle
- class clu.fs.filesystem.cd(pth)
- clu.fs.filesystem.ensure_path_is_valid(pth)
Raise an exception if we can’t write to the specified path
- class clu.fs.filesystem.hd
- clu.fs.filesystem.rm_rf(path)
rm_rf() does what rm -rf does – so, for the love of fuck, BE FUCKING CAREFUL WITH IT.
- clu.fs.filesystem.script_path()
Return the path to the embedded scripts directory.
- class clu.fs.filesystem.td
- class clu.fs.filesystem.wd
- clu.fs.filesystem.which(binary_name, pathvar=None)
Deduces the path corresponding to an executable name, as per the UNIX command which. Optionally takes an override for the $PATH environment variable. Always returns a string - an empty one for those executables that cannot be found.
- clu.fs.filesystem.write_to_path(data, pth, relative_to=None, verbose=False)
Write data to a new file using a context-managed handle
- clu.fs.misc.current_umask()
Get the current umask value. Results are cached, via “functools.lru_cache(…)”
- clu.fs.misc.differentfile(f1, f2)
differentfile(path0, path1) → Return True if path0 and path1 point to different locations on the filesystem
- clu.fs.misc.differentsize(path0, path1)
Compare the on-disk file sizes (in bytes) of two files by their paths, returning True if they are different, and False otherwise
“FilesystemError” will be raised if either of the paths are invalid
- clu.fs.misc.extension(path, dotted=False)
Return the extension – the file suffix – from a file pathname.
- clu.fs.misc.filesize(path)
Return the on-disk size (in bytes) of the file located at a path
- clu.fs.misc.gethomedir()
gethomedir() → Return the current user’s home directory
- clu.fs.misc.isinvalidpath(thing)
isinvalidpath(thing) → boolean predicate, True if thing does not represent a valid path on the filesystem
- clu.fs.misc.masked_chmod(path, perms=438)
Perform the os.chmod(…) operation, respecting the current umask value (q.v. current_umask() supra.)
- clu.fs.misc.masked_permissions(perms=438)
Compute the permission bitfield, using the current umask value and a given permission octal number.
- clu.fs.misc.modeflags(mode, delete=True)
Convert a file-open modestring to an integer flag.
Helper function, used by “clu.fs.filesystem.TemporaryNamedFile(…)” and “clu.fs.filesystem.NamedTemporaryFile(…)” functions internally.
- clu.fs.misc.octalize(integer)
octalize(integer) → Format an integer value as an octal number
- clu.fs.misc.re_excluder(*excludes)
Return a boolean function that will search for any of the given strings (provided as variadic arguments) and return False whenever any of them are found – True otherwise.
- clu.fs.misc.re_matcher(string)
Return a boolean function that will search for the given regular-expression within any strings with which it is called, returning True when the regex matches from the beginning of the string, and False when it doesn’t.
Results are cached, via “functools.lru_cache(…)”
- clu.fs.misc.re_searcher(string)
Return a boolean function that will search for the given regular-expression within any strings with which it is called, returning True when the regex matches and False when it doesn’t.
Results are cached, via “functools.lru_cache(…)”
Useful in filter(…) calls and comprehensions, e.g.:
>>> plists = filter(re_searcher(r'.plist$'), os.listdir()) >>> mmsuffix = suffix_searcher(r'.mm$') >>> objcpp = (f for f in os.listdir() where mmsuffix(f))
- clu.fs.misc.re_suffix(string)
Remove any “os.extsep” prefixing a string, and ensure that it ends with a “$” – to indicate a regular expression suffix.
- clu.fs.misc.samesize(path0, path1)
Compare the on-disk file sizes (in bytes) of two files by their paths, returning True if they are the same, and False otherwise
“FilesystemError” will be raised if either of the paths are invalid
- clu.fs.misc.suffix_searcher(string)
Return a boolean function that will search for the given string within any strings with which it is called, returning True when they are found and False when they aren’t.
Useful in filter(…) calls and comprehensions, e.g.:
>>> plists = filter(suffix_searcher('plist'), os.listdir()) >>> mmsuffix = suffix_searcher('mm') >>> objcpp = (f for f in os.listdir() where mmsuffix(f))
- clu.fs.misc.swapext(path, new_extension=None)
Swap the file extension of the path with a newly specified one – if no extension is present, the newly specified extension will be amended to the path; the new extension can provide or omit its leading extension-separator (or a “period” in most human usage).
Like E.G.:
>>> swapext('/yo/dogg.obj', 'odb') '/yo/dogg.odb' >>> swapext('/yo/dogg.obj', '.odb') '/yo/dogg.odb' >>> swapext('/yo/dogg', 'odb') '/yo/dogg.odb'
- clu.fs.misc.temporary(suffix='', prefix='', parent=None, **kwargs)
Wrapper around tempfile.mktemp() that allows full overriding of the prefix and suffix by the caller – that is to say, no random elements are used in the returned filename if both a prefix and a suffix are supplied.
To avoid problems, the function will throw a FilesystemError if it is called with arguments that result in the computation of a filename that already exists.
- clu.fs.misc.u8bytes(source)
Encode a source as bytes using the UTF-8 codec, guaranteeing a proper return value without raising an error
- clu.fs.misc.u8encode(source)
Encode a source as bytes using the UTF-8 codec
- clu.fs.misc.u8str(source)
Encode a source as a Python string, guaranteeing a proper return value without raising an error
- clu.fs.misc.win32_longpath(path)
Helper function to add the long path prefix for Windows, so that shutil.copytree won’t fail while working with paths with 255+ chars.
Vendored in from pytest-datadir – q.v. https://git.io/fjMWl supra.
- clu.fs.pypath.add_paths(*putatives, prepend=False)
Mutate sys.path by adding one or more new paths – all of which are checked for both nonexistence and presence within the existing sys.path list via inode lookup, and which those failing such checks are summarily excluded.
Paths are added to sys.path by appending, unless “add_paths(…)” is called with the keyword arg ‘prepend=True’.
- clu.fs.pypath.enhance(*putatives)
Convenience function for calling “remove_invalid_paths(…)” before calling “add_paths(•putatives)”
- clu.fs.pypath.remove_invalid_paths()
Mutate sys.path by removing any existing paths that don’t actually lead to a valid place somewhere on the filesystem (according to “os.path.exists(…)”). Path removal, as with “remove_paths(…)”, is done atomically.
- clu.fs.pypath.remove_paths(*putatives)
Mutate sys.path by removing one or more existing paths – all of which are checked for presence within the existing sys.path list via inode lookup before being marked for removal, which that (the removal) is done atomically.
- class clu.fs.sourcetree.SourceTree(filepath, path=None, **kwargs)
clu.importing
- class clu.importing.base.ArgumentSink(*args, **kwargs)
ArgumentSink is a class that stores the arguments with which it is initialized, for either later retrieval or subsequent functional application.
To wit:
>>> sink = ArgumentSink('yo', 'dogg', iheard="you like") >>> assert sink.args == ('yo', 'dogg') >>> assert sink.kwargs == dict(iheard="you like") >>> sink(stringify) # prints “str(iheard=you like) @ 0x10bd”
- inner_repr()
Return a repr string for instances of this class
- class clu.importing.base.FinderBase(*args, **kwargs)
The base class for all class-based module finders.
One must subclass this class once per app, specifying an “appname” – the name of the app. Q.v. the function “initialize_types(…)” sub. to easily set these up for your own app.
The class method “FinderBase.find_spec(…)” caches its returned instances of “ModuleSpec” using a ‘zict.LRU’ buffer, which is shared across all of the installed “FinderBase” subclasses – meaning that if a spec has been cached for one installed app via this mechanism, it will be found by the first Finder subclass that shows up in “sys.meta_path” to field a query for it (!)
- classmethod find_spec(fullname, path=None, target=None)
Return a ModuleSpec for a qualified module name – creating an instance anew if necessary, and returning an existing one from the cache if available.
- classmethod invalidate_caches()
Clear both the Finder’s internal ModuleSpec instance cache, and its associated Loader instances’ memoization cache for the “create_module(…)” method (q.v. method implementation sub.)
- classmethod iter_modules()
This “non-standard API method”§ yields ‘pkgutil.ModuleInfo’ instances for each registered class-module in the finder subclasses’ given app.
- § q.v. boxed notation sub., Python documentation,
https://docs.python.org/3/library/pkgutil.html#pkgutil.iter_modules
- classmethod spec(fullname)
Create, cache, and return a new ModuleSpec, corresponding to a given dotpath (née “fullname”) and using the Finder’s embedded loader instance.
- class clu.importing.base.LoaderBase(*args, **kwargs)
The base class for all class-based module loaders.
One must subclass this class once per app, specifying an “appname” – the name of the app. Q.v. the function “initialize_types(…)” sub. to easily set these up for your own app.
The method “LoaderBase.create_module(…)” caches returned instances of “types.Module” using the ‘functools.lru_cache’ function decorator.
- create_module(spec)
Create a new class-based module from a spec instance.
- exec_module(module)
Execute a newly created module.
Since the code of class-based module has, by definition, already been executed by the Python interpreter at this point, we delegate this action to a user-provided “__execute__()” instance method of the class-based module in question.
The “__execute__()” method will be called with no arguments. The class-based module instance will, at this point, have its “appname” and “appspace” class attributes set and readable, in addition to all of the contemporary module-instance attributes documented in e.g. PEP 451 and friends.
An “__execute__()” method shouldn’t return anything.
- static package_module(name)
Convenience method, returning an empty package module.
- class clu.importing.base.ModuleAlias(origin, specializer)
A ModuleAlias is created when subscripting the ModuleBase type, or a subtype thereof, with another ModuleBase subtype, as per the definition of ProxyModule – q.v. sub. and “typing” code sample supra.:
- inner_repr()
Return a repr string for instances of this class
- class clu.importing.base.ModuleBase(name, doc=None)
The base class for all class-based modules.
One must subclass this class once per app, specifying an “appname” – the name of the app – and an “appspace” – an optional prefix from which all class-based modules will be found and imported. Q.v. “initialize_types(…)” sub. to easily set these up for your own app.
Within CLU, the appname is “clu” (duh) and the appspace is “app” – all class-based modules are therefore imported from “clu.app”, á la:
>>> from clu.app import class_based_module
Note that class-based modules are forbidden from using the “__slots__” class attribute – the module class’ metaclass will remove any __slots__ it encounters, in fact, so don’t even bother with ’em.
- class clu.importing.base.ModuleSpec(name, loader)
A local “importlib.machinery.ModuleSpec” subclass that conveniently deals with setting the “origin” attribute.
- class clu.importing.base.Package(name, doc=None, path=None)
A subclass of ‘types.Module’ which assigns all instances of which either an empty list or the value of the “path” keyword argument to its “__path__” attribute in “__init__(…)”
- class clu.importing.base.Registry
The Registry mixin handles the registration of all class-based module subclasses.
- clu.importing.base.all_registered_appnames()
Return a generator of strings listing all registered app names
- clu.importing.base.all_registered_appspaces()
Return a generator of strings listing all registered “appspaces”
- clu.importing.base.all_registered_modules()
Return a generator over the instances of all registered class-based modules
- clu.importing.base.appspaces_for_appname(appname)
Return a generator over the “appspaces” belonging to a given registered app
- clu.importing.base.get_appspace(string) → Given a qualified name e.g. “clu.app.Module”, extract the appspace (“app” in the example)
- clu.importing.base.initialize_types(appname, appspace='app')
Initialize subtypes of FinderBase, LoaderBase, and ModuleBase, configured for a specific “appname” and “appspace” (the latter of which defaults to ‘app’).
You use ‘initialize_types(…)’ in one of your own app’s modules like so:
>>> Module, Finder, Loader = initialize_types('myappname')
… if you insert that line of code in a module of yours called, say, “myappname/modules.py” you could then either a) proceed to subclass Module to create your class-modules, or b) import the ‘Module’ class from elsewhere and subclass it subsequently.
- clu.importing.base.modules_for_appname(appname)
Return a generator over the instances of an apps’ registered class-based modules
- class clu.importing.proxy.ChainModuleMap(*dicts, fallbacks=None, **overrides)
Custom “clu.dicts.ChainMap” subclass, tailored for module dicts.
In addition to the arguments accepted by its ancestor, one may pass in a sequence of functions as a keyword argument “fallbacks”. Each of these functions should accept exactly one argument – a mapping key string – and either return something for it, or raise either an AttributeError or a KeyError.
… This is meant to allow one to pass in one or more module-level “__getattr__(…)” functions, “Mapping.__missing__(…)” methods, or similar callables – the ChainModuleMap “__missing__(…)” method itself will attempt to invoke these functions in order, should it be called upon (hence the name “fallbacks”).
- class clu.importing.proxy.ProxyModule(name, *targets, doc=None)
A ProxyModule is a specific type of module: one that wraps one or more other things and surfaces their attributes, as if they are all one big unified module.
In this case, “things” can be modules, mappings, or callables – the ProxyModule employs a bespoke ChainMap subclass to keep these varied targets in order, for idempotent access with deterministic ordering, like in a way that ought not surprise or scare anybody.
Callable targets are fallbacks – they are invoked by the “__missing__” method of the internal ChainMap, when attribute lookup across all of the module and mapping proxy targets is exhaustively unsuccessful.
The ProxyModule is a “pseudo-template” type – you need to specialize it with the specific Module types with which you wish to use it. In nearly every use-case scenario, this means using one of the Module class types you have obtained through calling “initialize_types(…)” (as above) – like so:
>>> Module, Finder, Loader = initialize_types(my_appname) >>> class myproxy(ProxyModule[Module]): >>> # …etc
Here’s a basic example of a ProxyModule subtype definition:
>>> overrides = dict(…) >>> from yodogg.app import base_module >>> from yodogg.utils import misc as second_module >>> from yodogg.utils.functions import default_factory
>>> class myproxy(ProxyModule[Module]): >>> targets = (overrides, base_module, >>> second_module, >>> default_factory)
… which after defining that, you’d use it like so – assuming your app is called “yodogg” with a default “app” appspace (see “ModuleBase” for more on these terms):
>>> from yodogg.app import myproxy >>> myproxy.attrib # searches overrides, base_module and second_module >>> # in sequence, looking for the 'attrib' value >>> dir(myproxy) # returns a list of the union of available stuff, >>> # across the proxy modules’ targets >>> myproxy.NOATTR # unknown attributes will be forwarded to each >>> # module-level “__getattr__(…)” function, dictionary >>> # “__missing__(…)” method, or callable target found, >>> # in turn, if the attribute search proves exhaustive
… you can, in the modules’ definition, include other stuff besides the class-level “targets” tuple; other elements added to the proxy will behave like elements of any other class-based module.
clu.keyvalue
- class clu.keyvalue.CLUInterface(*args, **kwargs)
- as_dict()
Return a plain dict with the key-value stores’ contents.
- close()
Attept to close zicts
- count()
Return the number of items in this key-value store.
- delete(key)
Delete a value from this key-value store.
- get(key, default=<class 'clu.constants.consts.NoDefault'>)
Return a value from this key-value store.
- has(key)
Test if a key is contained in this key-value store.
- items()
Return an iterable yielding (key, value) for all items in this key-value store.
- iterate()
Return an iterator for this key-value store.
- keys()
Return an iterable with all of the keys in this key-value store.
- set(key, value)
Set and return a value in this key-value store.
- to_string()
Stringify the CLUInterface instance.
- update(dictish=<class 'clu.constants.consts.NoDefault'>, **updates)
Update the key-value store with key/value pairs and/or an iterator; q.v. dict.update(…) docstring supra.
- values()
Return an iterable with all of the values in this key-value store.
- clu.keyvalue.count()
Return the number of items in the key-value store.
- clu.keyvalue.delete(key)
Delete a value from the CLU user-config key-value store.
- clu.keyvalue.get(key, default=<class 'clu.constants.consts.NoDefault'>)
Return a value from the CLU user-config key-value store.
- clu.keyvalue.has(key)
Test if a key is contained in the key-value store.
- clu.keyvalue.items()
Return an iterable yielding (key, value) for all items in the key-value store.
- clu.keyvalue.iterate()
Return an iterator for the key-value store.
- clu.keyvalue.keys()
Return an iterable with all of the keys in the key-value store.
- clu.keyvalue.set(key, value)
Set and return a value in the CLU user-config key-value store.
- clu.keyvalue.update(dictish=<class 'clu.constants.consts.NoDefault'>, **updates)
Update the CLU key-value store with key/value pairs, and/or an iterator
- clu.keyvalue.values()
Return an iterable with all of the values in the key-value store.
clu.mathematics
- class clu.mathematics.Clamper(dtype)
A callable object representing a per-dtype clamp function
- property bits
A human-readable string showing the bitlength of the dtype
- property kind
A human-readable string describing the “kind” of the dtype
- clu.mathematics.isdtype(thing)
isdtype(thing) → boolean predicate, True if thing is a non-object numpy dtype
- clu.mathematics.isnumpything(thing)
isnumpything(thing) → boolean predicate, True if thing’s qualified module name starts with “numpy”
- clu.mathematics.isnumpythinglist(thinglist)
isnumpythinglist(thinglist) → boolean predicate, True if thinglist is a sequence of things from the “numpy” module
- clu.mathematics.isnumpytype(cls)
isnumpytype(cls) → boolean predicate, True if thing is from the “numpy” module and is a classtype
- clu.mathematics.isnumpytypelist(thinglist)
isnumpytypelist(thinglist) → boolean predicate, True if thinglist is a sequence of types from the “numpy” module
- clu.mathematics.Σ()
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
- clu.mathematics.σ(iterable, /, start=0)
Return the sum of a ‘start’ value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types.
clu.naming
- clu.naming.determine_module(thing, name=None)
Private module function to find the module of a thing, using “pickle.whichmodule(…)”
- clu.naming.dotpath_join(base, *addenda)
Join dotpath elements together as one, á la os.path.join(…)
- clu.naming.dotpath_split(dotpath)
For a dotted path e.g. yo.dogg.DoggListener, return a tuple (‘DoggListener’, ‘yo.dogg’). When called with a string containing no dots, dotpath_split(…) returns (string, None).
- clu.naming.dotpath_to_prefix(dotpath, sep='-', end='-')
Convert a dotted path into a “prefix” string, suitable for use with e.g. clu.fs.filesystem.TemporaryDirectory – e.g. ‘clu.typespace.namespace.SimpleNamespace’ becomes:
‘clu-typespace-namespace-simplenamespace-’
- clu.naming.duplicate(target, name, gs=None, **attributes)
Make a renamed copy of a target function.
- Q.v. pypy/rpython source supra:
- clu.naming.isbuiltin(thing)
isbuiltin(thing) → boolean predicate, True if thing is a builtin function/method/class
- clu.naming.isinspectable(thing)
isinspectable(thing) → boolean predicate, True if thing is inspectable, through the “inspect” modules’ myriad functions and types.
- clu.naming.isnative(thing)
isnative(thing) → boolean predicate, True if thing comes from a native-compiled (“extension”) module.
- clu.naming.isnativemodule(module)
isnativemodule(thing) → boolean predicate, True if module is a native-compiled (“extension”) module.
- Q.v. this fine StackOverflow answer on this subject:
- clu.naming.moduleof(thing, default=<class 'clu.constants.consts.NoDefault'>)
Determine in which module a given thing is ensconced, and return that modules’ name as a string … optionally specifying a “default” fallback.
- clu.naming.nameof(thing, default=<class 'clu.constants.consts.NoDefault'>)
Get the name of a thing, according to its attributes, how it appears as a registered item in any Exporter subclasses, or (failing any of those) as it appears in the module in which it appears to be ensconced – … optionally specifying a “default” fallback.
- clu.naming.path_to_prefix(path, sep='-', end='-', relative_to=PosixPath('/Users/fish/Dropbox/CLU/develop/lib/python3.9/site-packages'))
Shortcut for dotpath_to_prefix(path_to_dotpath(…))
- clu.naming.qualified_import(qualified)
Import a qualified thing-name. e.g. ‘instakit.processors.halftone.FloydSteinberg’
- clu.naming.qualified_name(thing)
Get a qualified thing-name for a thing. e.g. ‘instakit.processors.halftone.FloydSteinberg’
- clu.naming.qualified_name_tuple(thing)
Get the thing-name and module/package name for a class or module. e.g. (‘FloydSteinberg’, ‘instakit.processors.halftone’)
- class clu.naming.rename(named=None, path=None, dotpath=None)
Function-rename decorator. Use like so:
@rename(named=’yodogg’) def YoDogg(*args):
…
… or:
yodogg = lambda *args: … yodogg = rename()(yodogg) # awkward syntax, I know
- assign_name(function, name=None)
Assign the function’s new name. Returns the mutated function.
- clu.naming.renamer(name, gs=None, **attributes)
A decorator which renames the target function. Usage:
@renamer(‘yo_dogg’) def no_dogg():
# …
- Q.v. pypy/rpython source supra:
- clu.naming.split_abbreviations(s)
Split a string into a tuple of its unique constituents, based on its internal capitalization – to wit:
>>> split_abbreviations('RGB') ('R', 'G', 'B') >>> split_abbreviations('CMYK') ('C', 'M', 'Y', 'K') >>> split_abbreviations('YCbCr') ('Y', 'Cb', 'Cr') >>> split_abbreviations('sRGB') ('R', 'G', 'B') >>> split_abbreviations('XYZZ') ('X', 'Y', 'Z') >>> split_abbreviations('I;16B') ('I',)
If you still find this function inscrutable, have a look here: https://gist.github.com/4027079
- clu.naming.suffix(filename)
suffix(path) → return the suffix ≠ the file extension ≠ for a file pathname
clu.predicates
- class clu.predicates.Base
Base type for programmatically created new types.
Can be accessed as an attribute of “newtype(…)”, e.g. “newtype.Base”; q.v. the “newtype(…)” function sub.
- clu.predicates.accessor(function, thing, *attrs, default=None)
accessor(func, thing, *attributes) → return the first non-None value had by successively applying func(thing, attribute) to all attributes
- clu.predicates.acquirer(function, thing, *attrs, default=())
acquirer(func, thing, *attributes) → return all of the non-None values had by successively applying func(thing, attribute) to all attributes
- clu.predicates.allattrs(thing, *attrs)
allattrs(thing, *attributes) → boolean predicate, shortcut for all(hasattr(thing, atx) for atx in attributes)
- clu.predicates.allitems(thing, *items)
allitems(thing, *items) → boolean predicate, shortcut for all(hasitem(thing, itx) for itx in items)
- clu.predicates.allof(*items)
allof(*items) → Return the result of “all(…)” on all non-None arguments
- clu.predicates.allpyattrs(thing, *attrs)
allpyattrs(thing, *attributes) → boolean predicate, shortcut for all(haspyattr(thing, atx) for atx in attributes)
- clu.predicates.always(thing)
always(thing) → boolean predicate that always returns True
- clu.predicates.ancestral(atx, cls, default=())
ancestral(atx, cls[, default]) → shortcut for “attr_across(atx, *rmro(cls)[, default])”
- clu.predicates.ancestral_union(atx, cls, default=())
ancestral_union(atx, cls[, default]) → shortcut for “uniquify(iterchain(attr_across(atx, *mro(cls)[, default])))”
- clu.predicates.anyattrs(thing, *attrs)
anyattrs(thing, *attributes) → boolean predicate, shortcut for any(hasattr(thing, atx) for atx in attributes)
- clu.predicates.anyitems(thing, *items)
anyitems(thing, *items) → boolean predicate, shortcut for any(hasitem(thing, itx) for itx in items)
- clu.predicates.anyof(*items)
anyof(*items) → Return the result of “any(…)” on all non-None arguments
- clu.predicates.anypyattrs(thing, *attrs)
anypyattrs(thing, *attributes) → boolean predicate, shortcut for any(haspyattr(thing, atx) for atx in attributes)
- clu.predicates.apply_to(predicate, function, *things)
apply_to(predicate, function, *things) → Apply a predicate to each of the things, and finally a function to the entirety of the things, returning as that function returns. Like e.g.:
function(predicate(thing) for thing in things)
apply_to(predicate, function) → Return a Partial† function ƒ(*things) that will behave as apply_to(predicate, function, *things) when it is called as above.
† q.v. functools.partial(…) standard-library module function supra.
- clu.predicates.attr(thing, *attrs, default=None)
attr(thing, *attributes) → Return the first existing attribute from thing, given 1+ attribute names
- clu.predicates.attr_across(attribute, *things) → Return all of the existing named attributes across all things (given 1+ things)
- clu.predicates.attr_search(atx, *things, default=None)
attr_search(attribute, *things) → Return the first-found existing attribute from a thing, given 1+ things
- clu.predicates.attrs(thing, *attrs, default=())
attrs(thing, *attributes) → Return all of the existing named attributes from thing, given 1+ attribute names
- clu.predicates.case_sort(string) → Sorting predicate to sort UPPERCASE names first (spoilers: it doesn’t quite work actually)
- clu.predicates.class_has(cls, attribute) → boolean predicate, True if `cls` is a class type and has “attribute” (in either `__dict__` or `__slots__`)
- clu.predicates.collator(function, xatx, *things, default=())
collator(func, attribute, *things) → return all of the non-None values had by successively applying func(thing, attribute) across all things
- clu.predicates.dunder_or(thing, atx)
dunder_or(thing, atx) → Like “getpyattr(…)” only with a default return value of thing itself
- clu.predicates.enumchoices(cls)
enumchoices(cls) → Return a tuple of strings naming the members of an Enum class.
- clu.predicates.finditem(itx, *things, default=None)
finditem(itx, *mappings, default=None) → Return the first mapping that contains “itx”, or “default” if “itx” isn’t found in any of them
- clu.predicates.finditems(itx, *things, default=())
finditems(itx, *mappings, default=tuple()) → Return a tuple of all mappings that contain “itx”, or “default” if “itx” isn’t found in any of them
- clu.predicates.getitem(thing, itx, default=None)
getitem(thing, item[, default]) → shortcut for thing.get(item[, default])
- clu.predicates.getpyattr(thing, atx, default=None)
getpyattr(thing, attribute[, default]) → shortcut for getattr(thing, ‘__%s__’ % attribute[, default])
- clu.predicates.hasitem(thing, itx)
hasitem(thing, item) → boolean predicate, shortcut for item in thing
- clu.predicates.haslength(thing)
haslength(thing) → boolean predicate, True if thing has a “__len__” attribute
- clu.predicates.haspyattr(thing, atx)
haspyattr(thing, attribute) → boolean predicate, shortcut for hasattr(thing, ‘__%s__’ % attribute)
- clu.predicates.hoist(thing)
hoist(thing) → if “thing” isn’t already callable, turn it into a lambda that returns it as a value (using “wrap_value(…)”).
- clu.predicates.isancestor(cls, ancestor=<class 'object'>)
isancestor(thing, ancestor=object) → boolean predicate, True if ancestor is found in “mro(thing)”
- clu.predicates.isclass(thing)
isclass(thing) → boolean predicate, True if thing is a class, descending from object but not type
- clu.predicates.isclasstype(thing)
isclasstype(thing) → boolean predicate, True if thing is a class type, descending from either object or type
- clu.predicates.iscontainer(thing) → boolean predicate, True if `thing` is iterable and not “normative” (q.v. `isnormative(…)` supra.)
- clu.predicates.isdictish(thing)
isdictish(thing) → boolean predicate, True if thing has both an __mro__ and a __dict__ attribute
- clu.predicates.isenum(cls)
isenum(cls) → boolean predicate, True if cls descends from Enum.
- clu.predicates.isexpandable(thing)
isexpandable(thing) → boolean predicate, True if thing can be *expanded
- clu.predicates.isiterable(thing)
isiterable(thing) → boolean predicate, True if thing can be iterated over
- clu.predicates.ismergeable(thing)
ismergeable(thing) → boolean predicate, True if thing is a valid operand to merge(…) or merge_as(…)
- clu.predicates.ismetaclass(thing)
ismetaclass(thing) → boolean predicate, True if thing is a metaclass, descending directly from type
- clu.predicates.ismifflin(name)
Returns True if a _sunder_ name, False otherwise.
- clu.predicates.isnormative(thing)
isnormative(thing) → boolean predicate, True if thing is a string-like or bytes-like iterable
- clu.predicates.isnotnone(thing)
isnotnone(thing) → boolean predicate, return True if “thing” is not None
- clu.predicates.isorigin(cls, originator=<class 'object'>)
isorigin(thing, original=object) → boolean predicate, True if original is an ancestor of “origin(thing)”
- clu.predicates.ispublic(string)
ispublic(string) → boolean predicate, True if string is neither in __dunder__ or _sunder_ (née “_mifflin_”) form
- clu.predicates.ispyname(name)
Returns True if a __dunder__ name, False otherwise.
- clu.predicates.isslotdicty(thing)
isslotdicty(thing) → boolean predicate, True if thing has __mro__, __slots__, and __dict__ attributes
- clu.predicates.isslotted(thing)
isslotted(thing) → boolean predicate, True if thing has both an __mro__ and a __slots__ attribute
- clu.predicates.item(thing, *items, default=None)
item(thing, *itemnames) → Return the first existing item held by thing, given 1+ item names
- clu.predicates.item_across(attribute, *things) → Return all of the existing named items held across all things (given 1+ things)
- clu.predicates.item_search(itx, *things, default=None)
item_search(itemname, *things) → Return the first-found existing item from a thing, given 1+ things
- clu.predicates.items(thing, *items, default=())
items(thing, *itemnames) → Return all of the existing named items held by thing, given 1+ item names
- clu.predicates.itervariadic(function)
Wrap a variadic function – one with the signature “function(•args)” – in logic that allows it to be called with a single-argument iterable (“function(iterable)”) with the same effect.
Screens out strings, bytes-y, and file-path-ish operands without iterating or expanding them.
- clu.predicates.lambda_repr(instance, default='<lambda>')
lambda_repr(instance) → Equivalent to the built-in __repr__(…) method of a lambda function
- clu.predicates.listify(*items)
listify(*items) → Return a new list containing all non-None arguments
- clu.predicates.lowers(string)
lowers(string) → Sorting predicate, for sorting lowercase-containing names first – returns the lowercase character count
- clu.predicates.metaclass(thing)
metaclass(thing) → Returns: a) thing, if thing is a metaclass; b) type(thing), if thing is a class; or c) type(type(thing)), for all other instances
- clu.predicates.mro(thing) → Return the method resolution order (née “MRO”) tuple for thing (using “type(thing)” for non-classtype operands)
- clu.predicates.negate(function)
negate(function) → Negate a boolean function, returning the callable inverse.
### … You use negate(function) thusly:
>>> iscat = lambda thing: thing == 😺 >>> isnotcat = lambda thing: negate(iscat)(thing) # <-- SEE?? >>> iscat(😺) True >>> isnotcat(🐇) True >>> isnotcat(😺) False
### … You’ll find that negate(function) works great with builtin and stdlib functions:
>>> uncallable = lambda thing: negate(callable)(thing) # see below! >>> os.path.differentfile = negate(os.path.samefile) # I’ll admit to having done this >>> misfnmatch = negate(shutil.fnmatch.fnmatch) # There are times when this makes sense
- clu.predicates.never(thing)
never(thing) → boolean predicate that always returns False
- clu.predicates.newtype(name, *bases, metaclass=None, attributes=None, **keywords)
→ Shortcut for “type(name, tuple(bases) or (newtype.Base,), dict(attributes))”
q.v. https://docs.python.org/3/library/types.html#dynamic-type-creation supra.
- clu.predicates.no_op(thing, atx=None, default=None)
no_op(thing, attribute[, default]) → shortcut for (attribute or default)
- clu.predicates.noattr(obj, name, /)
noattr(thing, attribute) → boolean predicate, shortcut for (not hasattr(thing, attribute))
- clu.predicates.noattrs(thing, *attrs)
noattrs(thing, *attributes) → boolean predicate, shortcut for (not anypyattrs(*attributes)
- clu.predicates.noitem(thing, itx)
noitem(thing, item) → boolean predicate, shortcut for (not hasitem(thing, item))
- clu.predicates.noitems(thing, *items)
noitems(thing, *items) → boolean predicate, shortcut for (not anyitems(*attributes)
- clu.predicates.noneof(*items)
noneof(*items) → Return the result of “not any(…)” on all non-None arguments
- clu.predicates.nopyattr(thing, atx)
nopyattr(thing, attribute) → boolean predicate, shortcut for (not hasattr(thing, ‘__%s__’ % attribute))
- clu.predicates.nopyattrs(thing, *attrs)
nopyattrs(thing, *attributes) → boolean predicate, shortcut for (not any(haspyattr(thing, atx) for atx in attributes))
- clu.predicates.nuhuh(thing)
nuhuh(thing) → boolean predicate that always returns None
- clu.predicates.or_none(thing, atx)
or_none(thing, attribute) → shortcut for getattr(thing, attribute, None)
- clu.predicates.origin(thing)
origin(thing) → Return either typeof(thing).__origin__ or typeof(thing) for a given thing
- clu.predicates.predicate_all(predicate, *things)
predicate_all(predicate, *things) → boolean predicate, shortcut for apply_to(predicate, all, *things)
- clu.predicates.predicate_and(predicate, a, b)
predicate_and(predicate, a, b) → boolean predicate, shortcut for apply_to(predicate, all, a, b)
- clu.predicates.predicate_any(predicate, *things)
predicate_any(predicate, *things) → boolean predicate, shortcut for apply_to(predicate, any, *things)
- clu.predicates.predicate_none(predicate, *things)
predicate_none(predicate, *things) → boolean predicate, shortcut for apply_to(predicate, negate(any), *things)
- clu.predicates.predicate_or(predicate, a, b)
predicate_or(predicate, a, b) → boolean predicate, shortcut for apply_to(predicate, any, a, b)
- clu.predicates.predicate_xor(predicate, a, b)
predicate_xor(predicate, a, b) → boolean predicate, shortcut for apply_to(predicate, any, a, b) and not apply_to(predicate, all, a, b)
- clu.predicates.pyattr(thing, *attrs, default=None)
pyattr(thing, *attributes) → Return the first existing __special__ attribute from thing, given 1+ attribute names
- clu.predicates.pyattr_across(attribute, *things) → Return all of the existing named __special__ attributes across all things (given 1+ things)
- clu.predicates.pyattr_search(atx, *things, default=None)
pyattr_search(attribute, *things) → Return the first-found existing __special__ attribute from a thing, given 1+ things
- clu.predicates.pyattrs(thing, *attrs, default=())
pyattrs(thing, *attributes) → Return all of the existing named __special__ attributes from thing, given 1+ attribute names
- clu.predicates.pymodule(thing)
pymodule(thing) → Return either __module__ or __package__ from a given thing
- clu.predicates.pyname(thing)
pyname(thing) → Return either __qualname__ or __name__ from a given thing
- clu.predicates.resolve(thing, atx)
resolve(thing, atx) → retrieve and resolve an attribute, following each dotted segment, back from its host thing.
- Q.v. the standard library “operator” module notes supra.:
https://docs.python.org/3/library/operator.html#operator.attrgetter
- clu.predicates.retrieve(thing, itx, default=None)
retrieve(thing, item[, default]) → shortcut for hasitem(thing, itx) and thing or default
- clu.predicates.reverse(function)
reverse(function) → Reverse an iterating function, returning the reverse of the iterable returned.
- clu.predicates.rmro(thing) → Return the reverse of the method resolution order (née “MRO”) tuple for thing (using “type(thing)” for non-classtype operands)
- clu.predicates.searcher(function, xatx, *things, default=None)
searcher(func, attribute, *things) → return the first non-None value had by successively applying func(thing, attribute) sequentially to all things
- clu.predicates.slots_for(cls)
slots_for(cls) → get the summation of the __slots__ tuples for a class and its ancestors
- clu.predicates.stattr(thing, *attributes) → Statically return the first existing attribute from `thing`, given 1+ attribute names (q.v. “inspect.getattr_static(¬)” supra.)
- clu.predicates.stattr_across(attribute, *things) → Statically return all of the existing named attributes across all things (given 1+ things) (q.v. “inspect.getattr_static(¬)” supra.)
- clu.predicates.stattr_search(attribute, *things) → Statically return the first-found existing attribute from a thing, given 1+ things (q.v. “inspect.getattr_static(¬)” supra.)
- clu.predicates.stattrs(thing, *attributes) → Statically return all of the existing named attributes from `thing`, given 1+ attribute names (q.v. “inspect.getattr_static(¬)” supra.)
- clu.predicates.stor_none(thing, atx)
stor_none(thing, attribute) → shortcut for inspect.getattr_static(thing, attribute, None)
- clu.predicates.stresolve(thing, atx)
stresolve(thing, atx) → statically retrieve and resolve an attribute, following each dotted segment, back from its host thing.
- Q.v. the standard library “operator” module notes supra.:
https://docs.python.org/3/library/operator.html#operator.attrgetter
- clu.predicates.thing_has(thing, attribute) → boolean predicate, True if `thing` has “attribute” (in either `__dict__` or `__slots__`)
- clu.predicates.try_items(itx, *things, default=<class 'clu.constants.consts.NoDefault'>)
try_items(itx, *things[, default]) → attempt to retrieve an item from each of the things, in sequence – falling back to a default, or raising a KeyError if no default is specified.
This works like “item_search(itx, *things[, default])” – with the notable exception that, if any of the things are instances of “collections.defaultdict”, “try_items(…)” will correctly trigger any “defaultdict” instances’ default factories.
- clu.predicates.tuplize(*items)
tuplize(*items) → Return a new tuple containing all non-None arguments
- clu.predicates.typeof(thing)
typeof(thing) → Returns thing, if thing is a class type; or type(thing), if it is not
- clu.predicates.uncallable(obj, /)
uncallable(thing) → boolean predicate, shortcut for not callable(thing)
- clu.predicates.union(*items)
union(*items) → Return the set-union of the contents of all non-None arguments
- clu.predicates.uniquify(*items)
uniquify(*items) → Return a generator yielding a unique set of all non-None arguments
- clu.predicates.unwrap(thing)
unwrap(thing) → Return either thing.__wrapped__ or thing for a given thing
- clu.predicates.uppers(string)
uppers(string) → Sorting predicate, for sorting UPPERCASE-containing names first – returns the UPPERCASE character count
- clu.predicates.wrap_value(value)
wrap_value(value) → Get a “lazified” copy of value, wrapped in a lamba
clu.repl
- class clu.repl.ansi.ANSI(name, bases, attributes, **kwargs)
- convert(specifier)
Convert a specifier of unknown type to an enum or alias member
- for_name(name)
Get an enum member or alias member by name
- class clu.repl.ansi.ANSIBase(value)
Root ancestor class for all ANSI-code enums
- class clu.repl.ansi.ANSICodeHighlighter(language='python', markup='terminal256', style='paraiso-dark')
- render(string)
Render a string with respect to the Format instance.
- class clu.repl.ansi.ANSIFormat(from_value=None, text=Text.NOTHING, background=Background.NOTHING, weight=Weight.NORMAL)
The formatter class for ANSI markup codes.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- classmethod from_dict(format_dict)
Instantiate an ANSIFormat with a dict of related ANSI values – q.v. FIELD string names supra.
- classmethod get_or_create(text, background, weight)
Return an instance matching the given text/background/weight.
Any such instance found in the cache will be summarily returned; otherwise, a new instance is created and ensconced in the cache before finally ending up as the return itself.
- inner_repr()
Return a repr string for instances of this class
- classmethod instance_for(text, background, weight)
Return an instance matching a given text/background/weight from the instance cache, or – if such an instance can’t be found – raise a descriptive KeyError to indicate failure
- classmethod null()
Retrieve a “null instance” of ANSIFormat – one with all of its formatting directives unspecified.
- classmethod pre_existing(text, background, weight)
Boolean function to test the instance cache for the presence of an ANSIFormat instance matching a given text/background/weight
- render(string)
Render a string appropriately marked up with the ANSI formatting called for by this ANSIFormat instance, ending with the necessary ANSI reset sequence(s).
- to_dict()
Return the ANSI format primitives as a dict
- to_string()
Build up an initial ANSI format string based on values present
- to_tuple()
Return the ANSI format primitives as a tuple
- class clu.repl.ansi.ANSIFormatBase(text, background, weight)
- background
Alias for field number 1
- text
Alias for field number 0
- weight
Alias for field number 2
- class clu.repl.ansi.ANSISanitizer(*args)
- class clu.repl.ansi.Background(value)
Enumeration mapping ANSI codes to names found in “colorama.ansi.Back”
- class clu.repl.ansi.DualOptionWrapper(kwargs, kwalts)
- class clu.repl.ansi.HighlighterWrapper
- class clu.repl.ansi.ParagraphWrapper
- render(string)
Render a string with respect to the Format instance.
- class clu.repl.ansi.PygmentsHighlighter(language='python', markup='terminal256', style='paraiso-dark')
- render(string)
Render a string with respect to the Format instance.
- class clu.repl.ansi.StagedFormat(*args)
- render(string)
Render a string with respect to the Format instance.
- class clu.repl.ansi.Text(value)
Enumeration mapping ANSI codes to names found in “colorama.ansi.Fore”
- class clu.repl.ansi.TextWrapper(**kwargs)
- render(string)
Render a string with respect to the Format instance.
- class clu.repl.ansi.Weight(value)
Enumeration mapping ANSI codes to names found in “colorama.ansi.Style”
- clu.repl.ansi.highlight(code_string, language='python', markup='terminal256', style='paraiso-dark', isatty=True)
Highlight a code string with inline 256-color ANSI markup, using pygments.highlight(…) and the “Paraiso Dark” theme
- clu.repl.ansi.paragraphize(doc)
Split a docstring into continuous paragraphs.
- clu.repl.ansi.print_ansi(text, **kwargs)
print_ansi(…) → Print text in ANSI color, using optional inline markup from colorama for terminal color-escape delimiters
- clu.repl.ansi.print_ansi_centered(text=None, filler='•', width=None, color=None, file=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, **kwargs)
print_ansi_centered(…) → Print a string to the terminal, centered and bookended with asterisks
- clu.repl.ansi.print_ansi_name_value(name, value, most=25, pilcrow='\x1b[31m\x1b[22m»\x1b[0m', equals='\x1b[90m\x1b[22m:\x1b[0m', color=ANSIFormat(text=NOTHING, background=NOTHING, weight=NORMAL) @ 0x1063f7630, file=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, namecolor=ANSIFormat(text=LIGHTBLUE_EX, background=NOTHING, weight=NORMAL) @ 0x1063f72c0, valuecolor=ANSIFormat(text=LIGHTBLACK_EX, background=NOTHING, weight=NORMAL) @ 0x1063f74f0, **kwargs)
Format and colorize each segment of the name/value output
- clu.repl.ansi.print_separator(filler='-')
print_separator(filler=’-’) → print ‘filler’ character consts.SEPARATOR_WIDTH times
- clu.repl.ansi.signature(thing)
Retrieve the signature for a thing, parsing the docstring if necessary.
- clu.repl.ansi.wrapper_kws(**kwargs)
wrapper_kws(**kwargs) → prepare default arguments for instancing a “textwrap.TextWrapper”
Transform an iterable list of something into a columnized string representation.
Adapted from the routine of the same name found in “cmd.py”; further messed with to remove all the “pass” statements, simplify keyword-arg handling, normalize basically all of the argument names, and generally adapt it to the CLU world.
Q.v. the original pre-CLU version supra: https://git.io/JvPfl
- class clu.repl.columnize.Percenter(opstring)
A format type that uses the %% (string-interpolation) operator on its opstring to render its operands.
- render(string)
Render a string with respect to the Format instance.
- class clu.repl.columnize.StrMethod(opstring)
A format type that uses a call to the “format(…)” method on its opstring to render its operands.
- render(string)
Render a string with respect to the Format instance.
- clu.repl.columnize.columnize(array, display_width=129, **opts)
- Return a list of strings as a compact set of columns, distributed
horizontally or vertically.
- For example, for a line width of 4 characters (arranged vertically):
[‘1’, ‘2,’, ‘3’, ‘4’] → ‘1 3
2 4 ‘
- … or arranged horizontally:
[‘1’, ‘2,’, ‘3’, ‘4’] → ‘1 2
3 4 ‘
Each column is only as wide as necessary. By default, columns are separated by two spaces - one wasn’t legible enough.
Set the “separator” option to adjust the string separate columns.
Set “display_width” to set the line width.
Normally, consecutive items go down from the top to bottom from the left-most column to the right-most. If “vertical_display” is set false, consecutive items will go across, left to right, top to bottom.
- class clu.repl.modules.Mismatch(which, determine, modulename, thingname, idx)
- determine
Alias for field number 1
- idx
Alias for field number 4
- modulename
Alias for field number 2
- thingname
Alias for field number 3
- which
Alias for field number 0
- class clu.repl.modules.Mismatches(total, mismatch_records, failure_rate)
- failure_rate
Alias for field number 2
- mismatch_records
Alias for field number 1
- total
Alias for field number 0
- class clu.repl.modules.ModuleMap(module)
An adaptor class, wrapping a module and providing access to that modules’ non-dunder-named exports through an implementation of the “collections.abc.Mapping” interface.
- clone(deep=False, memo=None)
Return a cloned copy of the ModuleMap instance
- inner_repr()
Return a repr string for instances of this class
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- most()
Return the string-length of the longest item name in the module
- values() an object providing a view on D's values
- class clu.repl.modules.Result(modulename, thingnames, idx)
- idx
Alias for field number 2
- modulename
Alias for field number 0
- thingnames
Alias for field number 1
- class clu.repl.modules.Results(total, modulenames, result_records)
- modulenames
Alias for field number 1
- result_records
Alias for field number 2
- total
Alias for field number 0
- clu.repl.modules.compare_module_lookups_for_all_things(*modules, **options)
Iterate through each exported item, for each exported module, and look up the original module of the exported item with both:
“pickle.whichmodule(…)” and
“clu.naming.moduleof(…)”
… comparing the results of the two search functions and computing the overall results.
- clu.repl.modules.isplural(integer)
isplural(integer) → returns an ‘s’ unless the integer argument is 1, in which case it returns an empty string
- clu.repl.modules.notpyname(name)
notpyname(string) → boolean predicate, returns True unless string is a __dunder__ name, when it returns False
clu.repr
- clu.repr.chop_instance_repr(instance)
Discard the the object-instance hex ID portion of an instance repr string
- clu.repr.compare_instance_reprs(repr0, *reprX)
Compare two or more instance reprs after discarding the object-instance hex ID
- clu.repr.fullrepr(instance, string)
Return a “full-repr” string for an instance and a given string.
For example, in the case of the following repr-stle string:
TypeName(fieldname=”val”, otherfieldname=”otherval”) @ 0x0FE
…the parameter “string” is the portion if the full-repr string that reads:
“fieldname=”val”, otherfieldname=”otherval””
… whereas the ‘TypeName’ and hex-ID portions are derived from the “instance” parameter.
- clu.repr.hexid(thing)
hexid(thing) → Return the hex-ified representation of “thing”’s ID – Equivalent to “hex(id(thing))”
- clu.repr.strfields(instance, fields, *extras, try_callables=True, **attributes)
Stringify an object instance, using an iterable field list to extract and render its values, and printing them along with the typename of the instance and its memory address – yielding a repr-style string of the format:
“fieldname=”val”, otherfieldname=”otherval””
The strfields(…) function is of use in __str__() and __repr__() definitions, e.g. something like:
- def inner_repr(self):
return strfields(self, type(self).__slots__)
- def __repr__(self):
typename, hex_id = typename_hexid(self) attr_string = self.inner_repr() return f”{typename}({attr_string}) {consts.REPR_DELIMITER} {hex_id}”
Callable fields, by default, will be called with no arguments to obtain their value. To supress this behavior – if you wish to represent callable fields that require arguments – you can pass the keyword-only “try_callables” flag as False:
- def inner_repr(self):
- return strfields(self,
type(self).__slots__, try_callables=False)
- clu.repr.stringify(instance, fields, *extras, try_callables=True, **attributes)
Stringify an object instance, using an iterable field list to extract and render its values, and printing them along with the typename of the instance and its memory address – yielding a repr-style string of the format:
TypeName(fieldname=”val”, otherfieldname=”otherval”) @ 0x0FE
The stringify(…) function is of use in __str__() and __repr__() definitions, e.g. something like:
- def __repr__(self):
return stringify(self, type(self).__slots__)
Callable fields, by default, will be called with no arguments to obtain their value. To supress this behavior – if you wish to represent callable fields that require arguments – you can pass the keyword-only “try_callables” flag as False:
- def __repr__(self):
- return stringify(self,
type(self).__slots__, try_callables=False)
- clu.repr.typename_hexid(thing)
typename_hexid(thing) → Return a two-tuple containing “thing”’s hex-ified ID and the string name of the type of “thing” – Equivalent to “(hexid(thing), typenameof(thing))”
- clu.repr.typenameof(thing)
typenameof(thing) → Return the string name of the type of “thing” – Equivalent to “pyname(typeof(thing))”, q.v. “clu.predicates”
clu.sanitizer
- clu.sanitizer.sanitize(text)
sanitize(text) → Remove specific unicode strings, in favor of ASCII-friendly versions, from the text passed in to the function
- clu.sanitizer.sanitizers()
sanitizers() → shortcut to get a tuple of tuples listing the registered sanitizers
- clu.sanitizer.utf8_decode(source)
utf8_decode(source) → Decode a source from UTF-8 bytes to a string using Python 3 semantics
- clu.sanitizer.utf8_encode(source)
utf8_encode(source) → Encode a source as a UTF-8 bytes object using Python 3 semantics
clu.scripts
- clu.scripts.prediversus.predicate_test(predicate, argument) → executes `predicate(argument)`, returning (`predicate`, `argument`, `predicate(argument)`)
- clu.scripts.prediversus.predicate_test_repr(predicate, argument) → stringifies `predicate` and `argument` – both individually and as the complete expression `predicate(argument)` – returning («operand string», «expression string»)
repl.py – THE RUBRICK:
- Import all modules with an exporter, excluding those from a list
… e.g. equivalent to “import clu.exporting”, etc.
- Import modules without an exporter, including those from a list
… e.g. “clu.constants.consts” and friends
Export everything from modules from (1) and (2) into the global namespace
Import additional modules (whether CLU, stdlib, or third-party) and just leave the modules themselves hanging out in the global namespace
Deal with any nitpicks – e.g. “from pprint import pprint”, “from clu.testing.utils import pout” and what have you
PUSH IT REAL GOOD
LOOK ON MY WORK, YE MIGHTY, AND MAYBE BE LIKE “I COULD USE THAT”
clu.shelving
clu.stdio
- class clu.stdio.TermSize(id: str = <factory>, width: int = <factory>, height: int = <factory>)
- clu.stdio.flush_all()
flush_all() → flush the output buffers of all possible stdout candidates
- clu.stdio.linebreak()
linebreak() → print a newline to stdout
- clu.stdio.terminal_size()
Deeper cut than “os.get_terminal_size(…)” value in “consts”
clu.testing
- clu.testing.pytest.clumods(consts)
Import all CLU modules that use the “clu.exporting.Exporter” mechanism for listing and exporting their module contents
- clu.testing.pytest.cluversion()
Fixture providing access to the current base version identifier – née the “semver” or “semantic version” – of the CLU project
- clu.testing.pytest.consts()
Fixture providing access to the CLU constants module, which you may know as “clu.constants.consts”
- clu.testing.pytest.datadir(dirname)
Local version of pytest-datadir’s “datadir” fixture, reimplemented using clu.fs.filesystem classes – ensuring that the temporary directory will be deleted immediately after use – and performing its copy operations through instance methods (vs. the raw calls to “shutil.copytree(…)” made by “datadir”).
- clu.testing.pytest.dirname(request)
Fixture for wrapping up the “request.fspath.dirname” value in a clu.fs.filesystem.Directory instance – this is intended to be a read-only value (no way to enforce that just now) so we only run it once per test package (which really there is one test package, total, so you see what we’re going for here doggie).
- clu.testing.pytest.environment()
Environment testing fixture: yields an instance of os.environ, free of XDG variables
Q.v. implementation https://git.io/JeYmf supra.
- clu.testing.pytest.gitrun()
Boolean fixture indicating whether or not this session is running within a Git repo (vs. like a tarball or somesuch).
- clu.testing.pytest.greektext()
Greek-text fixture: yield a dictionary with several lorem-ipsum-ish blocks of text.
Keys to the available texts are:
“lorem” (the classic),
“faust” (lots of Germanic short capitalized words),
“thoreau” (in actual English), and
“poe” (exerpted from The Raven, because I live in Baltimore)
- … All these came straight from the output of the top-notch lorem CLT:
- clu.testing.pytest.pytest_addhooks(pluginmanager)
Add all hooks defined in the “clu.testing.hooks” module
- clu.testing.pytest.pytest_addoption(parser, pluginmanager)
Set up the CLI/config option for “–delete-temps”
- clu.testing.pytest.pytest_configure(config)
Add the pytest custom markers used in CLU’s testing extensions
- clu.testing.pytest.pytest_sessionfinish(session, exitstatus)
Hook function to bind an exit handle – using “clu.dispatch” via the ‘@exithandle’ decorator – that removes any remaining temporary-file artifacts that may be hanging out in the putative directory “$TMPDIR/pytest-of-$USER”.
The exit handle function is bound if the exit status is “natural” – i.e. no internal errors and tests ran normally (this can include occasions when tests fail) – and if the relevant CLI, INI, and hook function values indicate said binding is warranted by the user.
The exit handle function executes when the Python interpreter either enters shutdown (via the “atexit” module) or receives a terminating signal (via the “signal” module).
- clu.testing.pytest.temporarydir()
clu.fs.filesystem.TemporaryDirectory fixture factory: yields a new instance of TemporaryDirectory, without making any calls to “os.chdir()”.
- clu.testing.pytest.temporaryname()
clu.fs.filesystem.TemporaryName fixture-factory function: yields a function returning new instances of TemporaryName, which can be called multiple times – each time producing a new TemporaryName instance under automatic context-management (via a behind-the-scenes “contextlib.ExitStack” instance).
The parent fixture is module-scoped; when the module in which this fixture-factory function was first invoked enters cleanup, the ExitStack is unwound and all TemporaryName instances are __exit__(…)-ed at that time.
clu.typespace
- clu.typespace.modulize(name, namespace, docs=None, path=None, appname='clu', basepath=PosixPath('/Users/fish/Dropbox/CLU/develop/lib/python3.9/site-packages'))
Convert a dictionary mapping into a legit Python module
- class clu.typespace.namespace.BaseNamespace(*args, **kwargs)
The abstract base for SimpleNamespace and Namespace.
- clone(deep=False, memo=None)
Return a cloned copy of this instance
- class clu.typespace.namespace.Namespace(*args, **kwargs)
Namespace adds the get(…), __len__(), __contains__(…), __getitem__(…), __setitem__(…), and __add__(…) methods to its ancestor class implementation BaseNamespace.
Since it implements a get(…) method, Namespace instances can be passed to merge(…) – q.v. merge(…) function definition supra.
The Namespace class also furnishes a __missing__(…) method, which can be overridden by subclasses to provide “collections.defaultdict”–like behaviors.
- get(key, default=<class 'clu.constants.consts.NoDefault'>)
Return the value for key if key is in the namespace, else default.
- pop(key, default=<class 'clu.constants.consts.NoDefault'>)
Return the value for key if key is in the namespace, else default, removing the key/value pairing if the key was found.
- update(dictish=None, **updates)
Update the namespace with key/value pairs and/or an iterator; q.v. dict.update(…) docstring supra.
- class clu.typespace.namespace.NamespaceRepr(*args, maxlevel=10, maxstring=120, maxother=120, **kwargs)
Custom Repr-izer for SimpleNamespace and Namespace mappings, which can recursively self-contain.
q.v. cpython docs, http://bit.ly/2r1GQ4l supra.
- fullrepr(thing, short=False)
Return the “full” repr of a namespace instance.
- primerepr(thing, level)
The internal method for “core” repr production of all namespace descendant types.
- repr_BaseNamespace(thing, level)
Return the “core” repr for a specific instance of “clu.typespace.namespace.BaseNamespace” – just the stringification of the key-value pairs, without the typename or instance-id adornment.
- repr_Namespace(thing, level)
Return the “core” repr for a specific instance of “clu.typespace.namespace.Namespace” – just the stringification of the key-value pairs, without the typename or instance-id adornment.
- repr_SimpleNamespace(thing, level)
Return the “core” repr for a specific instance of “clu.typespace.namespace.SimpleNamespace” – just the stringification of the key-value pairs, without the typename or instance-id adornment.
- shortrepr(thing)
Return the “short” repr of a namespace instance – all whitespace will be condensed to single spaces without newlines.
- subrepr(thing, level)
An internal “core” repr helper method.
- class clu.typespace.namespace.SimpleNamespace(*args, **kwargs)
Implementation courtesy this SO answer: • https://stackoverflow.com/a/37161391/298171
Additionally, SimpleNamespace furnishes an __hash__(…) method.
- clu.typespace.namespace.isnamespace(thing)
isnamespace(thing) → boolean predicate, True if the name of the type of “thing” is amongst those of the quote-unquote “Namespace tower”, as defined in the module “clu.typespace.namespace”
- clu.typespace.namespace.nsrepr(x)
Return the “core” repr for any descendant ChainMap type.
- clu.typespace.namespace.nsshortrepr(thing)
Return the “short” repr of a namespace instance – all whitespace will be condensed to single spaces without newlines.
clu.typology
- clu.typology.differentlength(a, b)
differentlength(a, b) → boolean predicate, True if both len(a) and len(b) are defined, but are unequal
- clu.typology.graceful_issubclass(putative, *thinglist)
subclasscheck(putative, *cls_or_tuple) → A wrapper for issubclass(…) and isinstance(…) that tries to work with you
- clu.typology.hasaliases(thing)
hasaliases(cls) → boolean predicate, True if cls descends from Enum and has 1+ items in its __aliases__ dict
- clu.typology.hasmembers(thing)
hasmembers(cls) → boolean predicate, True if cls descends from Enum and has 1+ items in its __members__ dict
- clu.typology.isabc(thing)
isabc(thing) → boolean predicate, True if thing is an abstract base class (née ‘ABC’) or a descendant or instance of same
- clu.typology.isabclist(thinglist) → boolean predicate, True if `thinglist` is a sequence of abstract base classes (née ABCs)
- clu.typology.isabstract(thing) → boolean predicate, True if `thing` is an abstract method OR an “abstract base class” (née ABC)
- clu.typology.isabstractcontextmanager(cls)
isabstractcontextmanager(thing) → boolean predicate, True if thing decends from contextlib.AbstractContextManager
- clu.typology.isabstractmethod(method)
isabstractmethod(thing) → boolean predicate, True if thing is a method declared “abstract” with @abc.abstractmethod
- clu.typology.isaliasdescriptor(thing)
isaliasdescriptor(thing) → boolean predicate, returns True if thing is an aliasing descriptor bound to an existing Enum member
- clu.typology.isarray(thing)
isarray(thing) → boolean predicate, True if thing is an array type or an instance of same
- clu.typology.isarraylist(*things)
isarraylist(thinglist) → boolean predicate, True if thinglist is a sequence of array types
- clu.typology.isbytes(thing)
isbytes(thing) → boolean predicate, True if thing is a bytes-like type or an instance of same
- clu.typology.isbyteslist(*things)
isbyteslist(thinglist) → boolean predicate, True if thinglist is a sequence of bytes-like types
- clu.typology.iscallable(thing)
iscallable(thing) → boolean predicate, True if thing is a callable type (a class with a “__call__” method) or an instance of same
N.B. this predicate is NOT the same as the built-in “callable(…)” predicate
- clu.typology.iscallablelist(thinglist) → boolean predicate, True if `thinglist` is a sequence of callable types (class types with “__call__” methods or instances of same)
- clu.typology.iscallabletype(thing) → boolean predicate, True if `thing` is one of the predefined callable types (q.v. “clu.typology.callable_types” supra.)
- clu.typology.iscallabletypelist(thinglist) → boolean predicate, True if `thinglist` is a sequence of predefined callable types (q.v. “clu.typology.callable_types” supra.)
- clu.typology.iscomplex(thing)
iscomplex(thing) → boolean predicate, True if thing is a complex numeric type or an instance of same
- clu.typology.iscomplexlist(*things)
iscomplexlist(thinglist) → boolean predicate, True if thinglist is a sequence of complex numeric types
- clu.typology.iscontextmanager(thing) → boolean predicate, True if `thing` is a context manager (either abstract or concrete)
- clu.typology.isderivative(putative, thing)
isderivative(putative, thing) → Boolean predicate, True if putative is either a subclass or an instance of thing – depending on whether putative is either a classtype or an instance, basically.
Used internally to implement subclasscheck(…) (née “graceful_issubclass(…)”).
- clu.typology.isextensibletype(thing) → boolean predicate, True if `thing` is an “extensible” type (q.v. “clu.extending” source supra.)
- clu.typology.isfunction(thing)
ΛΛ(thing) → boolean predicate, True if thing is of a callable function type
- clu.typology.isfunctionlist(*things)
isfunctionlist(thinglist) → boolean predicate, True if thinglist is a sequence of callable function types
- clu.typology.ishashable(thing)
ishashable(thing) → boolean predicate, True if thing can be hashed, via the builtin hash(…) function
- clu.typology.ishashablelist(*things)
ishashablelist(thinglist) → boolean predicate, True if thinglist is a sequence of things that can be hashed, via the builtin hash(…) function
- clu.typology.isitemsview(thing)
isitemsview(thing) → boolean predicate, True if thing is a mapping-items view instance
- clu.typology.iskeysview(thing)
iskeysview(thing) → boolean predicate, True if thing is a mapping-keys view instance
- clu.typology.islambda(thing)
λλ(thing) → boolean predicate, True if thing is a function created with the «lambda» keyword
- clu.typology.islambdalist(*things)
islambdalist(thinglist) → boolean predicate, True if thinglist is a sequence of functions created with the «lambda» keyword
- clu.typology.ismapping(thing)
ismapping(thing) → boolean predicate, True if thing is a mapping (dict-ish) type or an instance of same
- clu.typology.ismappinglist(*things)
ismappinglist(thinglist) → boolean predicate, True if thinglist is a sequence of mapping (dict-ish) types
- clu.typology.ismetatypelist(*things)
ismetatypelist(thing) → boolean predicate, True if thing is a “metatypelist” – a list consisting only of metaclass types
- clu.typology.ismodule(thing)
ismodule(thing) → boolean predicate, True if thing is a module type or an instance of same
- clu.typology.ismodulelist(*things)
ismodulelist(thinglist) → boolean predicate, True if thinglist is a sequence of module types
- clu.typology.isnotpath(thing)
isnotpath(thing) → boolean predicate, True if thing seems not to be a path-ish instance
- clu.typology.isnumber(thing)
isnumber(thing) → boolean predicate, True if thing is a numeric type or an instance of same
- clu.typology.isnumberlist(*things)
isnumberlist(thinglist) → boolean predicate, True if thinglist is a sequence of numeric types
- clu.typology.isnumeric(thing)
isnumeric(thing) → boolean predicate, True if thing is a numeric type or an instance of same
- clu.typology.isnumericlist(*things)
isnumericlist(thinglist) → boolean predicate, True if thinglist is a sequence of numeric types
- clu.typology.ispath(thing)
ispath(thing) → boolean predicate, True if thing seems to be a path-ish instance
- clu.typology.ispathlist(*things)
ispathlist(thinglist) → boolean predicate, True if thinglist is a sequence of path-like instances
- clu.typology.ispathtype(cls)
ispathtype(thing) → boolean predicate, True if thing is a path type
- clu.typology.ispathtypelist(*things)
ispathtypelist(thinglist) → boolean predicate, True if thinglist is a sequence of path-related class types
- clu.typology.isscalar(thing)
isscalar(thing) → boolean predicate, True if thing is a numpy scalar numeric type or an instance of same
- clu.typology.isscalarlist(*things)
isscalarlist(thinglist) → boolean predicate, True if thinglist is a sequence of numpy scalar numeric types
- clu.typology.issequence(thing) → boolean predicate, True if `thing` is a sequence type (e.g. a `tuple` or `list` type)
- clu.typology.issequencelist(*things)
issequencelist(thinglist) → boolean predicate, True if thinglist is a sequence of sequence types
- clu.typology.issingleton(thing)
issingleton(thing) → boolean predicate, True if thing is one of the “singleton” types: True, False, None, Ellipsis (aka “…”) or NotImplemented
- clu.typology.issingletonlist(*things)
issingletonlist(thinglist) → boolean predicate, True if thinglist is a sequence of things that are amongst the “singleton” types: True, False, None, Ellipsis (aka “…”) or NotImplemented
- clu.typology.isslottedtype(thing)
isslottedtype(thing) → boolean predicate, True if thing has “clu.exporting.Slotted” as its metaclass
- clu.typology.isstring(thing)
isstring(thing) → boolean predicate, True if thing is a string type or an instance of same
- clu.typology.isstringlist(*things)
isstringlist(thinglist) → boolean predicate, True if thinglist is a sequence of string types
- clu.typology.istypelist(*things)
istypelist(thing) → boolean predicate, True if thing is a “typelist” – a list consisting only of class types
- clu.typology.isunique(thing)
isunique(thing) → boolean predicate, True if thing is an iterable with unique contents
- clu.typology.isvalidpath(thing)
isvalidpath(thing) → boolean predicate, True if thing represents a valid path on the filesystem
- clu.typology.isvalidpathlist(*things)
isvalidpathlist(thinglist) → boolean predicate, True if thinglist is a sequence of valid filesystem path instances
- clu.typology.isvaluesview(thing)
isvaluesview(thing) → boolean predicate, True if thing is a mapping-values view instance
- clu.typology.isview(thing)
isview(thing) → boolean predicate, True if thing is any sort of mapping view instance – keys, values, or items
- clu.typology.isxlist(predicate, thinglist)
isxlist(predicate, thinglist) → boolean predicate, True if thinglist is a sequence of items, all of which match the predicate function
- clu.typology.isxmetatypelist(predicate, thinglist)
isxmetatypelist(predicate, thinglist) → boolean predicate, True if thinglist is a metatypelist, all types in which match the predicate function
- clu.typology.isxtypelist(predicate, thinglist)
isxtypelist(predicate, thinglist) → boolean predicate, True if thinglist is a typelist, all types in which match the predicate function
- clu.typology.iterlen(iterable)
iterlen(iterable) → Return the number of items in “iterable.”
This will consume iterables without a “__len__()” method – be careful!
- clu.typology.makemetatypelist(*things)
makemetatypelist(iterable) → convert an iterable of unknown things into a uniquified metatypelist – a list consisting only of metaclass types
- clu.typology.maketypelist(*things)
maketypelist(iterable) → convert an iterable of unknown things into a uniquified typelist – a list consisting only of class types
- clu.typology.metaclasscheck(putative, *thinglist)
metaclasscheck(putative, *cls_or_tuple) → A wrapper for issubclass(…) and isinstance(…) that specifically inspects the metaclass of its primary operand
- clu.typology.samelength(a, b)
samelength(a, b) → boolean predicate, True if both len(a) and len(b) are defined and equal to each other
- clu.typology.subclasscheck(putative, *thinglist)
subclasscheck(putative, *cls_or_tuple) → A wrapper for issubclass(…) and isinstance(…) that tries to work with you
- clu.typology.ΛΛ(thing)
ΛΛ(thing) → boolean predicate, True if thing is of a callable function type
- clu.typology.λλ(thing)
λλ(thing) → boolean predicate, True if thing is a function created with the «lambda» keyword
clu.version
- class clu.version.VersionAncestor(major, minor, patch, pre, build)
- build
Alias for field number 4
- major
Alias for field number 0
- minor
Alias for field number 1
- patch
Alias for field number 2
- pre
Alias for field number 3
- class clu.version.VersionInfo(from_value=None, major='‽', minor='‽', patch='‽', pre='‽', build=0)
NamedTuple-descendant class allowing for convenient and reasonably sane manipulation of semantic-version (née “semver”) string-triple numberings, or whatever the fuck is the technical term for them, erm. Yes!
- classmethod from_dict(version_dict)
Instantiate a VersionInfo with a dict of related values (q.v. FIELD string names supra.)
- classmethod from_string(version_string)
Instantiate a VersionInfo with a semver string
- to_dict()
Returns what you think it returns
- to_packaging_version()
aka an instance of pkg_resources.extern.packaging.version.Version
- to_string()
Return the VersionInfo data as a semver string
- to_tuple()
Return a complete tuple (as in, including “pre” and “build” fields)
- clu.version.comparator(operator)
Wrap a VersionInfo binary op method in a typechecker
- clu.version.compare_keys(dict1, dict2)
Blatantly based on code from “semver”: https://git.io/fhb98
- clu.version.git_version.are_we_gitted(directory=None)
Check if we’re in a Git repo
- clu.version.git_version.git_version_tags(directory=None)
Get the Git version tags
Extract your project’s __version__ variable
When creating a setup.py
for a new project, do you find yourself always
writing the same block of code for parsing __version__
from your project’s
source? Something like this?
with open(join(dirname(__file__), 'package_name', '__init__.py')) as fp:
for line in fp:
m = re.search(r'^\s*__version__\s*=\s*([\'"])([^\'"]+)\1\s*$', line)
if m:
version = m.group(2)
break
else:
raise RuntimeError('Unable to find own __version__ string')
setup(
version = version,
...
)
Someone needs to put all that into a reusable package, am I right? Well, someone did, and this is that package.
Visit <https://github.com/jwodder/read_version> for more information.
- clu.version.read_version.read_version(*fpath, **kwargs)
read_version()
takes one or more file path components pointing to a Python source file to parse. The path components will be joined together withos.path.join()
, and then, if the path isn’t absolute, the path to the directory containing the script callingread_version()
will be prepended to the path. (No morejoin(dirname(__file__), ...)
boilerplate needed!)read_version()
then parses the given Python file and searches through the parse tree for any assignments to a variable named__version__
, returning the last value assigned.The
variable
keyword argument can be set to the name of a variable other than__version__
to search for assignments to a different variable instead.If no assignments to the variable are found, a
ValueError
is raised. To instead return a default value when this happens, set thedefault
keyword argument.