Skip to content

Latest commit

 

History

History
177 lines (133 loc) · 4.17 KB

README.rst

File metadata and controls

177 lines (133 loc) · 4.17 KB

Coppyr

Coppyr (Copp-er) is a collecton of useful Python boilerplate that I find myself reusing frequently between projects.

subp

subp.call

Convenience wrapper around subprocess.run that abstracts many of the common options and features (such as subprocess.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 and STDERR are returned as List objects with each line as a String. This includes empty lines which become empty strings.

singleton

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 return None instead of raising an AttributeError.

Context

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

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

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': {}}