Python utils#
Reraise#
Reraise an exception with an additional message.
Usage as contextmanager:
with epy.maybe_reraise(f'Error for {x}: '):
fn(x)
Usage using try/except:
try:
fn(x)
except Exception as e:
epy.reraise(e, prefix=f'Error for {x}: ')
Benefit: Contrary to raise ... from ...
and raise Exception().with_traceback(tb)
, this function will:
Keep the original exception type, attributes,…
Avoid multi-nested
During handling of the above exception, another exception occurred
. Only the single original stacktrace is displayed.
This result in cleaner and more compact error messages.
Text utils#
epy.pprint
: Pretty print a value, supportsdataclasses
.epy.pretty_repr
: Returns a prettyrepr()
of the given object, supportsdataclasses
.epy.reverse_fstring
: Parse string to match a f-string patternepy.reverse_fstring( '/home/{user}/projects/{project}', '/home/conchylicultor/projects/menhir' ) == { 'user': 'conchylicultor', 'project': 'menhir', }
epy.diff_str
: Pretty diff between 2 objects.epy.dedent
: Liketextwrap.dedent
but alsostrip()
the content.
Itertool utils#
epy.zip_dict
: Iterate over items of dictionaries grouped by their keys.d0 = {'a': 1, 'b': 2} d1 = {'a': 10, 'b': 20} for k, (v0, v1) in epy.zip_dict(d0, d1): ...
epy.groupby
: Similar toitertools.groupby
but return result as adict()
assert epy.groupby(['ddd', 'c', 'aa', 'aa', 'bbb'], key=len) == { 3: ['ddd', 'bbb'], 1: ['c'], 2: ['aa', 'aa'], }
epy.splitby
: Split the iterable into 2 lists (false, true), based on the predicate.small, big = epy.splitby([100, 4, 4, 1, 200], lambda x: x > 10) assert small == [4, 4, 1] assert big == [100, 200]
Class utils#
epy.ContextManager
: Allows to define contextmanager class usingyield
-syntax.Example:
class A(epy.ContextManager): def __contextmanager__(self) -> Iterable[A]: yield self with A() as a: pass
epy.frozen
: Class decorator to make it immutable (except in__init__
).@epy.frozen class A: def __init__(self): self.x = 123 a = A() a.x = 456 # AttributeError
Supports inheritance, child classes should explicitly be marked as
@epy.frozen
if they mutate additional attributes in__init__
.epy.wraps_cls
: Equivalent of@functools.wraps
, but applied to classes.epy.is_namedtuple
: ReturnsTrue
if the value is instance ofNamedTuple
.epy.issubclass
: Likeissubclass
, but do not raise error if value is nottype
.
Miscellaneous#
epy.StrEnum
: Likeenum.StrEnum
, but is case insensitive.epy.lazy_imports
: Context Manager to lazy load modules (for optional dependencies or speed-up import time).
Environment utils#
epy.is_notebook
:True
if running insideColab
orIPython
notebook