.. image:: https://travis-ci.org/TriOptima/tri.token.svg?branch=master
:target: https://travis-ci.org/TriOptima/tri.token
.. image:: https://codecov.io/github/TriOptima/tri.token/coverage.svg?branch=master
:target: https://codecov.io/github/TriOptima/tri.token?branch=master
tri.token
=========
tri.token provides enriched enum functionality. tri.token enum structures are declared using:
- TokenAttribute: overridable attribute definitions with support for dynamic values.
- Token: holds TokenAttributes objects.
- TokenContainer: holds Token objects.
In other words: a Token is an enum which has TokenInstance members. Token instances are declared within TokenContainer(s).
Basic usage
-----------
.. code:: python
from tri_token import Token, TokenAttribute, TokenContainer, PRESENT
class Taste(Token):
name = TokenAttribute()
display_name = TokenAttribute(value=lambda name, **_: name.upper() + '!!')
opinion = TokenAttribute()
class Tastes(TokenContainer):
vanilla = Taste()
pecan_nut = Taste(display_name="pecan nutz", opinion="Tasty")
# A TokenContainer is a collection of Token objects.
assert Tastes.vanilla in Tastes
# The order of Token objects in a TokenContainer is by order of declaration.
assert list(Tastes) == [Tastes.vanilla, Tastes.pecan_nut]
assert list(Tastes) != [Tastes.pecan_nut, Tastes.vanilla]
# Magic for 'name' TokenAttribute. It is set automatically from the token declaration within it's container.
assert Tastes.vanilla.name == "vanilla"
# A TokenAttribute will have a None value if not set during Token instantiation.
assert Tastes.vanilla.opinion is None
# A TokenAttribute can have a dynamic value, derived from the invocation to the callable
# set as 'value' in the TokenAttribute definition
# (see declaration of 'display_name' TokenAttribute further up in the code).
# The real value of the token attribute will be the return value of an invocation to said callable.
# The invocation will receive the values of all other token attributes passed as keyword arguments.
assert Tastes.vanilla.display_name == "VANILLA!!"
# TokenAttribute dynamic value behavior is overridden/not used if value is set explicitly during Token instantiation.
assert Tastes.pecan_nut.display_name == "pecan nutz"
# A TokenContainer can be rendered as csv, excel, rst etc
assert """\
+--------------+---------+
| display_name | opinion |
+==============+=========+
| VANILLA!! | |
+--------------+---------+
| pecan nutz | Tasty |
+--------------+---------+\
""" == Tastes.to_rst(['display_name', 'opinion'])
Optional token attributes
-------------------------
.. code:: python
# A TokenAttribute may be declared as having optional dynamic values.
# That is, we want these dynamic attributes to be evaluated sometimes, but not always.
# In the example below, we want some superheroes to have homes, but not others.
SUPERHERO_HOMES = {'superman': 'Fortress of Solitude',
'batman': 'Batcave'}
class Superhero(Token):
name = TokenAttribute()
home = TokenAttribute(optional_value=lambda name, **_: SUPERHERO_HOMES[name])
# The PRESENT special value is used during Token instantiation to decide what
# optional token attributes should be evaluated.
class Superheroes(TokenContainer):
batman = Superhero(home=PRESENT)
hawkman = Superhero()
wonder_woman = Superhero(home='Themyscira')
# Batman has a home, but poor Hawkman does not.
assert Superheroes.batman.home == 'Batcave'
assert Superheroes.hawkman.home is None
# Just as with dynamic attributes, the logic for TokenAttribute optional dynamic values is overridden
if value is set explicitly during Token instantiation.
assert Superheroes.wonder_woman.home = 'Themyscira'
# As a shortcut, PRESENT for specific optional token attributes may be assigned to
# variables, and used in declarations, for enhanced readability.
# This is useful when one has tokens with many attributes declared using dynamic values,
# but we don't want all of them to be evaluated in all tokens.
home = PRESENT('home')
class Superheroes(TokenContainer):
batman = Superhero(home)
hawkman = Superhero()
# Again, Batman has a home, but poor Hawkman does not.
assert Superheroes.batman.home == 'Batcave'
assert Superheroes.hawkman.home is None
TokenAttribute inheritance
--------------------------
.. code:: python
class FooToken(Token):
foo = TokenAttribute(value=lambda **kwargs: 'foo_value')
class BarToken(Token):
bar = TokenAttribute()
class FieToken(FooToken, BarToken):
fie = TokenAttribute()
class FooBarFieTokenContainer(TokenContainer):
t = FieToken(fie=3)
assert dict(FooBarFieTokenContainer.t) == {'foo': 'foo_value', 'bar': None, 'name': 't', 'fie': 3}
TokenAttribute container inheritance
------------------------------------
.. code:: python
class MyToken(Token):
name = TokenAttribute()
stuff = TokenAttribute()
class MyTokens(TokenContainer):
foo = MyToken(stuff='Hello')
bar = MyToken(stuff='World')
assert MyTokens.foo in MyTokens
class MoreTokens(MyTokens):
boink = MyToken(stuff='Other Stuff')
assert MyTokens.foo in MoreTokens
assert list(MoreTokens) == [MyTokens.foo, MyTokens.bar, MoreTokens.boink]
assert MoreTokens.foo is MyTokens.foo
For more tri.token examples, please have a look at the contents of tests/test_tokens.py in the installation directory.
.. _test_tokens: tests/test_tokens.py
Running tests
-------------
You need tox installed then just `make test`.
License
-------
BSD
Documentation
-------------
http://tritoken.readthedocs.org.
Raw data
{
"_id": null,
"home_page": "https://github.com/TriOptima/tri.token",
"name": "tri.token",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "tri.token",
"author": "Johan L\u00fcbcke",
"author_email": "johan.lubcke@trioptima.com",
"download_url": "https://files.pythonhosted.org/packages/bb/2f/90a8b665507ca872c0cc8d0224ba6025af5c2b408e8a032a1a68c347698b/tri.token-4.0.0.tar.gz",
"platform": null,
"description": ".. image:: https://travis-ci.org/TriOptima/tri.token.svg?branch=master\n :target: https://travis-ci.org/TriOptima/tri.token\n\n\n.. image:: https://codecov.io/github/TriOptima/tri.token/coverage.svg?branch=master\n :target: https://codecov.io/github/TriOptima/tri.token?branch=master\n\n\ntri.token\n=========\n\ntri.token provides enriched enum functionality. tri.token enum structures are declared using:\n\n- TokenAttribute: overridable attribute definitions with support for dynamic values.\n- Token: holds TokenAttributes objects.\n- TokenContainer: holds Token objects.\n\nIn other words: a Token is an enum which has TokenInstance members. Token instances are declared within TokenContainer(s).\n\n\nBasic usage\n-----------\n\n.. code:: python\n\n from tri_token import Token, TokenAttribute, TokenContainer, PRESENT\n\n\n class Taste(Token):\n name = TokenAttribute()\n display_name = TokenAttribute(value=lambda name, **_: name.upper() + '!!')\n opinion = TokenAttribute()\n\n\n class Tastes(TokenContainer):\n vanilla = Taste()\n pecan_nut = Taste(display_name=\"pecan nutz\", opinion=\"Tasty\")\n\n\n # A TokenContainer is a collection of Token objects.\n assert Tastes.vanilla in Tastes\n\n # The order of Token objects in a TokenContainer is by order of declaration.\n assert list(Tastes) == [Tastes.vanilla, Tastes.pecan_nut]\n assert list(Tastes) != [Tastes.pecan_nut, Tastes.vanilla]\n\n # Magic for 'name' TokenAttribute. It is set automatically from the token declaration within it's container.\n assert Tastes.vanilla.name == \"vanilla\"\n\n # A TokenAttribute will have a None value if not set during Token instantiation.\n assert Tastes.vanilla.opinion is None\n\n # A TokenAttribute can have a dynamic value, derived from the invocation to the callable\n # set as 'value' in the TokenAttribute definition\n # (see declaration of 'display_name' TokenAttribute further up in the code).\n\n # The real value of the token attribute will be the return value of an invocation to said callable.\n # The invocation will receive the values of all other token attributes passed as keyword arguments.\n assert Tastes.vanilla.display_name == \"VANILLA!!\"\n\n # TokenAttribute dynamic value behavior is overridden/not used if value is set explicitly during Token instantiation.\n assert Tastes.pecan_nut.display_name == \"pecan nutz\"\n\n # A TokenContainer can be rendered as csv, excel, rst etc\n assert \"\"\"\\\n +--------------+---------+\n | display_name | opinion |\n +==============+=========+\n | VANILLA!! | |\n +--------------+---------+\n | pecan nutz | Tasty |\n +--------------+---------+\\\n \"\"\" == Tastes.to_rst(['display_name', 'opinion'])\n\n\nOptional token attributes\n-------------------------\n\n.. code:: python\n\n # A TokenAttribute may be declared as having optional dynamic values.\n # That is, we want these dynamic attributes to be evaluated sometimes, but not always.\n # In the example below, we want some superheroes to have homes, but not others.\n\n SUPERHERO_HOMES = {'superman': 'Fortress of Solitude',\n 'batman': 'Batcave'}\n\n\n class Superhero(Token):\n name = TokenAttribute()\n home = TokenAttribute(optional_value=lambda name, **_: SUPERHERO_HOMES[name])\n\n\n # The PRESENT special value is used during Token instantiation to decide what\n # optional token attributes should be evaluated.\n class Superheroes(TokenContainer):\n batman = Superhero(home=PRESENT)\n hawkman = Superhero()\n wonder_woman = Superhero(home='Themyscira')\n\n # Batman has a home, but poor Hawkman does not.\n assert Superheroes.batman.home == 'Batcave'\n assert Superheroes.hawkman.home is None\n\n # Just as with dynamic attributes, the logic for TokenAttribute optional dynamic values is overridden\n if value is set explicitly during Token instantiation.\n assert Superheroes.wonder_woman.home = 'Themyscira'\n\n # As a shortcut, PRESENT for specific optional token attributes may be assigned to\n # variables, and used in declarations, for enhanced readability.\n # This is useful when one has tokens with many attributes declared using dynamic values,\n # but we don't want all of them to be evaluated in all tokens.\n home = PRESENT('home')\n\n class Superheroes(TokenContainer):\n batman = Superhero(home)\n hawkman = Superhero()\n\n # Again, Batman has a home, but poor Hawkman does not.\n assert Superheroes.batman.home == 'Batcave'\n assert Superheroes.hawkman.home is None\n\n\nTokenAttribute inheritance\n--------------------------\n\n.. code:: python\n\n class FooToken(Token):\n foo = TokenAttribute(value=lambda **kwargs: 'foo_value')\n\n class BarToken(Token):\n bar = TokenAttribute()\n\n class FieToken(FooToken, BarToken):\n fie = TokenAttribute()\n\n class FooBarFieTokenContainer(TokenContainer):\n t = FieToken(fie=3)\n\n assert dict(FooBarFieTokenContainer.t) == {'foo': 'foo_value', 'bar': None, 'name': 't', 'fie': 3}\n\n\nTokenAttribute container inheritance\n------------------------------------\n\n.. code:: python\n\n class MyToken(Token):\n\n name = TokenAttribute()\n stuff = TokenAttribute()\n\n\n class MyTokens(TokenContainer):\n\n foo = MyToken(stuff='Hello')\n bar = MyToken(stuff='World')\n\n assert MyTokens.foo in MyTokens\n\n class MoreTokens(MyTokens):\n boink = MyToken(stuff='Other Stuff')\n\n assert MyTokens.foo in MoreTokens\n\n assert list(MoreTokens) == [MyTokens.foo, MyTokens.bar, MoreTokens.boink]\n assert MoreTokens.foo is MyTokens.foo\n\n\nFor more tri.token examples, please have a look at the contents of tests/test_tokens.py in the installation directory.\n\n.. _test_tokens: tests/test_tokens.py\n\n\nRunning tests\n-------------\n\nYou need tox installed then just `make test`.\n\n\nLicense\n-------\n\nBSD\n\n\nDocumentation\n-------------\n\nhttp://tritoken.readthedocs.org.\n\n\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "tri.token provides enriched enum functionality",
"version": "4.0.0",
"split_keywords": [
"tri.token"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8562b2b7257d281cd0ebc5f03c1c02edf9ca90a4a0821f7394a352eb01ac539d",
"md5": "89fa086f2cee8ce098ed72dcf611f380",
"sha256": "56c491bed5996567130ca4e58bd70c81362e1ed17e9888883d7e64055aacf15d"
},
"downloads": -1,
"filename": "tri.token-4.0.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "89fa086f2cee8ce098ed72dcf611f380",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 8033,
"upload_time": "2023-03-10T14:59:28",
"upload_time_iso_8601": "2023-03-10T14:59:28.881121Z",
"url": "https://files.pythonhosted.org/packages/85/62/b2b7257d281cd0ebc5f03c1c02edf9ca90a4a0821f7394a352eb01ac539d/tri.token-4.0.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "bb2f90a8b665507ca872c0cc8d0224ba6025af5c2b408e8a032a1a68c347698b",
"md5": "311d8c63b823cd9f37a649bc6fb964e8",
"sha256": "17ab78a63ac2efbfd99ce63d8e04aad0de312f01ca91a3a4ca9ad80e54be8516"
},
"downloads": -1,
"filename": "tri.token-4.0.0.tar.gz",
"has_sig": false,
"md5_digest": "311d8c63b823cd9f37a649bc6fb964e8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 10584,
"upload_time": "2023-03-10T14:59:30",
"upload_time_iso_8601": "2023-03-10T14:59:30.798503Z",
"url": "https://files.pythonhosted.org/packages/bb/2f/90a8b665507ca872c0cc8d0224ba6025af5c2b408e8a032a1a68c347698b/tri.token-4.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-10 14:59:30",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "TriOptima",
"github_project": "tri.token",
"travis_ci": true,
"coveralls": false,
"github_actions": false,
"requirements": [],
"test_requirements": [],
"tox": true,
"lcname": "tri.token"
}