pytoolbox.types module

pytoolbox.types.get_arguments_names(function)[source]

Return a list with arguments names.

>>> from pytoolbox import types
>>>
>>> get_arguments_names(get_arguments_names)
['function']
>>>
>>> def my_func(directory, a=1, *args, b, c=None, **kwargs):
...     pass
...
>>> get_arguments_names(my_func)
['directory', 'a', 'args', 'b', 'c', 'kwargs']
>>>
>>> get_arguments_names(types.get_subclasses)
['obj', 'nested']
>>> get_arguments_names(types.merge_bases_attribute)
['cls', 'attr_name', 'init', 'default', 'merge_func']
pytoolbox.types.get_properties(obj)[source]
pytoolbox.types.get_slots(obj)[source]

Return a set with the __slots__ of the obj including all parent classes __slots__.

pytoolbox.types.get_subclasses(obj, nested=True)[source]

Walk the inheritance tree of obj. Yield tuples with (class, subclasses).

Example usage

>>> class Root(object):
...     pass
...
>>> class NodeA(Root):
...     pass
...
>>> class NodeB(Root):
...     pass
...
>>> class NodeC(NodeA):
...     pass
...
>>> class NodeD(NodeA):
...     pass
...
>>> class NodeE(NodeD):
...     pass
...
>>> [(c.__name__, bool(s)) for c, s in get_subclasses(Root)]
[('NodeA', True), ('NodeC', False), ('NodeD', True), ('NodeE', False), ('NodeB', False)]
>>> [(c.__name__, bool(s)) for c, s in get_subclasses(Root, nested=False)]
[('NodeA', True), ('NodeB', False)]
>>> [(c.__name__, bool(s)) for c, s in get_subclasses(NodeB)]
[]
>>> [(c.__name__, bool(s)) for c, s in get_subclasses(NodeD)]
[('NodeE', False)]
pytoolbox.types.isiterable(obj, blacklist=(<class 'bytes'>, <class 'str'>))[source]

Return True if the object is an iterable, but False for any class in blacklist.

Example usage

>>> from pytoolbox.unittest import asserts
>>> for obj in b'binary', 'unicode', 42:
...     asserts.false(isiterable(obj), obj)
>>> for obj in [], (), set(), iter({}.items()):
...     asserts.true(isiterable(obj), obj)
>>> isiterable({}, dict)
False
pytoolbox.types.merge_annotations(cls: type)[source]

Merge annotations defined in all bases classes (using __mro__) into given cls.

Can be used as a decorator.

Example usage

>>> class Point2D(object):
...     x: int
...     y: int
...
>>> class Point3D(Point2D):
...     z: int
...
>>> class Point4D(Point3D, Point2D):
...     w: int
...
>>> @merge_annotations
... class Point4X(Point4D):
...     x: float
...     other: str
...
>>> assert Point2D.__annotations__ == {'x': int, 'y': int}
>>> assert Point3D.__annotations__ == {'z': int}
>>> assert Point4D.__annotations__ == {'w': int}
>>> assert Point4X.__annotations__ == {'x': float, 'y': int, 'z': int, 'w': int, 'other': str}
pytoolbox.types.merge_bases_attribute(cls, attr_name, init, default, merge_func=<function <lambda>>)[source]

Merge all values of attribute defined in all bases classes (using __mro__). Return resulting value. Use default every time a class does not have given attribute.

Be careful, merge_func must be a pure function.

class pytoolbox.types.DummyObject(**kwargs)[source]

Bases: object

Easy way to generate a dynamic object with the attributes defined at instantiation.

Example usage

>>> obj = DummyObject(foo=42, bar=None)
>>> obj.foo
42
>>> obj.bar is None
True
__init__(**kwargs)[source]

Initialize self. See help(type(self)) for accurate signature.

class pytoolbox.types.EchoObject(name, **attrs)[source]

Bases: object

Object that return any missing attribute as an instance of EchoObject with the name set to the Python expression used to access it. Also implements __getitem__. Some examples are worth hundred words…

Example usage

>>> from pytoolbox.unittest import asserts
>>> something = EchoObject('something', language='Python')
>>> something._name
'something'
>>> something.language
'Python'
>>> hasattr(something, 'everything')
True
>>> type(something.user.email)
<class 'pytoolbox.types.EchoObject'>
>>> str(something.user.first_name)
'something.user.first_name'
>>> str(something[0][None]['bar'])
"something[0][None]['bar']"
>>> str(something[0].node['foo'].x)
"something[0].node['foo'].x"
>>> str(something)
'something'

You can also define the class for the generated attributes:

>>> something.attr_class = list
>>> type(something.cool)
<class 'list'>

This class handles sub-classing appropriately:

>>> class MyEchoObject(EchoObject):
...     pass
>>>
>>> type(MyEchoObject('name').x.y.z)
<class 'pytoolbox.types.MyEchoObject'>
attr_class = None
__init__(name, **attrs)[source]

Initialize self. See help(type(self)) for accurate signature.

class pytoolbox.types.EchoDict(name, **items)[source]

Bases: dict

Dictionary that return any missing item as an instance of EchoObject with the name set to the Python expression used to access it. Some examples are worth hundred words…

Example usage

>>> context = EchoDict('context', language='Python')
>>> context._name
'context'
>>> context['language']
'Python'
>>> 'anything' in context
True
>>> str(context['user'].first_name)
"context['user'].first_name"
>>> str(context[0][None]['bar'])
"context[0][None]['bar']"
>>> str(context[0].node['foo'].x)
"context[0].node['foo'].x"

You can also define the class for the generated items:

>>> context.item_class = set
>>> type(context['jet'])
<class 'set'>
item_class

alias of EchoObject

__init__(name, **items)[source]

Initialize self. See help(type(self)) for accurate signature.

class pytoolbox.types.MissingType[source]

Bases: object