Name | truconsts JSON |
Version |
0.0.9
JSON |
| download |
home_page | |
Summary | Simple, easy to use with intuitive APIs, for managing constants in your Python applications. |
upload_time | 2023-06-27 18:28:28 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.8 |
license | |
keywords |
truconsts
truly constants
constants
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# truconsts
[![Actions](https://img.shields.io/github/actions/workflow/status/jymchng/truconsts/test.yml?branch=main&logo=github&style=flat-square&maxAge=300)](https://github.com/jymchng/truconsts/actions)
[![Coverage](https://img.shields.io/codecov/c/gh/jymchng/truconsts/branch/main.svg?style=flat-square&maxAge=3600)](https://codecov.io/gh/jymchng/truconsts/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square&maxAge=2678400)](https://choosealicense.com/licenses/mit/)
[![PyPI](https://img.shields.io/pypi/v/truconsts.svg?style=flat-square&maxAge=3600)](https://pypi.org/project/truconsts)
[![Wheel](https://img.shields.io/pypi/wheel/truconsts.svg?style=flat-square&maxAge=3600)](https://pypi.org/project/truconsts/#files)
[![Python Versions](https://img.shields.io/pypi/pyversions/truconsts.svg?style=flat-square&maxAge=600)](https://pypi.org/project/truconsts/#files)
[![Python Implementations](https://img.shields.io/pypi/implementation/truconsts.svg?style=flat-square&maxAge=600&label=impl)](https://pypi.org/project/truconsts/#files)
[![Source](https://img.shields.io/badge/source-GitHub-303030.svg?maxAge=2678400&style=flat-square)](https://github.com/jymchng/truconsts/)
[![Mirror](https://img.shields.io/badge/mirror-EMBL-009f4d?style=flat-square&maxAge=2678400)](https://git.embl.de/larralde/truconsts/)
[![Issues](https://img.shields.io/github/issues/jymchng/truconsts.svg?style=flat-square&maxAge=600)](https://github.com/jymchng/truconsts/issues)
[![Docs](https://img.shields.io/readthedocs/truconsts/latest?style=flat-square&maxAge=600)](https://truconsts.readthedocs.io)
[![Changelog](https://img.shields.io/badge/keep%20a-changelog-8A0707.svg?maxAge=2678400&style=flat-square)](https://github.com/jymchng/truconsts/blob/master/CHANGELOG.md)
[![Downloads](https://img.shields.io/badge/dynamic/json?style=flat-square&color=303f9f&maxAge=86400&label=downloads&query=%24.total_downloads&url=https%3A%2F%2Fapi.pepy.tech%2Fapi%2Fprojects%2Ftruconsts)](https://pepy.tech/project/truconsts)
<div align="center" height=1000, width=200>
<img src="assets/truconstscirlogo.png" width="15%" height="30%"><br>
<img src="assets/truconsts_logo.png" width="60%" height="30%">
</div>
## Version: 0.0.9
`truconsts` is a constants management package for Python applications.
It provides a base class named `BaseConstants` which the user can subclass to achieve certain behaviours when accessing the class variables defined in the subclass. It also provides three classes that are meant for type-hinting, `Immutable`, `Yield` and `Cache`.
These three type-hinting classes do the following to the class variable:
`Immutable`: The class variable annotated with `Immutable` is immutable. Its value cannot be changed, any assignment to the class variable will raise an `AttributeError`.
`Yield`: The class variable annotated with `Yield` will always return/yield a value whenever the class variable is accessed. You can assign a function,
`Cache`: The class variable annotated with `Cache` will always cache the yielded/returned value from the first call to the function/generator/asynchronous generator (alias: async-gen). Subsequent accesses to the class variable will return the cached value.
# Installation
You can use pip to install this package
```
pip install -U truconsts
```
# Usage
## If you want immutable constants
```python
from truconsts.constants import BaseConstants
from truconsts.annotations import Immutable
class MyConstants(BaseConstants):
# annotate with `Immutable`
MyImmutable: Immutable = "Cannot Be Changed"
try:
MyConstants.MyImmutable = "Let's change"
except AttributeError as err:
print(err)
# prints `MyConstants.MyImmutable` cannot be mutated
```
## If you want cached constants
'cached' constants refer to constants which are first 'gotten' through a function call and subsequent use of these constants need not be accessed through that function call.
```python
import time
import datetime
def get_from_network():
time.sleep(2)
return 'Going to cache'
class MyConstants(BaseConstants):
# annotate with `Cache`
MyCache: Cache = get_from_network
start = datetime.datetime.now()
MyConstants.MyCache
end = datetime.datetime.now()
print(f"Time taken to access the variable: {end-start}")
# Time taken to access the variable: 0:00:02.000991
start = datetime.datetime.now()
MyConstants.MyCache
end = datetime.datetime.now()
print(f"Time taken to access the variable after caching: {end-start}")
# Time taken to access the variable after caching: 0:00:00.000999
```
## If you want 'yielding' constants
'yielding' constants refer to constants (which are not 'really' constants in the strictest sense, but it's Python yeah...) to always generate a new value whenever you access them.
```python
import random
def gen():
while True: # this while loop is import
# if you always want a random number
# to be generate from this generator
num = random.randint(0, 100)
yield num
class MyConstants(BaseConstants):
# annotate with `Yield`
RANDOM_INT: Yield = gen
print(MyConstants.RANDOM_INT) # 23
print(MyConstants.RANDOM_INT) # 88
```
## If you want 'yielding' constants from an asynchronous generator
Same as the above, but now with asynchronous generator. It makes your generators run as if they are synchronous.
```python
async def gen():
i = 1
while i:
yield i
i += 1
async def getter():
async_asend_gen = gen()
while True:
num = await async_asend_gen.asend(None)
yield num
class MyConstants(BaseConstants):
COUNT_UP: Yield = getter()
print(MyConstants.COUNT_UP) # 1
print(MyConstants.COUNT_UP) # 2
print(MyConstants.COUNT_UP) # 3
print(MyConstants.COUNT_UP) # 4
```
## If you want a mix of constants
```python
# Simple API, just subclass `BaseConstants`
class Constants(BaseConstants):
# `NUM` is an immutable `int`, i.e. Constants.NUM will always be 123
NUM: Immutable[int] = 123
# No `Immutable` annotation implies Constants.STR is mutable
STR: str = "Hello"
# Constants.IMMU_FUNC will call `get_constant` function; the returned value is cached
# and it is immutable
IMMU_FUNC: Cache[Immutable] = get_constant
# Order/Subscripting of annotation does not matter
MUT_FUNC: Immutable[Cache] = get_constant
# Only `Cache` annotation without `Immutable` means it is mutable even after
# the returned value is cached after being called for the first time
JUST_CACHE: Cache[str] = get_constant
# No annotation means it is neither `Cache` nor `Immutable`
NO_ANNO = "NO_ANNO"
```
## Finally, if you want to manage your own asynchronous generator but want the 'reference' to it to be immutable
```python
async def gen():
i = 1
while i:
stop = yield i
if stop == True:
print("Someone asked me to stop!")
return
i += 1
async def getter():
async_asend_gen = gen()
num = None
while True:
i = await async_asend_gen.asend(num)
num = yield i
class MyConstants(BaseConstants):
INT: Immutable = getter()
print(await MyConstants.INT.asend(None)) # 1
print(await MyConstants.INT.asend(None)) # 2
print(await MyConstants.INT.asend(None)) # 3
print(await MyConstants.INT.asend(None)) # 4
print(await MyConstants.INT.asend(True)) # Someone asked me to stop!;
# Raises `RuntimeError: async generator raised StopAsyncIteration``
```
There are more examples in the `examples` folder on Github.
# Roadmap
|Description|Progress|Code Sample|
|:--|:--:|:--:|
|Subclassing e.g. `Immutables` make all subclass' class variables immutable|![](https://img.shields.io/badge/Status-UNCOMPLETED-red)|[1]|
|Able to define inner class in outer class definition and declare annotation through parameters passed into class call|![](https://img.shields.io/badge/Status-UNCOMPLETED-red)|[1]|
## Samples
### [1]
```python
# Future APIs
class MyConstants(BaseConstants):
class FilePaths(Immutables, this_class_as=(Immutable,)):
# All `TRAINING`, `TESTING` class variables will be `Immutable`.
# The class variable `FilePaths` of `MyConstants`
# will be immutable as well.
TRAINING = "."
TESTING = ".."
VALIDATION = "..."
class Yielders(Yields):
# Same as above just that all class variables will be
# `Yield` annotated but `Yielders` will be mutable
FIRST = gen
```
# Contributing
Contributions are welcome!
Raw data
{
"_id": null,
"home_page": "",
"name": "truconsts",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "truconsts,truly constants,constants",
"author": "",
"author_email": "Jim Chng <jimchng@outlook.com>",
"download_url": "https://files.pythonhosted.org/packages/15/8e/793a0bff4b805f26c327a799b3f647ffb41467c8c24323ae78b513a5b809/truconsts-0.0.9.tar.gz",
"platform": null,
"description": "# truconsts\r\n\r\n[![Actions](https://img.shields.io/github/actions/workflow/status/jymchng/truconsts/test.yml?branch=main&logo=github&style=flat-square&maxAge=300)](https://github.com/jymchng/truconsts/actions)\r\n[![Coverage](https://img.shields.io/codecov/c/gh/jymchng/truconsts/branch/main.svg?style=flat-square&maxAge=3600)](https://codecov.io/gh/jymchng/truconsts/)\r\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square&maxAge=2678400)](https://choosealicense.com/licenses/mit/)\r\n[![PyPI](https://img.shields.io/pypi/v/truconsts.svg?style=flat-square&maxAge=3600)](https://pypi.org/project/truconsts)\r\n[![Wheel](https://img.shields.io/pypi/wheel/truconsts.svg?style=flat-square&maxAge=3600)](https://pypi.org/project/truconsts/#files)\r\n[![Python Versions](https://img.shields.io/pypi/pyversions/truconsts.svg?style=flat-square&maxAge=600)](https://pypi.org/project/truconsts/#files)\r\n[![Python Implementations](https://img.shields.io/pypi/implementation/truconsts.svg?style=flat-square&maxAge=600&label=impl)](https://pypi.org/project/truconsts/#files)\r\n[![Source](https://img.shields.io/badge/source-GitHub-303030.svg?maxAge=2678400&style=flat-square)](https://github.com/jymchng/truconsts/)\r\n[![Mirror](https://img.shields.io/badge/mirror-EMBL-009f4d?style=flat-square&maxAge=2678400)](https://git.embl.de/larralde/truconsts/)\r\n[![Issues](https://img.shields.io/github/issues/jymchng/truconsts.svg?style=flat-square&maxAge=600)](https://github.com/jymchng/truconsts/issues)\r\n[![Docs](https://img.shields.io/readthedocs/truconsts/latest?style=flat-square&maxAge=600)](https://truconsts.readthedocs.io)\r\n[![Changelog](https://img.shields.io/badge/keep%20a-changelog-8A0707.svg?maxAge=2678400&style=flat-square)](https://github.com/jymchng/truconsts/blob/master/CHANGELOG.md)\r\n[![Downloads](https://img.shields.io/badge/dynamic/json?style=flat-square&color=303f9f&maxAge=86400&label=downloads&query=%24.total_downloads&url=https%3A%2F%2Fapi.pepy.tech%2Fapi%2Fprojects%2Ftruconsts)](https://pepy.tech/project/truconsts)\r\n\r\n\r\n<div align=\"center\" height=1000, width=200>\r\n<img src=\"assets/truconstscirlogo.png\" width=\"15%\" height=\"30%\"><br>\r\n<img src=\"assets/truconsts_logo.png\" width=\"60%\" height=\"30%\">\r\n</div>\r\n\r\n## Version: 0.0.9\r\n\r\n`truconsts` is a constants management package for Python applications.\r\n\r\nIt provides a base class named `BaseConstants` which the user can subclass to achieve certain behaviours when accessing the class variables defined in the subclass. It also provides three classes that are meant for type-hinting, `Immutable`, `Yield` and `Cache`.\r\n\r\nThese three type-hinting classes do the following to the class variable:\r\n\r\n`Immutable`: The class variable annotated with `Immutable` is immutable. Its value cannot be changed, any assignment to the class variable will raise an `AttributeError`.\r\n\r\n`Yield`: The class variable annotated with `Yield` will always return/yield a value whenever the class variable is accessed. You can assign a function, \r\n\r\n`Cache`: The class variable annotated with `Cache` will always cache the yielded/returned value from the first call to the function/generator/asynchronous generator (alias: async-gen). Subsequent accesses to the class variable will return the cached value.\r\n\r\n# Installation\r\n\r\nYou can use pip to install this package\r\n```\r\npip install -U truconsts\r\n```\r\n\r\n# Usage\r\n\r\n## If you want immutable constants\r\n```python\r\nfrom truconsts.constants import BaseConstants\r\nfrom truconsts.annotations import Immutable\r\n\r\nclass MyConstants(BaseConstants):\r\n # annotate with `Immutable`\r\n MyImmutable: Immutable = \"Cannot Be Changed\"\r\n \r\ntry:\r\n MyConstants.MyImmutable = \"Let's change\"\r\nexcept AttributeError as err:\r\n print(err)\r\n# prints `MyConstants.MyImmutable` cannot be mutated\r\n```\r\n\r\n## If you want cached constants\r\n'cached' constants refer to constants which are first 'gotten' through a function call and subsequent use of these constants need not be accessed through that function call.\r\n```python\r\nimport time\r\nimport datetime\r\n\r\ndef get_from_network():\r\n time.sleep(2)\r\n return 'Going to cache'\r\n\r\nclass MyConstants(BaseConstants):\r\n # annotate with `Cache`\r\n MyCache: Cache = get_from_network\r\n \r\nstart = datetime.datetime.now()\r\nMyConstants.MyCache\r\nend = datetime.datetime.now()\r\nprint(f\"Time taken to access the variable: {end-start}\")\r\n# Time taken to access the variable: 0:00:02.000991\r\n\r\nstart = datetime.datetime.now()\r\nMyConstants.MyCache\r\nend = datetime.datetime.now()\r\nprint(f\"Time taken to access the variable after caching: {end-start}\")\r\n# Time taken to access the variable after caching: 0:00:00.000999\r\n```\r\n\r\n## If you want 'yielding' constants\r\n'yielding' constants refer to constants (which are not 'really' constants in the strictest sense, but it's Python yeah...) to always generate a new value whenever you access them.\r\n```python\r\nimport random\r\n\r\ndef gen():\r\n while True: # this while loop is import \r\n # if you always want a random number\r\n # to be generate from this generator\r\n num = random.randint(0, 100)\r\n yield num\r\n \r\nclass MyConstants(BaseConstants):\r\n # annotate with `Yield`\r\n RANDOM_INT: Yield = gen \r\n \r\nprint(MyConstants.RANDOM_INT) # 23\r\nprint(MyConstants.RANDOM_INT) # 88\r\n```\r\n\r\n## If you want 'yielding' constants from an asynchronous generator\r\nSame as the above, but now with asynchronous generator. It makes your generators run as if they are synchronous.\r\n```python\r\nasync def gen():\r\n i = 1\r\n while i:\r\n yield i\r\n i += 1\r\n\r\nasync def getter():\r\n async_asend_gen = gen()\r\n while True:\r\n num = await async_asend_gen.asend(None)\r\n yield num\r\n \r\nclass MyConstants(BaseConstants):\r\n COUNT_UP: Yield = getter()\r\n \r\nprint(MyConstants.COUNT_UP) # 1\r\nprint(MyConstants.COUNT_UP) # 2\r\nprint(MyConstants.COUNT_UP) # 3\r\nprint(MyConstants.COUNT_UP) # 4\r\n```\r\n\r\n## If you want a mix of constants\r\n```python\r\n# Simple API, just subclass `BaseConstants`\r\nclass Constants(BaseConstants):\r\n # `NUM` is an immutable `int`, i.e. Constants.NUM will always be 123\r\n NUM: Immutable[int] = 123\r\n # No `Immutable` annotation implies Constants.STR is mutable\r\n STR: str = \"Hello\"\r\n # Constants.IMMU_FUNC will call `get_constant` function; the returned value is cached\r\n # and it is immutable\r\n IMMU_FUNC: Cache[Immutable] = get_constant\r\n # Order/Subscripting of annotation does not matter\r\n MUT_FUNC: Immutable[Cache] = get_constant\r\n # Only `Cache` annotation without `Immutable` means it is mutable even after\r\n # the returned value is cached after being called for the first time\r\n JUST_CACHE: Cache[str] = get_constant\r\n # No annotation means it is neither `Cache` nor `Immutable`\r\n NO_ANNO = \"NO_ANNO\"\r\n```\r\n\r\n## Finally, if you want to manage your own asynchronous generator but want the 'reference' to it to be immutable\r\n```python\r\nasync def gen():\r\n i = 1\r\n while i:\r\n stop = yield i\r\n if stop == True:\r\n print(\"Someone asked me to stop!\")\r\n return\r\n i += 1\r\n\r\nasync def getter():\r\n async_asend_gen = gen()\r\n num = None\r\n while True:\r\n i = await async_asend_gen.asend(num)\r\n num = yield i\r\n\r\nclass MyConstants(BaseConstants):\r\n INT: Immutable = getter()\r\n \r\nprint(await MyConstants.INT.asend(None)) # 1\r\nprint(await MyConstants.INT.asend(None)) # 2\r\nprint(await MyConstants.INT.asend(None)) # 3\r\nprint(await MyConstants.INT.asend(None)) # 4\r\nprint(await MyConstants.INT.asend(True)) # Someone asked me to stop!;\r\n# Raises `RuntimeError: async generator raised StopAsyncIteration``\r\n```\r\nThere are more examples in the `examples` folder on Github.\r\n\r\n# Roadmap\r\n\r\n|Description|Progress|Code Sample|\r\n|:--|:--:|:--:|\r\n|Subclassing e.g. `Immutables` make all subclass' class variables immutable|![](https://img.shields.io/badge/Status-UNCOMPLETED-red)|[1]|\r\n|Able to define inner class in outer class definition and declare annotation through parameters passed into class call|![](https://img.shields.io/badge/Status-UNCOMPLETED-red)|[1]|\r\n\r\n## Samples\r\n\r\n### [1]\r\n```python\r\n# Future APIs\r\n\r\nclass MyConstants(BaseConstants):\r\n \r\n class FilePaths(Immutables, this_class_as=(Immutable,)):\r\n # All `TRAINING`, `TESTING` class variables will be `Immutable`.\r\n # The class variable `FilePaths` of `MyConstants`\r\n # will be immutable as well.\r\n TRAINING = \".\"\r\n TESTING = \"..\"\r\n VALIDATION = \"...\"\r\n \r\n class Yielders(Yields):\r\n # Same as above just that all class variables will be\r\n # `Yield` annotated but `Yielders` will be mutable\r\n FIRST = gen\r\n```\r\n# Contributing\r\nContributions are welcome!\r\n",
"bugtrack_url": null,
"license": "",
"summary": "Simple, easy to use with intuitive APIs, for managing constants in your Python applications.",
"version": "0.0.9",
"project_urls": null,
"split_keywords": [
"truconsts",
"truly constants",
"constants"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "158e793a0bff4b805f26c327a799b3f647ffb41467c8c24323ae78b513a5b809",
"md5": "c8751f4f02c6c82eb752df2878a5f5db",
"sha256": "dace782b928ba69e4a6c358dff71eede396f373afad05cb322d30d29904133ba"
},
"downloads": -1,
"filename": "truconsts-0.0.9.tar.gz",
"has_sig": false,
"md5_digest": "c8751f4f02c6c82eb752df2878a5f5db",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 53836,
"upload_time": "2023-06-27T18:28:28",
"upload_time_iso_8601": "2023-06-27T18:28:28.818479Z",
"url": "https://files.pythonhosted.org/packages/15/8e/793a0bff4b805f26c327a799b3f647ffb41467c8c24323ae78b513a5b809/truconsts-0.0.9.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-06-27 18:28:28",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "truconsts"
}