Collection of lower-level utilities that enhance code readability and validation.
Project description
Motivation
While developing Python software for Visual Effects pipelines, I found myself writing the same general lower-level utilities over and over again. So I decided to package those up into Basicco.
Overview
Basicco provides a collection of lower-level Utilities that enhance code readability and validation.
Utilities
abstract_class
Decorator that prevents an abstract class from being instantiated.
This works even if the class doesn’t have any abstract methods or properties. Concrete subclasses (non-decorated) are able to be instantiated without any issues.
>>> from basicco.abstract_class import abstract_class
>>> @abstract_class
... class Abstract:
... pass
...
>>> class Concrete(Abstract):
... pass
...
>>> concrete = Concrete()
>>> abstract = Abstract()
Traceback (most recent call last):
NotImplementedError: can't instantiate abstract class 'Abstract'
caller_module
Retrieve the caller’s module name.
>>> from basicco.caller_module import caller_module
>>> def do_something():
... return f"I was called by {caller_module()}"
...
>>> do_something()
'I was called by __main__'
custom_repr
Custom representation functions.
>>> from basicco.custom_repr import mapping_repr
>>> dct = {"a": 1, "b": 2}
>>> mapping_repr(dct, prefix="<", suffix=">", template="{key}={value}", sorting=True)
"<'a'=1, 'b'=2>"
>>> from basicco.custom_repr import iterable_repr
>>> tup = ("a", "b", "c", 1, 2, 3)
>>> iterable_repr(tup, prefix="<", suffix=">", value_repr=str)
'<a, b, c, 1, 2, 3>'
explicit_hash
Metaclass that forces __hash__ to be declared when __eq__ is declared.
>>> from basicco.explicit_hash import ExplicitHashMeta
>>> class Asset(metaclass=ExplicitHashMeta):
... def __eq__(self, other):
... pass
...
Traceback (most recent call last):
TypeError: declared '__eq__' in 'Asset' but didn't declare '__hash__'
import_path
Generate importable dot paths and import from them.
>>> import itertools
>>> from basicco.import_path import get_path, import_path
>>> get_path(itertools.chain)
'itertools.chain'
>>> import_path("itertools.chain")
<class 'itertools.chain'>
>>> from basicco.import_path import extract_generic_paths
>>> extract_generic_paths("Tuple[int, str]")
('Tuple', ('int', 'str'))
namespace
Wraps a dictionary/mapping and provides attribute-style access to it.
>>> from basicco.namespace import Namespace
>>> ns = Namespace({"bar": "foo"})
>>> ns.bar
'foo'
>>> from basicco.namespace import MutableNamespace
>>> ns = MutableNamespace({"bar": "foo"})
>>> ns.foo = "bar"
>>> ns.foo
'bar'
>>> ns.bar
'foo'
Also provides a NamespacedMeta metaclass for adding a __namespace__ private property that is unique to each class.
>>> from basicco.namespace import NamespacedMeta
>>> class Asset(metaclass=NamespacedMeta):
... pass
...
>>> Asset.__namespace__.foo = "bar"
privatize
Functions to privatize/deprivatize member names.
>>> from basicco.privatize import privatize, deprivatize
>>> privatize("__member", "Foo")
'_Foo__member'
>>> deprivatize("_Foo__member")
('__member', 'Foo')
recursive_repr
Decorator that prevents infinite recursion for __repr__ methods.
>>> from basicco.recursive_repr import recursive_repr
>>> class MyClass:
...
... @recursive_repr
... def __repr__(self):
... return f"MyClass<{self!r}>"
...
>>> my_obj = MyClass()
>>> repr(my_obj)
'MyClass<...>'
runtime_final
Runtime-checked version of the typing.final decorator.
Can be used on methods, properties, classmethods, staticmethods, and classes that have FinalizedMeta as a metaclass. It is also recognized by static type checkers and prevents subclassing and/or member overriding during runtime:
>>> from basicco.runtime_final import FinalizedMeta, final
>>> @final
... class Asset(metaclass=FinalizedMeta):
... pass
...
>>> class SubAsset(Asset):
... pass
...
Traceback (most recent call last):
TypeError: can't subclass final class 'Asset'
>>> from basicco.runtime_final import FinalizedMeta, final
>>> class Asset(metaclass=FinalizedMeta):
... @final
... def method(self):
... pass
...
>>> class SubAsset(Asset):
... def method(self):
... pass
Traceback (most recent call last):
TypeError: can't override final member 'method'
>>> from basicco.runtime_final import FinalizedMeta, final
>>> class Asset(metaclass=FinalizedMeta):
... @property
... @final
... def prop(self):
... pass
...
>>> class SubAsset(Asset):
... @property
... def prop(self):
... pass
Traceback (most recent call last):
TypeError: can't override final member 'prop'
unique_iterator
Iterator that yields unique values.
>>> from basicco.unique_iterator import unique_iterator
>>> list(unique_iterator([1, 2, 3, 3, 4, 4, 5]))
[1, 2, 3, 4, 5]
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for basicco-3.1.0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 19a804748dc4be2b9d0c0c6ca84c6634df5665e720c1ffcec22e392b1dfd6663 |
|
MD5 | 6393378d63703963e1de6bc07b9420c1 |
|
BLAKE2b-256 | 146f447f1a8e60ff102aceea1ceb6290201bced5769ff7970da0e65cbe8a681b |