extypes
This project provides a few enhanced types for Python:
- A "constrained set" (ordered or not)
- That's all for now.
It also provides extensions for Django (1.7 - 1.10).
It has been fully tested with all versions of Python from 2.7 to 3.4; and is distributed under the BSD license.
Links
- Package on PyPI: http://pypi.python.org/pypi/extypes
- Repository and issues on GitHub: http://github.com/rbarrois/extypes
- Doc on https://extypes.readthedocs.io/ (not available yet)
Getting started
Intall the package from PyPI, using pip:
$ pip install extypes
Or from GitHub:
$ git clone git://github.com/rbarrois/extypes
$ cd extypes
$ python setup.py install
To check that everything went fine, fire a Python shell and import extypes
:
import extypes
Introduction
extypes
provides a new type, ConstrainedSet
.
This is a set()
-like object, but values can only be taken from a
specific set of options.
A ConstrainedSet
is declared in a manner very similar to collections.namedtuple
:
import extypes
Foods = extypes.ConstrainedSet(['eggs', 'spam', 'bacon'])
This will declare a new class, Foods
, whose instances are ConstrainedSet
that only accept
options among 'eggs'
, 'spam'
and 'bacon'
.
Those objects can be used as simple set()
objects:
>>> import extypes
>>> Foods = extypes.ConstrainedSet(['eggs', 'spam', 'bacon'])
>>> meat = Foods(['spam', 'bacon'])
>>> fresh = Foods(['bacon', 'eggs'])
>>> 'eggs' in meat
False
>>> 'eggs' in fresh
True
>>> meat & fresh
Foods(['bacon'])
As a set()
object, they are mutable:
>>> import extypes
>>> Foods = extypes.ConstrainedSet(['eggs', 'spam', 'bacon'])
>>> meat = Foods(['spam', 'bacon'])
>>> meat.remove('spam')
>>> meat
Foods(['bacon'])
And iterable:
>>> import extypes
>>> Foods = extypes.ConstrainedSet(['eggs', 'spam', 'bacon'])
>>> meat = Foods(['bacon', 'spam'])
>>> list(meat)
['spam', 'bacon']
But only valid options are accepted:
>>> Foods = extypes.ConstrainedSet(['eggs', 'spam', 'bacon'])
>>> greens = Foods(['spinach']
Traceback (most recent call last):
...
ValueError: Invalid keys ['spinach'], please use a value in ['spam', 'bacon', 'eggs'].
Extensions: Django
extypes
also provides custom fields for Django - compatible with Django 1.7 and upwards.
from django.db import models
import extypes
import extypes.django
Foods = extypes.ConstrainedSet(['eggs', 'spam', 'bacon'])
class Fridge(models.Model):
contents = extypes.django.SetField(choices=Foods)
This field will simply behave as a simple ConstrainedSet
.
>>> fridge = Fridge(contents=['bacon'])
>>> fridge.contents.add('eggs')
>>> fridge.save()
It is displayed in forms as a multiple choice field.
In the database, it is saved as a |
-separated list of enabled values
(in the above example, the field is stored as |eggs|bacon|
).
Note
extypes.django.SetField
can also receive a choice-like list:
class Fridge(models.Model):
contents = extypes.django.SetField(choices=[('eggs', "Eggs"), ('spam', "Spam"), ('bacon', "Yummy bacon")])
In that case, the field definition is available at Fridge.contents.set_definition
:
>>> f = Fridge(contents=Fridge.contents.set_definition(['eggs', 'spam']))
>>> f.get_contents_display()
"Eggs, Spam"