Coppyr (Copp-er) is a collecton of useful Python boilerplate that I find myself reusing frequently between projects.
subp.call
Convenience wrapper around
subprocess.run
that abstracts many of the common options and features (such assubprocess.PIPE
passing).>>> from coppyr import subp >>> retcode, stdout, stederr = subp.call("lsb_release -a") >>> print retcode 0 >>> print stdout ['Distributor ID:\tUbuntu', 'Description:\tUbuntu 18.04.3 LTS', 'Release:\t18.04', 'Codename:\tbionic', ''] >>> print stderr ['No LSB modules are available.', '']
Note:
STDOUT
andSTDERR
are returned asList
objects with each line as aString
. This includes empty lines which become empty strings.
singleton.Singleton
Base object that implements the Singleton pattern pythonically. Future inits of this object will return previously the first created object.
>>> from coppyr.types import Singleton >>> first = Singleton() >>> first <singleton.Singleton object at 0x7fa72df4cd30> >>> second = Singleton() >>> second <singleton.Singleton object at 0x7fa72df4cd30>
This object can be used as a base class or mixin to add Singleton behavior to custom objects.
Warning: When inheriting from Singleton it is neccessary to override the
_instance
class attribute to ensure that you don't inadvertantly store your subclass instance in the parent class variable (types.Singleton._instance
). For the same reason, you should also override_init
as well.class MySingletonClass(Singleton): _instance = None _init = False
singleton.Namespace
Simple Singleton object that stores KV pairs.
>>> from coppyr.singleton import Namespace >>> ns = Namespace() >>> ns.foo = "bar" >>> ns.foo 'bar' >>> ns2 = Namespace() >>> ns2.foo 'bar'
Returns
None
if the key is not in the namespace.>>> ns.baz >>>
Warning: Just like
Singleton
, child objects should override the class_instance
and_init
attributes.__getattr__(self, attr)
When an attribute does not exist, a
Namespace
will returnNone
instead of raising anAttributeError
.
Context
This is intended as an interpreter local object that can store common state between executing threads/coroutines. It's a convenient tool to provide access to shared utilities such as logging, environment information, and other shared utilities for an application.
>>> from coppyr import Context >>> context = Context() >>> context.action_id '15_100000' >>> context.inc_action_id() >>> context.action_id '15_100001'
lazyproperty
This is a decorator that will turn a class method into a property that is evaluated once. This is a useful performance optimization for class elements that require computation but do not change overtime.
>>> from coppyr import lazyproperty >>> class Foo: ... def __init__(self): ... self.a = 5 ... self.b = 6 ... ... @lazyproperty ... def c(self): ... return self.a + self.b ... >>> x = Foo() >>> x.c 11 >>> x.a = 6 >>> x.c 11 # c remains 11
CoppyrError
Simple boilerplate for readable, consistent, custom error messages. Adds a dict representation that can be used for easy(ish) conversion to JSON for web use cases.
>>> from coppyr import CoppyrError >>> class MyError(CoppyrError): ... description = "Doom 2: Hell on earth." ... >>> err = MyError() >>> raise err Traceback (most recent call last): File "<stdin>", line 1, in <module> __main__.MyError: Doom 2: Hell on earth. >>> err MyError(message=Doom 2: Hell on earth., payload={}) >>> err.to_dict() {'error': 'MyError', 'message': 'Doom 2: Hell on earth.', 'payload': {}}