requirementslib.utils module¶
-
exception
requirementslib.utils.
PathAccessError
(exc, seg, path)[source]¶ Bases:
KeyError
,IndexError
,TypeError
An amalgamation of KeyError, IndexError, and TypeError, representing what can occur when looking up a path in a nested object.
-
requirementslib.utils.
get_path
(root, path, default=<object object>)[source]¶ Retrieve a value from a nested object via a tuple representing the lookup path. >>> root = {‘a’: {‘b’: {‘c’: [[1], [2], [3]]}}} >>> get_path(root, (‘a’, ‘b’, ‘c’, 2, 0)) 3 The path format is intentionally consistent with that of
remap()
. One of get_path’s chief aims is improved error messaging. EAFP is great, but the error messages are not. For instance,root['a']['b']['c'][2][1]
gives backIndexError: list index out of range
What went out of range where? get_path currently raisesPathAccessError: could not access 2 from path ('a', 'b', 'c', 2, 1), got error: IndexError('list index out of range',)
, a subclass of IndexError and KeyError. You can also pass a default that covers the entire operation, should the lookup fail at any level. Args:- root: The target nesting of dictionaries, lists, or other
- objects supporting
__getitem__
. - path (tuple): A list of strings and integers to be successively
- looked up within root.
- default: The value to be returned should any
PathAccessError
exceptions be raised.
-
requirementslib.utils.
is_installable_file
(path)[source]¶ Determine if a path can potentially be installed
-
requirementslib.utils.
is_vcs
(pipfile_entry)[source]¶ Determine if dictionary entry from Pipfile is for a vcs dependency.
-
requirementslib.utils.
remap
(root, visit=<function default_visit>, enter=<function dict_path_enter>, exit=<function dict_path_exit>, **kwargs)[source]¶ The remap (“recursive map”) function is used to traverse and transform nested structures. Lists, tuples, sets, and dictionaries are just a few of the data structures nested into heterogenous tree-like structures that are so common in programming. Unfortunately, Python’s built-in ways to manipulate collections are almost all flat. List comprehensions may be fast and succinct, but they do not recurse, making it tedious to apply quick changes or complex transforms to real-world data. remap goes where list comprehensions cannot. Here’s an example of removing all Nones from some data: >>> from pprint import pprint >>> reviews = {‘Star Trek’: {‘TNG’: 10, ‘DS9’: 8.5, ‘ENT’: None}, … ‘Babylon 5’: 6, ‘Dr. Who’: None} >>> pprint(remap(reviews, lambda p, k, v: v is not None)) {‘Babylon 5’: 6, ‘Star Trek’: {‘DS9’: 8.5, ‘TNG’: 10}} Notice how both Nones have been removed despite the nesting in the dictionary. Not bad for a one-liner, and that’s just the beginning. See `this remap cookbook`_ for more delicious recipes. .. _this remap cookbook: http://sedimental.org/remap.html remap takes four main arguments: the object to traverse and three optional callables which determine how the remapped object will be created. Args:
- root: The target object to traverse. By default, remap
- supports iterables like
list
,tuple
,dict
, andset
, but any object traversable by enter will work. - visit (callable): This function is called on every item in
- root. It must accept three positional arguments, path,
key, and value. path is simply a tuple of parents’
keys. visit should return the new key-value pair. It may
also return
True
as shorthand to keep the old item unmodified, orFalse
to drop the item from the new structure. visit is called after enter, on the new parent. The visit function is called for every item in root, including duplicate items. For traversable values, it is called on the new parent object, after all its children have been visited. The default visit behavior simply returns the key-value pair unmodified. - enter (callable): This function controls which items in root
- are traversed. It accepts the same arguments as visit: the
path, the key, and the value of the current item. It returns a
pair of the blank new parent, and an iterator over the items
which should be visited. If
False
is returned instead of an iterator, the value will not be traversed. The enter function is only called once per unique value. The default enter behavior support mappings, sequences, and sets. Strings and all other iterables will not be traversed. - exit (callable): This function determines how to handle items
- once they have been visited. It gets the same three
arguments as the other functions – path, key, value
– plus two more: the blank new parent object returned
from enter, and a list of the new items, as remapped by
visit.
Like enter, the exit function is only called once per
unique value. The default exit behavior is to simply add
all new items to the new parent, e.g., using
list.extend()
anddict.update()
to add to the new parent. Immutable objects, such as atuple
ornamedtuple
, must be recreated from scratch, but use the same type as the new parent passed back from the enter function. - reraise_visit (bool): A pragmatic convenience for the visit
- callable. When set to
False
, remap ignores any errors raised by the visit callback. Items causing exceptions are kept. See examples for more details.
remap is designed to cover the majority of cases with just the visit callable. While passing in multiple callables is very empowering, remap is designed so very few cases should require passing more than one function. When passing enter and exit, it’s common and easiest to build on the default behavior. Simply add
from boltons.iterutils import default_enter
(ordefault_exit
), and have your enter/exit function call the default behavior before or after your custom logic. See `this example`_. Duplicate and self-referential objects (aka reference loops) are automatically handled internally, `as shown here`_. .. _this example: http://sedimental.org/remap.html#sort_all_lists .. _as shown here: http://sedimental.org/remap.html#corner_cases