diff options
| author | CoprDistGit <infra@openeuler.org> | 2023-05-10 04:54:19 +0000 |
|---|---|---|
| committer | CoprDistGit <infra@openeuler.org> | 2023-05-10 04:54:19 +0000 |
| commit | f1645ed82753eddd7ac8cd2e770c405d31687fed (patch) | |
| tree | d20531c011ae66b6d38da2a5df509df8687fa66b /python-toolbox.spec | |
| parent | e8438e1ca3c7781930f47b566b9f6fa3f178ed42 (diff) | |
automatic import of python-toolboxopeneuler20.03
Diffstat (limited to 'python-toolbox.spec')
| -rw-r--r-- | python-toolbox.spec | 1581 |
1 files changed, 1581 insertions, 0 deletions
diff --git a/python-toolbox.spec b/python-toolbox.spec new file mode 100644 index 0000000..dad426d --- /dev/null +++ b/python-toolbox.spec @@ -0,0 +1,1581 @@ +%global _empty_manifest_terminate_build 0 +Name: python-toolbox +Version: 1.11.0 +Release: 1 +Summary: Extends Python with useful features. +License: MIT +URL: https://github.com/synchronizing/toolbox +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/54/42/27357827649818b5b6cc86c1b90138e4016b1dd6e469c6b05ae0374ed95e/toolbox-1.11.0.tar.gz +BuildArch: noarch + + +%description +# 🧰 Toolbox + +<p align="center"> + + <a href="https://github.com/synchronizing/toolbox/actions?query=workflow%3ABuild"> + <img src="https://github.com/synchronizing/toolbox/workflows/Build/badge.svg?branch=master&event=push"> + </a> + +<a href="https://synchronizing.github.io/toolbox/"> + <img src="https://github.com/synchronizing/toolbox/workflows/Docs/badge.svg?branch=master&event=push"> + </a> + + <a href="https://coveralls.io/github/synchronizing/toolbox?branch=master"> + <img src="https://coveralls.io/repos/github/synchronizing/toolbox/badge.svg?branch=master"> + </a> + + <a href="https://opensource.org/licenses/MIT"> + <img src="https://img.shields.io/badge/License-MIT-yellow.svg"> + </a> +</p> + +Toolbox is a small (~0.2MB) set of tools that expands the [Python Standard Library](https://docs.python.org/3/library/). + +## Installing + +``` +pip install toolbox +``` + +## Documentation + +Documentation can be found [**here**](http://synchronizing.github.io/toolbox/). + +## Tools + +### `asyncio` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.cache.future_lru_cache"><code>future_lru_cache</code></a> — <code>lru_cache</code> for async functions.</summary><br> + +```python +from toolbox import future_lru_cache +import asyncio + +@future_lru_cache +async def func(): + await asyncio.sleep(10) + return 42 + +async def main(): + await func() # Runs once. + await func() # Returns cached value. + +asyncio.run(main()) +```` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.threads.to_thread"><code>to_thread</code></a> — Run a synchronous function in a separate thread.</summary><br> + +```python +from toolbox import to_thread +import asyncio +import time + +def func(): + time.sleep(2) + return "Hello world" + +async def main(): + await to_thread(func) + +asyncio.run(main()) +```` + +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.threads.awaitable"><code>awaitable</code></a> — Convert synchronous function to an async function via thread.</summary><br> + +Leverages the `to_thread` function above. + +```python +from toolbox import awaitable +import asyncio +import time + +@awaitable +def func(): + time.sleep(2) + return "Hello world" + +async def main(): + await func() + +asyncio.run(func()) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.streams.tls_handshake"><code>tls_handshake</code></a> — Perform TLS handshake with a stream reader & writer.</summary><br> + +```python +from toolbox import tls_handshake +import asyncio + +async def client(): + reader, writer = await asyncio.open_connection("httpbin.org", 443, ssl=False) + await tls_handshake(reader=reader, writer=writer) + + # Communication is now encrypted. + +asyncio.run(client()) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.pattern.CoroutineClass"><code>CoroutineClass</code></a> — Class pattern for implementing object-based coroutines. </summary><br> + +Pattern for creating a coroutine-like class that has multiple ways to start it. + +```python +from toolbox import CoroutineClass +import asyncio + +class Coroutine(CoroutineClass): + def __init__(self, run: bool = False): + super().__init__(run=run) + + # Default entry function. + async def entry(self): + await asyncio.sleep(1) + return "Hello world" + +# Start coroutine outside Python async context. +def iomain(): + + # via __init__ + coro = Coroutine(run=True) + print(coro.result) # Hello world + + # via .run() + coro = Coroutine() + result = coro.run() + print(result) # Hello world + +# Start coroutine inside Python async context. +async def aiomain(): + + # via __init__ + coro = Coroutine(run=True) + await asyncio.sleep(1) + coro.stop() + print(coro.result) # None - because process was stopped before completion. + + # via .run() + coro = Coroutine() + coro.run() + await asyncio.sleep(1) + result = coro.stop() # None - because coroutine was stopped before completion. + print(result) # Hello world + + # via await + coro = Coroutine() + result = await coro # You can also start, and await later. + print(result) # Hello World + + # via context manager + async with Coroutine() as coro: + result = await coro + print(result) # Hello World +``` +</details> + +### `builtins` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/builtins.html#toolbox.builtins.property.classproperty"><code>classproperty</code></a> — Decorator for defining a method as a property and classmethod.</summary><br> + +Allows access to computed class attributes. + +```python +from toolbox import classproperty + +class Animal: + @classproperty + def dog(cls): + return "whoof!" + +print(Animal.dog) # 'whoof!' +``` +</details> + +### `collections` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.item.Item"><code>Item</code></a> — An interface for type-agnostic operations between different types.</summary><br> + +```python +from toolbox import Item + +item = Item(100) +print(item == b"100" == "100" == 100) # True +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.namedtuple.nestednamedtuple"><code>nestednamedtuple</code></a> — Creates a nested <code>namedtuple</code>.</summary><br> + +```python +from toolbox import nestednamedtuple + +nt = nestednamedtuple({"hello": {"ola": "mundo"}}) +print(nt) # namedtupled(hello=namedtupled(ola='mundo')) +print(nt.hello.ola) # mundo +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.namedtuple.fdict"><code>fdict</code></a> — Forces <code>nestednamedtuple</code> to not convert <code>dict</code> to <code>namedtuple</code>. </summary><br> + +```python +from toolbox import nestednamedtuple, fdict + +d = {"hello": "world"} +nt = nestednamedtuple({"forced": fdict(d), "notforced": d}) + +print(nt.notforced) # namedtupled(hello='world') +print(nt.forced) # {'hello': 'world'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.BidirectionalDict"><code>BidirectionalDict</code></a> — Dictionary with two-way capabilities.</summary><br> + +```python +from toolbox import BidirectionalDict + +d = BidirectionalDict({"hello": "world"}) +print(d) # {'hello': 'world', 'world': 'hello'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.ObjectDict"><code>ObjectDict</code></a> — Dictionary that can be accessed as though it was an object.</summary><br> + +```python +from toolbox import ObjectDict + +d = ObjectDict({"hello": "world"}) +print(d.hello) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.OverloadedDict"><code>OverloadedDict</code></a> — Dictionary that can be added or subtracted to.</summary><br> + +```python +from toolbox import OverloadedDict + +d1 = OverloadedDict({"hello": "world"}) +d2 = OverloadedDict({"ola": "mundo"}) + +d1 += d2 +print(d1) # {'hello': 'world', 'ola': 'mundo'} + +d1 -= d2 +print(d1) # {'hello': 'world'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.UnderscoreAccessDict"><code>UnderscoreAccessDict</code></a> — Dictionary with underscore access.</summary><br> + +```python +from toolbox import UnderscoreAccessDict + +d = UnderscoreAccessDict({"hello": "world"}) +print(d.hello) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.FrozenDict"><code>FrozenDict</code></a> — Dictionary that is frozen.</summary><br> + +```python +from toolbox import FrozenDict + +d = FrozenDict({"hello": "world"}) +d["hello"] = "mundo" # KeyError: Cannot set key and value because this is a frozen dictionary. +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.MultiEntryDict"><code>MultiEntryDict</code></a> — Dictionary that can have multiple entries for the same key.</summary><br> + +```python +from toolbox import MultiEntryDict + +d = MultiEntryDict({"hello": "world"}) +d["hello"] = "mundo" +print(d) # {'hello': ['world', 'mundo']} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.ItemDict"><code>ItemDict</code></a> — Dictionary that utilizes <a href="#Item"><code>Item</code></a> for key and values.</summary><br> + +```python +from toolbox import ItemDict, Item + +d = ItemDict({"100": "one hundred"}) +print(d[100]) # one hundred +print(d[100] == d['100'] == d[b'100'] == d[Item(100)]) # True +``` +</details> + +All `*Dict` types above can be combined together (as mixins) to create unique dictionary types. + +### `config` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.make_config"><code>make_config</code></a> — Stores configuration dictionary in-memory.</summary><br> + +Creates a global configuration that can be accessed by other portions of the code via `conf` or `config` function calls. Minimizes the need to create `Config` objects and pass them around different modules, classes, functions, etc. + +```python +from toolbox import make_config + +make_config(hello="world") +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.config"><code>config</code></a> — Access in-memory configuration as dictionary.</summary><br> + +```python +from toolbox import config + +print(config()['hello']) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.conf"><code>conf</code></a> — Access in-memory configuration as <code>nestednametuple</code>.</summary><br> + +```python +from toolbox import conf + +print(conf().hello) # 'world' +``` +</details> + +### `functools` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/functools.html#toolbox.functools.timeout.timeout"><code>timeout</code></a> — Decorator to add timeout for synchronous and asychronous functions.</summary><br> + +Decorator that adds support for synchronous and asynchronous function timeout. Quits function after an amount of time passes. + +```python +from toolbox import timeout +import asyncio +import time + +@timeout(seconds=1) +def func(): + time.sleep(15) + +@timeout(seconds=1) +async def func(): + await asyncio.sleep(15) +``` +</details> + +### `pdb` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/pdb.html#toolbox.pdb.sprinke.sprinkle"><code>sprinkle</code></a> — Prints the line and file that this function was just called from.</summary><br> + +```python +from toolbox.pdb.sprinkle import sprinkle + +sprinkle() # >>> 3 this_file.py +sprinkle("hello", "world") # >>> 4 this_file.py hello world +``` +</details> + +### `pkgutil` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/pkgutil.html#toolbox.pkgutil.package.search_package"><code>search_package</code></a> — Searches for packages installed in the system.</summary><br> + +```python +from toolbox import search_package + +print(search_package("toolbox", method="is")) +# {'toolbox': <module 'toolbox' from '.../toolbox/__init__.py'>} +``` +</details> + +### `sockets` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/sockets.html#toolbox.sockets.ip.is_ip"><code>is_ip</code></a> — Checks if a string is an IP address.</summary><br> + +```python +from toolbox import is_ip + +print(is_ip('127.0.0.1')) # True +print(is_ip('localhost')) # False +``` +</details> + +### `string` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#color">ANSI Formatting</a> — Color formatting.</summary><br> + +Check documentation [here](https://synchronizing.github.io/toolbox/module/string.html#color) for further information on all built-in formats. + +```python +from toolbox import bold, red + +print(red("This text is red!")) +print(bold("This text is bolded!")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.Format"><code>Format</code></a> — Persistent ANSI formatter that takes a custom ANSI code.</summary><br> + +```python +from toolbox import Format + +bold = Format(code=1) +print(bold("hello world")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.Style"><code>Style</code></a> — Persistent ANSI formatter that allows multiple ANSI codes.</summary><br> + +```python +from toolbox import Style, red, bold + +error = Style(red, bold) +print(error("This is red & bolded error.")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.supports_color"><code>supports_color</code></a> — Check's if the user's terminal supports color.</summary><br> + +```python +from toolbox import supports_color + +print(supports_color()) # True +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.strip_ansi"><code>strip_ansi</code></a> — Removes ANSI codes from string.</summary><br> + +```python +from toolbox import strip_ansi + +print(strip_ansi("\x1b[1mhello world\x1b[0m")) # hello world +``` +</details> + +### `textwrap` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/textwrap.html#toolbox.textwrap.text.unindent"><code>unindent</code></a> — Removes indent and white-space from docstrings.</summary><br> + +```python +from toolbox import unindent + +def test(): + text = """ + hello world + this is a test + """ + print(text) + + text = unindent( + """ + hello world + this is a test + """ + ) + print(text) + +test() +# hello world +# this is a test +# +# hello world +# this is a test +``` +</details> + + + +%package -n python3-toolbox +Summary: Extends Python with useful features. +Provides: python-toolbox +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-toolbox +# 🧰 Toolbox + +<p align="center"> + + <a href="https://github.com/synchronizing/toolbox/actions?query=workflow%3ABuild"> + <img src="https://github.com/synchronizing/toolbox/workflows/Build/badge.svg?branch=master&event=push"> + </a> + +<a href="https://synchronizing.github.io/toolbox/"> + <img src="https://github.com/synchronizing/toolbox/workflows/Docs/badge.svg?branch=master&event=push"> + </a> + + <a href="https://coveralls.io/github/synchronizing/toolbox?branch=master"> + <img src="https://coveralls.io/repos/github/synchronizing/toolbox/badge.svg?branch=master"> + </a> + + <a href="https://opensource.org/licenses/MIT"> + <img src="https://img.shields.io/badge/License-MIT-yellow.svg"> + </a> +</p> + +Toolbox is a small (~0.2MB) set of tools that expands the [Python Standard Library](https://docs.python.org/3/library/). + +## Installing + +``` +pip install toolbox +``` + +## Documentation + +Documentation can be found [**here**](http://synchronizing.github.io/toolbox/). + +## Tools + +### `asyncio` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.cache.future_lru_cache"><code>future_lru_cache</code></a> — <code>lru_cache</code> for async functions.</summary><br> + +```python +from toolbox import future_lru_cache +import asyncio + +@future_lru_cache +async def func(): + await asyncio.sleep(10) + return 42 + +async def main(): + await func() # Runs once. + await func() # Returns cached value. + +asyncio.run(main()) +```` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.threads.to_thread"><code>to_thread</code></a> — Run a synchronous function in a separate thread.</summary><br> + +```python +from toolbox import to_thread +import asyncio +import time + +def func(): + time.sleep(2) + return "Hello world" + +async def main(): + await to_thread(func) + +asyncio.run(main()) +```` + +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.threads.awaitable"><code>awaitable</code></a> — Convert synchronous function to an async function via thread.</summary><br> + +Leverages the `to_thread` function above. + +```python +from toolbox import awaitable +import asyncio +import time + +@awaitable +def func(): + time.sleep(2) + return "Hello world" + +async def main(): + await func() + +asyncio.run(func()) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.streams.tls_handshake"><code>tls_handshake</code></a> — Perform TLS handshake with a stream reader & writer.</summary><br> + +```python +from toolbox import tls_handshake +import asyncio + +async def client(): + reader, writer = await asyncio.open_connection("httpbin.org", 443, ssl=False) + await tls_handshake(reader=reader, writer=writer) + + # Communication is now encrypted. + +asyncio.run(client()) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.pattern.CoroutineClass"><code>CoroutineClass</code></a> — Class pattern for implementing object-based coroutines. </summary><br> + +Pattern for creating a coroutine-like class that has multiple ways to start it. + +```python +from toolbox import CoroutineClass +import asyncio + +class Coroutine(CoroutineClass): + def __init__(self, run: bool = False): + super().__init__(run=run) + + # Default entry function. + async def entry(self): + await asyncio.sleep(1) + return "Hello world" + +# Start coroutine outside Python async context. +def iomain(): + + # via __init__ + coro = Coroutine(run=True) + print(coro.result) # Hello world + + # via .run() + coro = Coroutine() + result = coro.run() + print(result) # Hello world + +# Start coroutine inside Python async context. +async def aiomain(): + + # via __init__ + coro = Coroutine(run=True) + await asyncio.sleep(1) + coro.stop() + print(coro.result) # None - because process was stopped before completion. + + # via .run() + coro = Coroutine() + coro.run() + await asyncio.sleep(1) + result = coro.stop() # None - because coroutine was stopped before completion. + print(result) # Hello world + + # via await + coro = Coroutine() + result = await coro # You can also start, and await later. + print(result) # Hello World + + # via context manager + async with Coroutine() as coro: + result = await coro + print(result) # Hello World +``` +</details> + +### `builtins` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/builtins.html#toolbox.builtins.property.classproperty"><code>classproperty</code></a> — Decorator for defining a method as a property and classmethod.</summary><br> + +Allows access to computed class attributes. + +```python +from toolbox import classproperty + +class Animal: + @classproperty + def dog(cls): + return "whoof!" + +print(Animal.dog) # 'whoof!' +``` +</details> + +### `collections` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.item.Item"><code>Item</code></a> — An interface for type-agnostic operations between different types.</summary><br> + +```python +from toolbox import Item + +item = Item(100) +print(item == b"100" == "100" == 100) # True +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.namedtuple.nestednamedtuple"><code>nestednamedtuple</code></a> — Creates a nested <code>namedtuple</code>.</summary><br> + +```python +from toolbox import nestednamedtuple + +nt = nestednamedtuple({"hello": {"ola": "mundo"}}) +print(nt) # namedtupled(hello=namedtupled(ola='mundo')) +print(nt.hello.ola) # mundo +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.namedtuple.fdict"><code>fdict</code></a> — Forces <code>nestednamedtuple</code> to not convert <code>dict</code> to <code>namedtuple</code>. </summary><br> + +```python +from toolbox import nestednamedtuple, fdict + +d = {"hello": "world"} +nt = nestednamedtuple({"forced": fdict(d), "notforced": d}) + +print(nt.notforced) # namedtupled(hello='world') +print(nt.forced) # {'hello': 'world'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.BidirectionalDict"><code>BidirectionalDict</code></a> — Dictionary with two-way capabilities.</summary><br> + +```python +from toolbox import BidirectionalDict + +d = BidirectionalDict({"hello": "world"}) +print(d) # {'hello': 'world', 'world': 'hello'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.ObjectDict"><code>ObjectDict</code></a> — Dictionary that can be accessed as though it was an object.</summary><br> + +```python +from toolbox import ObjectDict + +d = ObjectDict({"hello": "world"}) +print(d.hello) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.OverloadedDict"><code>OverloadedDict</code></a> — Dictionary that can be added or subtracted to.</summary><br> + +```python +from toolbox import OverloadedDict + +d1 = OverloadedDict({"hello": "world"}) +d2 = OverloadedDict({"ola": "mundo"}) + +d1 += d2 +print(d1) # {'hello': 'world', 'ola': 'mundo'} + +d1 -= d2 +print(d1) # {'hello': 'world'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.UnderscoreAccessDict"><code>UnderscoreAccessDict</code></a> — Dictionary with underscore access.</summary><br> + +```python +from toolbox import UnderscoreAccessDict + +d = UnderscoreAccessDict({"hello": "world"}) +print(d.hello) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.FrozenDict"><code>FrozenDict</code></a> — Dictionary that is frozen.</summary><br> + +```python +from toolbox import FrozenDict + +d = FrozenDict({"hello": "world"}) +d["hello"] = "mundo" # KeyError: Cannot set key and value because this is a frozen dictionary. +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.MultiEntryDict"><code>MultiEntryDict</code></a> — Dictionary that can have multiple entries for the same key.</summary><br> + +```python +from toolbox import MultiEntryDict + +d = MultiEntryDict({"hello": "world"}) +d["hello"] = "mundo" +print(d) # {'hello': ['world', 'mundo']} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.ItemDict"><code>ItemDict</code></a> — Dictionary that utilizes <a href="#Item"><code>Item</code></a> for key and values.</summary><br> + +```python +from toolbox import ItemDict, Item + +d = ItemDict({"100": "one hundred"}) +print(d[100]) # one hundred +print(d[100] == d['100'] == d[b'100'] == d[Item(100)]) # True +``` +</details> + +All `*Dict` types above can be combined together (as mixins) to create unique dictionary types. + +### `config` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.make_config"><code>make_config</code></a> — Stores configuration dictionary in-memory.</summary><br> + +Creates a global configuration that can be accessed by other portions of the code via `conf` or `config` function calls. Minimizes the need to create `Config` objects and pass them around different modules, classes, functions, etc. + +```python +from toolbox import make_config + +make_config(hello="world") +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.config"><code>config</code></a> — Access in-memory configuration as dictionary.</summary><br> + +```python +from toolbox import config + +print(config()['hello']) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.conf"><code>conf</code></a> — Access in-memory configuration as <code>nestednametuple</code>.</summary><br> + +```python +from toolbox import conf + +print(conf().hello) # 'world' +``` +</details> + +### `functools` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/functools.html#toolbox.functools.timeout.timeout"><code>timeout</code></a> — Decorator to add timeout for synchronous and asychronous functions.</summary><br> + +Decorator that adds support for synchronous and asynchronous function timeout. Quits function after an amount of time passes. + +```python +from toolbox import timeout +import asyncio +import time + +@timeout(seconds=1) +def func(): + time.sleep(15) + +@timeout(seconds=1) +async def func(): + await asyncio.sleep(15) +``` +</details> + +### `pdb` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/pdb.html#toolbox.pdb.sprinke.sprinkle"><code>sprinkle</code></a> — Prints the line and file that this function was just called from.</summary><br> + +```python +from toolbox.pdb.sprinkle import sprinkle + +sprinkle() # >>> 3 this_file.py +sprinkle("hello", "world") # >>> 4 this_file.py hello world +``` +</details> + +### `pkgutil` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/pkgutil.html#toolbox.pkgutil.package.search_package"><code>search_package</code></a> — Searches for packages installed in the system.</summary><br> + +```python +from toolbox import search_package + +print(search_package("toolbox", method="is")) +# {'toolbox': <module 'toolbox' from '.../toolbox/__init__.py'>} +``` +</details> + +### `sockets` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/sockets.html#toolbox.sockets.ip.is_ip"><code>is_ip</code></a> — Checks if a string is an IP address.</summary><br> + +```python +from toolbox import is_ip + +print(is_ip('127.0.0.1')) # True +print(is_ip('localhost')) # False +``` +</details> + +### `string` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#color">ANSI Formatting</a> — Color formatting.</summary><br> + +Check documentation [here](https://synchronizing.github.io/toolbox/module/string.html#color) for further information on all built-in formats. + +```python +from toolbox import bold, red + +print(red("This text is red!")) +print(bold("This text is bolded!")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.Format"><code>Format</code></a> — Persistent ANSI formatter that takes a custom ANSI code.</summary><br> + +```python +from toolbox import Format + +bold = Format(code=1) +print(bold("hello world")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.Style"><code>Style</code></a> — Persistent ANSI formatter that allows multiple ANSI codes.</summary><br> + +```python +from toolbox import Style, red, bold + +error = Style(red, bold) +print(error("This is red & bolded error.")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.supports_color"><code>supports_color</code></a> — Check's if the user's terminal supports color.</summary><br> + +```python +from toolbox import supports_color + +print(supports_color()) # True +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.strip_ansi"><code>strip_ansi</code></a> — Removes ANSI codes from string.</summary><br> + +```python +from toolbox import strip_ansi + +print(strip_ansi("\x1b[1mhello world\x1b[0m")) # hello world +``` +</details> + +### `textwrap` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/textwrap.html#toolbox.textwrap.text.unindent"><code>unindent</code></a> — Removes indent and white-space from docstrings.</summary><br> + +```python +from toolbox import unindent + +def test(): + text = """ + hello world + this is a test + """ + print(text) + + text = unindent( + """ + hello world + this is a test + """ + ) + print(text) + +test() +# hello world +# this is a test +# +# hello world +# this is a test +``` +</details> + + + +%package help +Summary: Development documents and examples for toolbox +Provides: python3-toolbox-doc +%description help +# 🧰 Toolbox + +<p align="center"> + + <a href="https://github.com/synchronizing/toolbox/actions?query=workflow%3ABuild"> + <img src="https://github.com/synchronizing/toolbox/workflows/Build/badge.svg?branch=master&event=push"> + </a> + +<a href="https://synchronizing.github.io/toolbox/"> + <img src="https://github.com/synchronizing/toolbox/workflows/Docs/badge.svg?branch=master&event=push"> + </a> + + <a href="https://coveralls.io/github/synchronizing/toolbox?branch=master"> + <img src="https://coveralls.io/repos/github/synchronizing/toolbox/badge.svg?branch=master"> + </a> + + <a href="https://opensource.org/licenses/MIT"> + <img src="https://img.shields.io/badge/License-MIT-yellow.svg"> + </a> +</p> + +Toolbox is a small (~0.2MB) set of tools that expands the [Python Standard Library](https://docs.python.org/3/library/). + +## Installing + +``` +pip install toolbox +``` + +## Documentation + +Documentation can be found [**here**](http://synchronizing.github.io/toolbox/). + +## Tools + +### `asyncio` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.cache.future_lru_cache"><code>future_lru_cache</code></a> — <code>lru_cache</code> for async functions.</summary><br> + +```python +from toolbox import future_lru_cache +import asyncio + +@future_lru_cache +async def func(): + await asyncio.sleep(10) + return 42 + +async def main(): + await func() # Runs once. + await func() # Returns cached value. + +asyncio.run(main()) +```` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.threads.to_thread"><code>to_thread</code></a> — Run a synchronous function in a separate thread.</summary><br> + +```python +from toolbox import to_thread +import asyncio +import time + +def func(): + time.sleep(2) + return "Hello world" + +async def main(): + await to_thread(func) + +asyncio.run(main()) +```` + +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.threads.awaitable"><code>awaitable</code></a> — Convert synchronous function to an async function via thread.</summary><br> + +Leverages the `to_thread` function above. + +```python +from toolbox import awaitable +import asyncio +import time + +@awaitable +def func(): + time.sleep(2) + return "Hello world" + +async def main(): + await func() + +asyncio.run(func()) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.streams.tls_handshake"><code>tls_handshake</code></a> — Perform TLS handshake with a stream reader & writer.</summary><br> + +```python +from toolbox import tls_handshake +import asyncio + +async def client(): + reader, writer = await asyncio.open_connection("httpbin.org", 443, ssl=False) + await tls_handshake(reader=reader, writer=writer) + + # Communication is now encrypted. + +asyncio.run(client()) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/asyncio.html#toolbox.asyncio.pattern.CoroutineClass"><code>CoroutineClass</code></a> — Class pattern for implementing object-based coroutines. </summary><br> + +Pattern for creating a coroutine-like class that has multiple ways to start it. + +```python +from toolbox import CoroutineClass +import asyncio + +class Coroutine(CoroutineClass): + def __init__(self, run: bool = False): + super().__init__(run=run) + + # Default entry function. + async def entry(self): + await asyncio.sleep(1) + return "Hello world" + +# Start coroutine outside Python async context. +def iomain(): + + # via __init__ + coro = Coroutine(run=True) + print(coro.result) # Hello world + + # via .run() + coro = Coroutine() + result = coro.run() + print(result) # Hello world + +# Start coroutine inside Python async context. +async def aiomain(): + + # via __init__ + coro = Coroutine(run=True) + await asyncio.sleep(1) + coro.stop() + print(coro.result) # None - because process was stopped before completion. + + # via .run() + coro = Coroutine() + coro.run() + await asyncio.sleep(1) + result = coro.stop() # None - because coroutine was stopped before completion. + print(result) # Hello world + + # via await + coro = Coroutine() + result = await coro # You can also start, and await later. + print(result) # Hello World + + # via context manager + async with Coroutine() as coro: + result = await coro + print(result) # Hello World +``` +</details> + +### `builtins` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/builtins.html#toolbox.builtins.property.classproperty"><code>classproperty</code></a> — Decorator for defining a method as a property and classmethod.</summary><br> + +Allows access to computed class attributes. + +```python +from toolbox import classproperty + +class Animal: + @classproperty + def dog(cls): + return "whoof!" + +print(Animal.dog) # 'whoof!' +``` +</details> + +### `collections` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.item.Item"><code>Item</code></a> — An interface for type-agnostic operations between different types.</summary><br> + +```python +from toolbox import Item + +item = Item(100) +print(item == b"100" == "100" == 100) # True +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.namedtuple.nestednamedtuple"><code>nestednamedtuple</code></a> — Creates a nested <code>namedtuple</code>.</summary><br> + +```python +from toolbox import nestednamedtuple + +nt = nestednamedtuple({"hello": {"ola": "mundo"}}) +print(nt) # namedtupled(hello=namedtupled(ola='mundo')) +print(nt.hello.ola) # mundo +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.namedtuple.fdict"><code>fdict</code></a> — Forces <code>nestednamedtuple</code> to not convert <code>dict</code> to <code>namedtuple</code>. </summary><br> + +```python +from toolbox import nestednamedtuple, fdict + +d = {"hello": "world"} +nt = nestednamedtuple({"forced": fdict(d), "notforced": d}) + +print(nt.notforced) # namedtupled(hello='world') +print(nt.forced) # {'hello': 'world'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.BidirectionalDict"><code>BidirectionalDict</code></a> — Dictionary with two-way capabilities.</summary><br> + +```python +from toolbox import BidirectionalDict + +d = BidirectionalDict({"hello": "world"}) +print(d) # {'hello': 'world', 'world': 'hello'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.ObjectDict"><code>ObjectDict</code></a> — Dictionary that can be accessed as though it was an object.</summary><br> + +```python +from toolbox import ObjectDict + +d = ObjectDict({"hello": "world"}) +print(d.hello) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.OverloadedDict"><code>OverloadedDict</code></a> — Dictionary that can be added or subtracted to.</summary><br> + +```python +from toolbox import OverloadedDict + +d1 = OverloadedDict({"hello": "world"}) +d2 = OverloadedDict({"ola": "mundo"}) + +d1 += d2 +print(d1) # {'hello': 'world', 'ola': 'mundo'} + +d1 -= d2 +print(d1) # {'hello': 'world'} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.UnderscoreAccessDict"><code>UnderscoreAccessDict</code></a> — Dictionary with underscore access.</summary><br> + +```python +from toolbox import UnderscoreAccessDict + +d = UnderscoreAccessDict({"hello": "world"}) +print(d.hello) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.FrozenDict"><code>FrozenDict</code></a> — Dictionary that is frozen.</summary><br> + +```python +from toolbox import FrozenDict + +d = FrozenDict({"hello": "world"}) +d["hello"] = "mundo" # KeyError: Cannot set key and value because this is a frozen dictionary. +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.MultiEntryDict"><code>MultiEntryDict</code></a> — Dictionary that can have multiple entries for the same key.</summary><br> + +```python +from toolbox import MultiEntryDict + +d = MultiEntryDict({"hello": "world"}) +d["hello"] = "mundo" +print(d) # {'hello': ['world', 'mundo']} +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/collections.html#toolbox.collections.mapping.ItemDict"><code>ItemDict</code></a> — Dictionary that utilizes <a href="#Item"><code>Item</code></a> for key and values.</summary><br> + +```python +from toolbox import ItemDict, Item + +d = ItemDict({"100": "one hundred"}) +print(d[100]) # one hundred +print(d[100] == d['100'] == d[b'100'] == d[Item(100)]) # True +``` +</details> + +All `*Dict` types above can be combined together (as mixins) to create unique dictionary types. + +### `config` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.make_config"><code>make_config</code></a> — Stores configuration dictionary in-memory.</summary><br> + +Creates a global configuration that can be accessed by other portions of the code via `conf` or `config` function calls. Minimizes the need to create `Config` objects and pass them around different modules, classes, functions, etc. + +```python +from toolbox import make_config + +make_config(hello="world") +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.config"><code>config</code></a> — Access in-memory configuration as dictionary.</summary><br> + +```python +from toolbox import config + +print(config()['hello']) # 'world' +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/config.html#toolbox.config.globalconfig.conf"><code>conf</code></a> — Access in-memory configuration as <code>nestednametuple</code>.</summary><br> + +```python +from toolbox import conf + +print(conf().hello) # 'world' +``` +</details> + +### `functools` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/functools.html#toolbox.functools.timeout.timeout"><code>timeout</code></a> — Decorator to add timeout for synchronous and asychronous functions.</summary><br> + +Decorator that adds support for synchronous and asynchronous function timeout. Quits function after an amount of time passes. + +```python +from toolbox import timeout +import asyncio +import time + +@timeout(seconds=1) +def func(): + time.sleep(15) + +@timeout(seconds=1) +async def func(): + await asyncio.sleep(15) +``` +</details> + +### `pdb` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/pdb.html#toolbox.pdb.sprinke.sprinkle"><code>sprinkle</code></a> — Prints the line and file that this function was just called from.</summary><br> + +```python +from toolbox.pdb.sprinkle import sprinkle + +sprinkle() # >>> 3 this_file.py +sprinkle("hello", "world") # >>> 4 this_file.py hello world +``` +</details> + +### `pkgutil` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/pkgutil.html#toolbox.pkgutil.package.search_package"><code>search_package</code></a> — Searches for packages installed in the system.</summary><br> + +```python +from toolbox import search_package + +print(search_package("toolbox", method="is")) +# {'toolbox': <module 'toolbox' from '.../toolbox/__init__.py'>} +``` +</details> + +### `sockets` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/sockets.html#toolbox.sockets.ip.is_ip"><code>is_ip</code></a> — Checks if a string is an IP address.</summary><br> + +```python +from toolbox import is_ip + +print(is_ip('127.0.0.1')) # True +print(is_ip('localhost')) # False +``` +</details> + +### `string` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#color">ANSI Formatting</a> — Color formatting.</summary><br> + +Check documentation [here](https://synchronizing.github.io/toolbox/module/string.html#color) for further information on all built-in formats. + +```python +from toolbox import bold, red + +print(red("This text is red!")) +print(bold("This text is bolded!")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.Format"><code>Format</code></a> — Persistent ANSI formatter that takes a custom ANSI code.</summary><br> + +```python +from toolbox import Format + +bold = Format(code=1) +print(bold("hello world")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.Style"><code>Style</code></a> — Persistent ANSI formatter that allows multiple ANSI codes.</summary><br> + +```python +from toolbox import Style, red, bold + +error = Style(red, bold) +print(error("This is red & bolded error.")) +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.supports_color"><code>supports_color</code></a> — Check's if the user's terminal supports color.</summary><br> + +```python +from toolbox import supports_color + +print(supports_color()) # True +``` +</details> + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/string.html#toolbox.string.color.strip_ansi"><code>strip_ansi</code></a> — Removes ANSI codes from string.</summary><br> + +```python +from toolbox import strip_ansi + +print(strip_ansi("\x1b[1mhello world\x1b[0m")) # hello world +``` +</details> + +### `textwrap` + +<details> + <summary><a href="https://synchronizing.github.io/toolbox/module/textwrap.html#toolbox.textwrap.text.unindent"><code>unindent</code></a> — Removes indent and white-space from docstrings.</summary><br> + +```python +from toolbox import unindent + +def test(): + text = """ + hello world + this is a test + """ + print(text) + + text = unindent( + """ + hello world + this is a test + """ + ) + print(text) + +test() +# hello world +# this is a test +# +# hello world +# this is a test +``` +</details> + + + +%prep +%autosetup -n toolbox-1.11.0 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-toolbox -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Wed May 10 2023 Python_Bot <Python_Bot@openeuler.org> - 1.11.0-1 +- Package Spec generated |
