Provides a number os useful data types for day-to-day Python programming.
Project description
nr.types
The nr.types
package provides a number os useful data types for day-to-day
Python programming. It is compatible with Python 2.7 and modern versions of
Python 3.
Installation
pip install nr.types
Run Tests
pip install -e .[test]
pytest --cov=./src/nr
API
nr.types.NotSet
The NotSet
singleton is useful in cases where None
is an acceptable value
for a parameter so there needs to be an additional state that defines the
parameter as "not set".
nr.types.abc
An alias for collections.abc
or collections
(the six
module does not
provide a move for these modules).
nr.types.functools
Tools to help with Python function internals such as closures, code and function objects.
Example:
import nr.types.functools as ft
def test(value):
def x():
return value
return x
x = test(42)
assert x() == 42
y = ft.copy_function(x, closure={'value': 99})
assert y() == 99
nr.types.generic
Allows you to implement generic types, ie. classes with parameters.
Example:
from nr.types import generic
class HashDict(generic.Generic['key_hash']):
def __init__(self):
generic.assert_initialized(self)
self.data = {}
def __getitem__(self, key):
return self.data[self.key_hash(key)]
def __setitem__(self, key, value):
self.data[self.key_hash(key)] = value
UnsafeHashDict = HashDict[hash]
nr.types.interface
Similar to zope.interface
, but Python 3 compatible and less magical.
Example:
from nr.types.interface import Interface, Implementation, implements, attr
class IFoo(Interface):
""" The foo interface. """
x = attr("""Some attribute.""")
def bar(self, q, r=None):
""" The bar function. """
assert set(IFoo) == set(['x', 'bar'])
assert not hasattr(IFoo, 'x')
assert not hasattr(IFoo, 'bar')
assert IFoo['x'].name == 'x'
assert IFoo['bar'].name == 'bar'
@implements(IFoo)
class Foo(object):
def __init__(self, x=None):
self.x = x
def bar(self, q, r=None):
return q, r, self.x
assert issubclass(Foo, Implementation)
assert IFoo.implemented_by(Foo)
assert IFoo.provided_by(Foo())
assert list(IFoo.implementations()) == [Foo]
assert Foo(42).x == 42
nr.types.local
Vendors the LocalProxy
class fro,m pallets/werkzeug@0.15.2
.
Example (LocalProxy):
from nr.types.local import LocalProxy
count = 0
def test():
global count
count += 1
return count
proxy = LocalProxy(test)
assert proxy == 1
assert count == 1
assert proxy == 2
assert count == 2
assert proxy == 3
assert count == 3
assert proxy + 10 == 14
nr.types.maps
Provides the following mapping (and mapping-related) implementations:
OrderedDict
ObjectAsDict
ObjectFromDict
ChainDict
(usemaps.chain()
)HashDict[hash_func]
ValueIterableDict
nr.types.meta
Provides useful metaclasses, such as InlineMetaclass
.
Example:
from nr.types.meta import InlineMetaclassBase
class MyClass(InlineMetaclassBase):
def __metainit__(self, name, bases, attr):
print('MyClass constructed!')
self.value = 'foo'
assert MyClass.value == 'foo'
nr.types.moduletools
Provides some tools for working with modules. Currently only provides the
make_inheritable()
function which can be used from within your module to
make the module object itself usable as a parent class.
# myclass.py
class MyClass(object): pass
make_inheritable(__name__)
# test.py
import myclass
class MySubclass(myclass): pass
assert issubclass(MySubclass, myclass.MyClass)
nr.types.record
Similar to namedtuple
but mutable, with support for keyword arguments,
type declarations and default values. Supports multiple forms of declaring
a record, eg. via Python 3.6+ class-level annotations, specifying a class-level
__fields__
member or declaring attributes by creating record.Field()
objects.
Example:
import random
from nr.types import record
class Person(record.Record):
name: str
mail: str = None
age: int = lambda: random.randint(10, 50)
p = Person('John Smith')
assert p.name == 'John Smith'
assert p.mail is None
assert 10 <= p.age <= 50
Alternatives:
import random
from nr.types import record
class Person(record.Record):
name = record.Field(str)
mail = record.Field(str, None)
age = record.Field(str, lambda: random.randint(10, 50))
class Person(record.Record):
__fields__ = [
('name', str),
('mail', str, None),
('age', str, lambda: random.randint(10, 50)),
]
Person = record.create_record('Person', [
('name', str),
record.Field.with_name('mail', str, None),
('age', str, lambda: random.randint(10, 50))
])
Person = record.create_record('Person', {
'name': record.Field(str),
'mail': record.Field(str, None),
'age': record.Field(str, lambda: random.randint(10, 50))
})
assert list(Person.__fields__.keys()) == ['name', 'mail', 'age']
nr.types.sets
Currently only provides an OrderedSet
implementation.
nr.types.stream
Example:
from nr.types import stream
stream(range(10)).map(lambda x: x*2)
stream.map(range(10), lambda x: x*2)
nr.types.sumtype
Example:
from nr.types import record, sumtype
class Filter(sumtype):
Date = record.create_record('Date', 'min,max')
Keyword = sumtype.constructor('text')
class Duration(record.Record):
value = record.Field(int, lambda: 3600)
f = Filter.Keyword('building')
assert isinstance(f, Filter)
assert f.is_keyword()
assert f.text == 'building'
f = Filter.Date(10, 42)
assert isinstance(f, Filter)
assert f.is_date()
assert (f.min, f.max) == (10, 42)
f = Filter.Duration()
assert isinstance(f, Filter)
assert f.is_duration()
assert f.value == 3600
Acknowledgements
- This library vendors a modified version of the
werkzeug.local
module in version 0.15.2 as thenr.types.local
module. Werkzeug is licensed under the BSD-3-Clause license and the copyright of thenr.types.local
module lies with Pallets.
Copyright © Niklas Rosenstein 2019
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.