[![Sourcecode on GitHub](https://img.shields.io/badge/pyTooling-pyTooling-63bf7f.svg?longCache=true&style=flat-square&longCache=true&logo=GitHub)](https://GitHub.com/pyTooling/pyTooling)
[![Sourcecode License](https://img.shields.io/pypi/l/pyTooling?longCache=true&style=flat-square&logo=Apache&label=code)](LICENSE.md)
[![Documentation](https://img.shields.io/website?longCache=true&style=flat-square&label=pyTooling.github.io%2FpyTooling&logo=GitHub&logoColor=fff&up_color=blueviolet&up_message=Read%20now%20%E2%9E%9A&url=https%3A%2F%2FpyTooling.github.io%2FpyTooling%2Findex.html)](https://pyTooling.github.io/pyTooling/)
[![Documentation License](https://img.shields.io/badge/doc-CC--BY%204.0-green?longCache=true&style=flat-square&logo=CreativeCommons&logoColor=fff)](LICENSE.md)
[![PyPI](https://img.shields.io/pypi/v/pyTooling?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)](https://pypi.org/project/pyTooling/)
![PyPI - Status](https://img.shields.io/pypi/status/pyTooling?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyTooling?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)
[![GitHub Workflow - Build and Test Status](https://img.shields.io/github/actions/workflow/status/pyTooling/pyTooling/Pipeline.yml?branch=main&longCache=true&style=flat-square&label=Build%20and%20test&logo=GitHub%20Actions&logoColor=FFFFFF)](https://GitHub.com/pyTooling/pyTooling/actions/workflows/Pipeline.yml)
[![Libraries.io status for latest release](https://img.shields.io/librariesio/release/pypi/pyTooling?longCache=true&style=flat-square&logo=Libraries.io&logoColor=fff)](https://libraries.io/github/pyTooling/pyTooling)
[![Codacy - Quality](https://img.shields.io/codacy/grade/8dc5205ba8b24e008f2287759096e181?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/pyTooling/pyTooling)
[![Codacy - Coverage](https://img.shields.io/codacy/coverage/8dc5205ba8b24e008f2287759096e181?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/pyTooling/pyTooling)
[![Codecov - Branch Coverage](https://img.shields.io/codecov/c/github/pyTooling/pyTooling?longCache=true&style=flat-square&logo=Codecov)](https://codecov.io/gh/pyTooling/pyTooling)
![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/pyTooling/pyTooling/Pipeline.yml?branch=main)
<!--
[![Gitter](https://img.shields.io/badge/chat-on%20gitter-4db797.svg?longCache=true&style=flat-square&logo=gitter&logoColor=e8ecef)](https://gitter.im/hdl/community)
[![Dependent repos (via libraries.io)](https://img.shields.io/librariesio/dependent-repos/pypi/pyTooling?longCache=true&style=flat-square&logo=GitHub)](https://github.com/pyTooling/pyTooling/network/dependents)
[![Libraries.io SourceRank](https://img.shields.io/librariesio/sourcerank/pypi/pyTooling)](https://libraries.io/github/pyTooling/pyTooling/sourcerank)
-->
# pyTooling
**pyTooling** is a powerful collection of arbitrary useful abstract data models, missing classes, decorators, a new
performance boosting meta-class and enhanced exceptions. It also provides lots of helper functions e.g. to ease the
handling of package descriptions or to unify multiple existing APIs into a single API.
It's useful - if not even essential - for **any** Python-base project independent if it's a library, framework, CLI tool
or just a "script".
In addition, pyTooling provides a collection of [CI job templates for GitHub Actions](https://github.com/pyTooling/Actions).
This drastically simplifies GHA-based CI pipelines for Python projects.
## Package Details
### Attributes
The [pyTooling.Attributes] module offers the base implementation of *.NET-like attributes* realized with Python
decorators. The annotated and declarative data is stored as instances of Attribute classes in an additional field per
class, method or function.
The annotation syntax (decorator syntax) allows users to attach any structured data to classes, methods or functions. In
many cases, a user will derive a custom attribute from Attribute and override the __init__ method, so user-defined
parameters can be accepted when the attribute is constructed.
Later, classes, methods or functions can be searched for by querying the attribute class for attribute instance usage
locations (see example to the right). Another option for class and method attributes is declaring a classes using
pyTooling’s `ExtendedType` meta-class. Here the class itself offers helper methods for discovering annotated methods.
A `SimpleAttribute` class is offered accepting any positional and keyword parameters. In a more advanced use case, users
are encouraged to derive their own attribute class hierarchy from `Attribute`.
#### Use Cases
In general all classes, methods and functions can be annotated with additional meta-data. It depends on the application,
framework or library to decide if annotations should be applied imperatively as regular code or declaratively as
attributes via Python decorators.
**With this in mind, the following use-cases and ideas can be derived:**
* Describe a command line argument parser (like ArgParse) in a declarative form. |br|
See [pyTooling.Attributes.ArgParse Package and Examples](https://pytooling.github.io/pyTooling/Attributes/ArgParse.html)
* Mark nested classes, so later when the outer class gets instantiated, these nested classes are indexed or
automatically registered.
See [CLIAbstraction](https://pytooling.github.io/pyTooling/CLIAbstraction/index.html) → [CLIABS/CLIArgument]
* Mark methods in a class as test cases and classes as test suites, so test cases and suites are not identified based on
a magic method name.
*Investigation ongoing / planned feature.*
#### Using `SimpleAttribute`
````Python
from pyTooling.Attributes import SimpleAttribute
@SimpleAttribute(kind="testsuite")
class MyClass:
@SimpleAttribute(kind="testcase", id=1, description="Test and operator")
def test_and(self):
...
@SimpleAttribute(kind="testcase", id=2, description="Test xor operator")
def test_xor(self):
...
````
### CLI Abstraction
[pyTooling.CLIAbstraction] offers an abstraction layer for command line programs, so they can be used easily in Python.
There is no need for manually assembling parameter lists or considering the order of parameters. All parameters like
`-v` or `--value=42` are described as [CommandLineArgument] instances on a [Program] class. Each argument class like
[ShortFlag] or [PathArgument] knows about the correct formatting pattern, character escaping, and if needed about
necessary type conversions. A program instance can be converted to an argument list suitable for [subprocess.Popen].
While a user-defined command line program abstraction derived from [Program] only
takes care of maintaining and assembling parameter lists, a more advanced base-class, called [Executable],
is offered with embedded [subprocess.Popen] behavior.
#### Design Goals
* Offer access to CLI programs as Python classes.
* Abstract CLI arguments (a.k.a. parameter, option, flag, ...) as members on such a Python class.
* Abstract differences in operating systems like argument pattern (POSIX: `-h` vs. Windows: `/h`), path delimiter
signs (POSIX: `/` vs. Windows: `\`) or executable names.
* Derive program variants from existing programs.
* Assemble parameters as list for handover to [subprocess.Popen] with proper escaping and quoting.
* Launch a program with :class:[subprocess.Popen] and hide the complexity of Popen.
* Get a generator object for line-by-line output reading to enable postprocessing of outputs.
### Common Helper Functions
This is a set of useful [helper functions](https://pytooling.github.io/pyTooling/Common/index.html#common-helperfunctions):
* [getsizeof](https://pytooling.github.io/pyTooling/Common/index.html#getsizeof) calculates the "real" size of a data structure.
* [isnestedclass](https://pytooling.github.io/pyTooling/Common/index.html#isnestedclass) checks if a class is nested inside another class.
* [firstKey](https://pytooling.github.io/pyTooling/Common/index.html#firstkey), [firstValue](https://pytooling.github.io/pyTooling/Common/index.html#firstvalue), [firstPair](https://pytooling.github.io/pyTooling/Common/index.html#firstitem) get the firstItem key/value/item from an ordered dictionary.
* [mergedicts](https://pytooling.github.io/pyTooling/Common/index.html#mergedicts) merges multiple dictionaries into a new dictionary.
* [zipdicts](https://pytooling.github.io/pyTooling/Common/index.html#zipdicts) iterate multiple dictionaries simultaneously.
### Common Classes
* [Call-by-reference parameters](https://pytooling.github.io/pyTooling/Common/CallByRef.html): Python doesn't provide
*call-by-reference parameters* for simple types.
This behavior can be emulated with classes provided by the `pyTooling.CallByRef` module.
* [Unified license names](https://pytooling.github.io/pyTooling/Common/Licensing.html): Setuptools, PyPI, and others
have a varying understanding of license names.
The `pyTooling.Licensing` module provides *unified license names* as well as license name mappings or translations.
* [Unified platform and environment description](https://pytooling.github.io/pyTooling/Common/Platform.html): Python has
many ways in figuring out the current platform using APIs from `sys`, `platform`, `os`, …. Unfortunately, none of the
provided standard APIs offers a comprehensive answer. pyTooling provides a `CurrentPlatform` singleton summarizing
multiple platform APIs into a single class instance.
* [Representations of version numbers](https://pytooling.github.io/pyTooling/Common/Versioning.html): While Python
itself has a good versioning schema, there are no classes provided to abstract version numbers. pyTooling provides
such representations following semantic versioning (SemVer) and calendar versioning (CalVer) schemes. It's provided by
the `pyTooling.Versioning` module.
### Configuration
Various file formats suitable for configuration information share the same features supporting: key-value pairs
(dictionaries), sequences (lists), and simple types like string, integer and float. pyTooling provides an
[abstract configuration file data model](https://pytooling.github.io/pyTooling/Configuration/index.html) supporting
these features. Moreover, concrete [configuration file format reader](https://pytooling.github.io/pyTooling/Configuration/FileFormats.html)
implementations are provided as well.
* [JSON configuration reader](https://pytooling.github.io/pyTooling/Configuration/JSON.html) for the JSON file format.
* [TOML configuration reader](https://pytooling.github.io/pyTooling/Configuration/TOML.html) → To be implemented.
* [YAML configuration reader](https://pytooling.github.io/pyTooling/Configuration/YAML.html) for the YAML file format.
### Data Structures
pyTooling also provides [fast and powerful data structures](https://pytooling.github.io/pyTooling/DataStructures/index.html)
offering object-oriented APIs:
* [Graph data structure](https://pytooling.github.io/pyTooling/DataStructures/Graph.html)
→ A directed graph implementation using a `Vertex` and an `Edge` class.
* [Path data structure](https://pytooling.github.io/pyTooling/DataStructures/Path/index.html)
→ To be documented.
* [Finite State Machine data structure](https://pytooling.github.io/pyTooling/DataStructures/StateMachine.html)
→ A data model for state machines using a `State` and a `Transition` class.
* [Tree data structure](https://pytooling.github.io/pyTooling/DataStructures/Tree.html)
→ A fast and simple implementation using a single `Node` class.
### Decorators
* [Abstract Methods](https://pytooling.github.io/pyTooling/MetaClasses.html#meta-abstract)
* Methods marked with `abstractmethod` are abstract and need to be overwritten in a derived class.
An *abstract method* might be called from the overwriting method.
* Methods marked with `mustoverride` are abstract and need to be overridden in a derived class.
It's not allowed to call a *mustoverride method*.
* [Documentation](https://pytooling.github.io/pyTooling/Decorators.html#deco-documentation)
* Copy the doc-string from given base-class via `InheritDocString`.
* [Visibility](https://pytooling.github.io/pyTooling/Decorators.html#deco-visibility)
* Register the given function or class as publicly accessible in a module via `export`.
* [Documentation](https://pyTooling.GitHub.io/pyTooling/Decorators.html#documentation)
* [`@InheritDocString`](https://pyTooling.GitHub.io/pyTooling/Decorators.html#inheritdocstring)
→ Copy the doc-string from given base-class.
* [Visibility](https://pyTooling.GitHub.io/pyTooling/Decorators.html#visibility)
* [`@export`](https://pyTooling.GitHub.io/pyTooling/Decorators.html#export)
→ Register the given function or class as publicly accessible in a module.
### Exceptions
* [EnvironmentException](https://pyTooling.GitHub.io/pyTooling/Exceptions.html#environmentexception)
... is raised when an expected environment variable is missing.
* [PlatformNotSupportedException](https://pyTooling.GitHub.io/pyTooling/Exceptions.html#platformnotsupportedexception)
... is raise if the platform is not supported.
* [NotConfiguredException](https://pyTooling.GitHub.io/pyTooling/Exceptions.html#notconfiguredexception)
... is raise if the requested setting is not configured.
### Meta-Classes
pyTooling provides an [enhanced meta-class](https://pytooling.github.io/pyTooling/MetaClasses.html) called
`ExtendedType`. This meta-classes allows to implement
[abstract methods](https://pytooling.github.io/pyTooling/MetaClasses.html#abstract-method),
[singletons](https://pytooling.github.io/pyTooling/MetaClasses.html#singleton),
[slotted types](https://pytooling.github.io/pyTooling/MetaClasses.html#slotted-type) and combinations thereof.
`class MyClass(metaclass=ExtendedType):`
A class definition using that meta-class can implement
[abstract methods](https://pytooling.github.io/pyTooling/MetaClasses.html#abstract-method) using decorators
`@abstractmethod` or `@mustoverride`.
`class MyClass(metaclass=ExtendedType, singleton=True):`
A class defined with enabled [singleton](https://pytooling.github.io/pyTooling/MetaClasses.html#singleton) behavior
allows only a single instance of that class to exist. If another instance is going to be created, a previously cached
instance of that class will be returned.
`class MyClass(metaclass=ExtendedType, slots=True):`
A class defined with enabled [slots](https://pytooling.github.io/pyTooling/MetaClasses.html#slotted-type) behavior
stores instance fields in slots. The meta-class, translates all type-annotated fields in a class definition into
slots. Slots allow a more efficient field storage and access compared to dynamically stored and accessed fields hosted
by `__dict__`. This improves the memory footprint as well as the field access performance of all class instances. This
behavior is automatically inherited to all derived classes.
`class MyClass(ObjectWithSlots):`
A class definition deriving from `ObjectWithSlots` will bring the slotted type behavior to that class and all derived
classes.
### Packaging
A set of helper functions to describe a Python package for setuptools.
* Helper Functions:
* `loadReadmeFile`
Load a `README.md` file from disk and provide the content as long description for setuptools.
* `loadRequirementsFile`
Load a `requirements.txt` file from disk and provide the content for setuptools.
* `extractVersionInformation`
Extract version information from Python source files and provide the data to setuptools.
* Package Descriptions
* `DescribePythonPackage`
tbd
* `DescribePythonPackageHostedOnGitHub`
tbd
### Terminal
A set of helpers to implement a text user interface (TUI) in a terminal.
#### Features
* Colored command line outputs based on `colorama`.
* Message classification in `fatal`, `error`, `warning`, `normal`, `quiet`, ...
* Get information like terminal dimensions from underlying terminal window.
#### Simple Terminal Application
This is a minimal terminal application example which inherits from `LineTerminal`.
```python
from pyTooling.TerminalUI import TerminalApplication
class Application(TerminalApplication):
def __init__(self) -> None:
super().__init__()
def run(self):
self.WriteNormal("This is a simple application.")
self.WriteWarning("This is a warning message.")
self.WriteError("This is an error message.")
# entry point
if __name__ == "__main__":
Application.CheckPythonVersion((3, 6, 0))
app = Application()
app.run()
app.Exit()
```
### Timer
*tbd*
## Examples
### `@export` Decorator
```Python
from pyTooling.Decorators import export
@export
class MyClass:
pass
```
### `CallByRefIntParam`
```Python
from pyTooling.CallByRef import CallByRefIntParam
# define a call-by-reference parameter for integer values
myInt = CallByRefIntParam(3)
# a function using a call-by-reference parameter
def func(param: CallByRefIntParam):
param <<= param * 4
# call the function and pass the wrapper object
func(myInt)
print(myInt.Value)
```
## Contributors
* [Patrick Lehmann](https://GitHub.com/Paebbels) (Maintainer)
* [Sven Köhler](https://GitHub.com/skoehler)
* [Unai Martinez-Corral](https://github.com/umarcor)
* [and more...](https://GitHub.com/pyTooling/pyTooling/graphs/contributors)
## License
This Python package (source code) licensed under [Apache License 2.0](LICENSE.md).
The accompanying documentation is licensed under [Creative Commons - Attribution 4.0 (CC-BY 4.0)](doc/Doc-License.rst).
-------------------------
SPDX-License-Identifier: Apache-2.0
Raw data
{
"_id": null,
"home_page": "https://GitHub.com/pyTooling/pyTooling",
"name": "pyTooling",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "abstract, argparse, attributes, bfs, cli, console, data structure, decorators, dfs, exceptions, generators, generic library, generic path, graph, installation, iterators, licensing, message logging, meta-classes, overloading, override, packaging, path, platform, setuptools, shell, singleton, slots, terminal, text user interface, stopwatch, tree, TUI, url, versioning, wheel",
"author": "Patrick Lehmann",
"author_email": "Paebbels@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/44/88/22922827ef42e2defcf7e20a57ecf01f16b6f53dadc54a0c6ff70b70aacd/pytooling-8.0.3.tar.gz",
"platform": null,
"description": "[![Sourcecode on GitHub](https://img.shields.io/badge/pyTooling-pyTooling-63bf7f.svg?longCache=true&style=flat-square&longCache=true&logo=GitHub)](https://GitHub.com/pyTooling/pyTooling)\n[![Sourcecode License](https://img.shields.io/pypi/l/pyTooling?longCache=true&style=flat-square&logo=Apache&label=code)](LICENSE.md)\n[![Documentation](https://img.shields.io/website?longCache=true&style=flat-square&label=pyTooling.github.io%2FpyTooling&logo=GitHub&logoColor=fff&up_color=blueviolet&up_message=Read%20now%20%E2%9E%9A&url=https%3A%2F%2FpyTooling.github.io%2FpyTooling%2Findex.html)](https://pyTooling.github.io/pyTooling/)\n[![Documentation License](https://img.shields.io/badge/doc-CC--BY%204.0-green?longCache=true&style=flat-square&logo=CreativeCommons&logoColor=fff)](LICENSE.md) \n[![PyPI](https://img.shields.io/pypi/v/pyTooling?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)](https://pypi.org/project/pyTooling/)\n![PyPI - Status](https://img.shields.io/pypi/status/pyTooling?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pyTooling?longCache=true&style=flat-square&logo=PyPI&logoColor=FBE072) \n[![GitHub Workflow - Build and Test Status](https://img.shields.io/github/actions/workflow/status/pyTooling/pyTooling/Pipeline.yml?branch=main&longCache=true&style=flat-square&label=Build%20and%20test&logo=GitHub%20Actions&logoColor=FFFFFF)](https://GitHub.com/pyTooling/pyTooling/actions/workflows/Pipeline.yml)\n[![Libraries.io status for latest release](https://img.shields.io/librariesio/release/pypi/pyTooling?longCache=true&style=flat-square&logo=Libraries.io&logoColor=fff)](https://libraries.io/github/pyTooling/pyTooling)\n[![Codacy - Quality](https://img.shields.io/codacy/grade/8dc5205ba8b24e008f2287759096e181?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/pyTooling/pyTooling)\n[![Codacy - Coverage](https://img.shields.io/codacy/coverage/8dc5205ba8b24e008f2287759096e181?longCache=true&style=flat-square&logo=Codacy)](https://www.codacy.com/gh/pyTooling/pyTooling)\n[![Codecov - Branch Coverage](https://img.shields.io/codecov/c/github/pyTooling/pyTooling?longCache=true&style=flat-square&logo=Codecov)](https://codecov.io/gh/pyTooling/pyTooling)\n\n![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/pyTooling/pyTooling/Pipeline.yml?branch=main)\n\n<!--\n[![Gitter](https://img.shields.io/badge/chat-on%20gitter-4db797.svg?longCache=true&style=flat-square&logo=gitter&logoColor=e8ecef)](https://gitter.im/hdl/community)\n[![Dependent repos (via libraries.io)](https://img.shields.io/librariesio/dependent-repos/pypi/pyTooling?longCache=true&style=flat-square&logo=GitHub)](https://github.com/pyTooling/pyTooling/network/dependents)\n[![Libraries.io SourceRank](https://img.shields.io/librariesio/sourcerank/pypi/pyTooling)](https://libraries.io/github/pyTooling/pyTooling/sourcerank)\n-->\n\n# pyTooling\n\n**pyTooling** is a powerful collection of arbitrary useful abstract data models, missing classes, decorators, a new\nperformance boosting meta-class and enhanced exceptions. It also provides lots of helper functions e.g. to ease the\nhandling of package descriptions or to unify multiple existing APIs into a single API.\n\nIt's useful - if not even essential - for **any** Python-base project independent if it's a library, framework, CLI tool\nor just a \"script\".\n\nIn addition, pyTooling provides a collection of [CI job templates for GitHub Actions](https://github.com/pyTooling/Actions).\nThis drastically simplifies GHA-based CI pipelines for Python projects.\n\n## Package Details\n\n### Attributes\n\nThe [pyTooling.Attributes] module offers the base implementation of *.NET-like attributes* realized with Python\ndecorators. The annotated and declarative data is stored as instances of Attribute classes in an additional field per\nclass, method or function.\n\nThe annotation syntax (decorator syntax) allows users to attach any structured data to classes, methods or functions. In\nmany cases, a user will derive a custom attribute from Attribute and override the __init__ method, so user-defined\nparameters can be accepted when the attribute is constructed.\n\nLater, classes, methods or functions can be searched for by querying the attribute class for attribute instance usage\nlocations (see example to the right). Another option for class and method attributes is declaring a classes using\npyTooling\u2019s `ExtendedType` meta-class. Here the class itself offers helper methods for discovering annotated methods.\n\nA `SimpleAttribute` class is offered accepting any positional and keyword parameters. In a more advanced use case, users\nare encouraged to derive their own attribute class hierarchy from `Attribute`.\n\n\n#### Use Cases\n\nIn general all classes, methods and functions can be annotated with additional meta-data. It depends on the application,\nframework or library to decide if annotations should be applied imperatively as regular code or declaratively as\nattributes via Python decorators.\n\n**With this in mind, the following use-cases and ideas can be derived:**\n\n* Describe a command line argument parser (like ArgParse) in a declarative form. |br|\n See [pyTooling.Attributes.ArgParse Package and Examples](https://pytooling.github.io/pyTooling/Attributes/ArgParse.html)\n* Mark nested classes, so later when the outer class gets instantiated, these nested classes are indexed or\n automatically registered. \n See [CLIAbstraction](https://pytooling.github.io/pyTooling/CLIAbstraction/index.html) → [CLIABS/CLIArgument]\n* Mark methods in a class as test cases and classes as test suites, so test cases and suites are not identified based on\n a magic method name. \n *Investigation ongoing / planned feature.*\n\n\n#### Using `SimpleAttribute`\n\n````Python\nfrom pyTooling.Attributes import SimpleAttribute\n\n@SimpleAttribute(kind=\"testsuite\")\nclass MyClass:\n @SimpleAttribute(kind=\"testcase\", id=1, description=\"Test and operator\")\n def test_and(self):\n ...\n\n @SimpleAttribute(kind=\"testcase\", id=2, description=\"Test xor operator\")\n def test_xor(self):\n ...\n````\n\n\n### CLI Abstraction\n\n[pyTooling.CLIAbstraction] offers an abstraction layer for command line programs, so they can be used easily in Python.\nThere is no need for manually assembling parameter lists or considering the order of parameters. All parameters like\n`-v` or `--value=42` are described as [CommandLineArgument] instances on a [Program] class. Each argument class like\n[ShortFlag] or [PathArgument] knows about the correct formatting pattern, character escaping, and if needed about\nnecessary type conversions. A program instance can be converted to an argument list suitable for [subprocess.Popen].\n\nWhile a user-defined command line program abstraction derived from [Program] only\ntakes care of maintaining and assembling parameter lists, a more advanced base-class, called [Executable],\nis offered with embedded [subprocess.Popen] behavior.\n\n#### Design Goals\n\n* Offer access to CLI programs as Python classes.\n* Abstract CLI arguments (a.k.a. parameter, option, flag, ...) as members on such a Python class.\n* Abstract differences in operating systems like argument pattern (POSIX: `-h` vs. Windows: `/h`), path delimiter\n signs (POSIX: `/` vs. Windows: `\\`) or executable names.\n* Derive program variants from existing programs.\n* Assemble parameters as list for handover to [subprocess.Popen] with proper escaping and quoting.\n* Launch a program with :class:[subprocess.Popen] and hide the complexity of Popen.\n* Get a generator object for line-by-line output reading to enable postprocessing of outputs.\n\n\n### Common Helper Functions\n\nThis is a set of useful [helper functions](https://pytooling.github.io/pyTooling/Common/index.html#common-helperfunctions):\n\n* [getsizeof](https://pytooling.github.io/pyTooling/Common/index.html#getsizeof) calculates the \"real\" size of a data structure.\n* [isnestedclass](https://pytooling.github.io/pyTooling/Common/index.html#isnestedclass) checks if a class is nested inside another class.\n* [firstKey](https://pytooling.github.io/pyTooling/Common/index.html#firstkey), [firstValue](https://pytooling.github.io/pyTooling/Common/index.html#firstvalue), [firstPair](https://pytooling.github.io/pyTooling/Common/index.html#firstitem) get the firstItem key/value/item from an ordered dictionary.\n* [mergedicts](https://pytooling.github.io/pyTooling/Common/index.html#mergedicts) merges multiple dictionaries into a new dictionary.\n* [zipdicts](https://pytooling.github.io/pyTooling/Common/index.html#zipdicts) iterate multiple dictionaries simultaneously.\n\n\n### Common Classes\n\n* [Call-by-reference parameters](https://pytooling.github.io/pyTooling/Common/CallByRef.html): Python doesn't provide\n *call-by-reference parameters* for simple types. \n This behavior can be emulated with classes provided by the `pyTooling.CallByRef` module.\n* [Unified license names](https://pytooling.github.io/pyTooling/Common/Licensing.html): Setuptools, PyPI, and others\n have a varying understanding of license names. \n The `pyTooling.Licensing` module provides *unified license names* as well as license name mappings or translations.\n* [Unified platform and environment description](https://pytooling.github.io/pyTooling/Common/Platform.html): Python has\n many ways in figuring out the current platform using APIs from `sys`, `platform`, `os`, \u2026. Unfortunately, none of the\n provided standard APIs offers a comprehensive answer. pyTooling provides a `CurrentPlatform` singleton summarizing\n multiple platform APIs into a single class instance.\n* [Representations of version numbers](https://pytooling.github.io/pyTooling/Common/Versioning.html): While Python\n itself has a good versioning schema, there are no classes provided to abstract version numbers. pyTooling provides\n such representations following semantic versioning (SemVer) and calendar versioning (CalVer) schemes. It's provided by \n the `pyTooling.Versioning` module.\n\n### Configuration\n\nVarious file formats suitable for configuration information share the same features supporting: key-value pairs\n(dictionaries), sequences (lists), and simple types like string, integer and float. pyTooling provides an\n[abstract configuration file data model](https://pytooling.github.io/pyTooling/Configuration/index.html) supporting\nthese features. Moreover, concrete [configuration file format reader](https://pytooling.github.io/pyTooling/Configuration/FileFormats.html)\nimplementations are provided as well.\n\n* [JSON configuration reader](https://pytooling.github.io/pyTooling/Configuration/JSON.html) for the JSON file format.\n* [TOML configuration reader](https://pytooling.github.io/pyTooling/Configuration/TOML.html) → To be implemented.\n* [YAML configuration reader](https://pytooling.github.io/pyTooling/Configuration/YAML.html) for the YAML file format.\n\n\n### Data Structures\n\npyTooling also provides [fast and powerful data structures](https://pytooling.github.io/pyTooling/DataStructures/index.html)\noffering object-oriented APIs:\n\n* [Graph data structure](https://pytooling.github.io/pyTooling/DataStructures/Graph.html) \n → A directed graph implementation using a `Vertex` and an `Edge` class.\n* [Path data structure](https://pytooling.github.io/pyTooling/DataStructures/Path/index.html) \n → To be documented.\n* [Finite State Machine data structure](https://pytooling.github.io/pyTooling/DataStructures/StateMachine.html) \n → A data model for state machines using a `State` and a `Transition` class.\n* [Tree data structure](https://pytooling.github.io/pyTooling/DataStructures/Tree.html) \n → A fast and simple implementation using a single `Node` class.\n\n\n### Decorators\n\n* [Abstract Methods](https://pytooling.github.io/pyTooling/MetaClasses.html#meta-abstract)\n * Methods marked with `abstractmethod` are abstract and need to be overwritten in a derived class. \n An *abstract method* might be called from the overwriting method.\n * Methods marked with `mustoverride` are abstract and need to be overridden in a derived class. \n It's not allowed to call a *mustoverride method*.\n* [Documentation](https://pytooling.github.io/pyTooling/Decorators.html#deco-documentation)\n * Copy the doc-string from given base-class via `InheritDocString`.\n* [Visibility](https://pytooling.github.io/pyTooling/Decorators.html#deco-visibility)\n * Register the given function or class as publicly accessible in a module via `export`.\n* [Documentation](https://pyTooling.GitHub.io/pyTooling/Decorators.html#documentation)\n * [`@InheritDocString`](https://pyTooling.GitHub.io/pyTooling/Decorators.html#inheritdocstring) \n → Copy the doc-string from given base-class.\n* [Visibility](https://pyTooling.GitHub.io/pyTooling/Decorators.html#visibility)\n * [`@export`](https://pyTooling.GitHub.io/pyTooling/Decorators.html#export) \n → Register the given function or class as publicly accessible in a module.\n\n\n### Exceptions\n\n* [EnvironmentException](https://pyTooling.GitHub.io/pyTooling/Exceptions.html#environmentexception) \n ... is raised when an expected environment variable is missing.\n* [PlatformNotSupportedException](https://pyTooling.GitHub.io/pyTooling/Exceptions.html#platformnotsupportedexception) \n ... is raise if the platform is not supported.\n* [NotConfiguredException](https://pyTooling.GitHub.io/pyTooling/Exceptions.html#notconfiguredexception) \n ... is raise if the requested setting is not configured.\n\n\n### Meta-Classes\n\npyTooling provides an [enhanced meta-class](https://pytooling.github.io/pyTooling/MetaClasses.html) called\n`ExtendedType`. This meta-classes allows to implement\n[abstract methods](https://pytooling.github.io/pyTooling/MetaClasses.html#abstract-method),\n[singletons](https://pytooling.github.io/pyTooling/MetaClasses.html#singleton),\n[slotted types](https://pytooling.github.io/pyTooling/MetaClasses.html#slotted-type) and combinations thereof.\n\n`class MyClass(metaclass=ExtendedType):`\n A class definition using that meta-class can implement\n [abstract methods](https://pytooling.github.io/pyTooling/MetaClasses.html#abstract-method) using decorators\n `@abstractmethod` or `@mustoverride`.\n\n`class MyClass(metaclass=ExtendedType, singleton=True):`\n A class defined with enabled [singleton](https://pytooling.github.io/pyTooling/MetaClasses.html#singleton) behavior\n allows only a single instance of that class to exist. If another instance is going to be created, a previously cached\n instance of that class will be returned.\n\n`class MyClass(metaclass=ExtendedType, slots=True):`\n A class defined with enabled [slots](https://pytooling.github.io/pyTooling/MetaClasses.html#slotted-type) behavior\n stores instance fields in slots. The meta-class, translates all type-annotated fields in a class definition into\n slots. Slots allow a more efficient field storage and access compared to dynamically stored and accessed fields hosted\n by `__dict__`. This improves the memory footprint as well as the field access performance of all class instances. This\n behavior is automatically inherited to all derived classes.\n\n`class MyClass(ObjectWithSlots):`\n A class definition deriving from `ObjectWithSlots` will bring the slotted type behavior to that class and all derived\n classes.\n\n\n### Packaging\n\nA set of helper functions to describe a Python package for setuptools.\n\n* Helper Functions:\n * `loadReadmeFile` \n Load a `README.md` file from disk and provide the content as long description for setuptools.\n * `loadRequirementsFile` \n Load a `requirements.txt` file from disk and provide the content for setuptools.\n * `extractVersionInformation` \n Extract version information from Python source files and provide the data to setuptools.\n* Package Descriptions\n * `DescribePythonPackage` \n tbd\n * `DescribePythonPackageHostedOnGitHub` \n tbd\n\n\n### Terminal\n\nA set of helpers to implement a text user interface (TUI) in a terminal.\n\n#### Features\n\n* Colored command line outputs based on `colorama`.\n* Message classification in `fatal`, `error`, `warning`, `normal`, `quiet`, ...\n* Get information like terminal dimensions from underlying terminal window.\n\n\n#### Simple Terminal Application\n\nThis is a minimal terminal application example which inherits from `LineTerminal`.\n\n```python\nfrom pyTooling.TerminalUI import TerminalApplication\n\nclass Application(TerminalApplication):\n def __init__(self) -> None:\n super().__init__()\n\n def run(self):\n self.WriteNormal(\"This is a simple application.\")\n self.WriteWarning(\"This is a warning message.\")\n self.WriteError(\"This is an error message.\")\n\n# entry point\nif __name__ == \"__main__\":\n Application.CheckPythonVersion((3, 6, 0))\n app = Application()\n app.run()\n app.Exit()\n```\n\n### Timer\n\n*tbd*\n\n## Examples\n\n### `@export` Decorator\n\n```Python\nfrom pyTooling.Decorators import export\n\n@export\nclass MyClass:\n pass\n```\n\n### `CallByRefIntParam`\n\n```Python\nfrom pyTooling.CallByRef import CallByRefIntParam\n\n# define a call-by-reference parameter for integer values\nmyInt = CallByRefIntParam(3)\n\n# a function using a call-by-reference parameter\ndef func(param: CallByRefIntParam):\n param <<= param * 4\n\n# call the function and pass the wrapper object\nfunc(myInt)\n\nprint(myInt.Value)\n```\n\n\n## Contributors\n\n* [Patrick Lehmann](https://GitHub.com/Paebbels) (Maintainer)\n* [Sven K\u00f6hler](https://GitHub.com/skoehler)\n* [Unai Martinez-Corral](https://github.com/umarcor)\n* [and more...](https://GitHub.com/pyTooling/pyTooling/graphs/contributors)\n\n\n## License\n\nThis Python package (source code) licensed under [Apache License 2.0](LICENSE.md). \nThe accompanying documentation is licensed under [Creative Commons - Attribution 4.0 (CC-BY 4.0)](doc/Doc-License.rst).\n\n\n-------------------------\n\nSPDX-License-Identifier: Apache-2.0\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "pyTooling is a powerful collection of arbitrary useful classes, decorators, meta-classes and exceptions.",
"version": "8.0.3",
"project_urls": {
"Documentation": "https://pyTooling.GitHub.io/pyTooling",
"Homepage": "https://GitHub.com/pyTooling/pyTooling",
"Issue Tracker": "https://GitHub.com/pyTooling/pyTooling/issues",
"Source Code": "https://GitHub.com/pyTooling/pyTooling"
},
"split_keywords": [
"abstract",
" argparse",
" attributes",
" bfs",
" cli",
" console",
" data structure",
" decorators",
" dfs",
" exceptions",
" generators",
" generic library",
" generic path",
" graph",
" installation",
" iterators",
" licensing",
" message logging",
" meta-classes",
" overloading",
" override",
" packaging",
" path",
" platform",
" setuptools",
" shell",
" singleton",
" slots",
" terminal",
" text user interface",
" stopwatch",
" tree",
" tui",
" url",
" versioning",
" wheel"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1a9d5ae7e07279ca690e4964471c23a3b03b60526e1b64b0d230b2993ad9e23d",
"md5": "a0d9877fa1d32e08c40a7a6cf7557ecb",
"sha256": "91a6f3c5016e40c084c34a1c0f4a96175814737aec4499b3692542a363f81fa3"
},
"downloads": -1,
"filename": "pyTooling-8.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a0d9877fa1d32e08c40a7a6cf7557ecb",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 157246,
"upload_time": "2024-11-17T17:05:23",
"upload_time_iso_8601": "2024-11-17T17:05:23.515881Z",
"url": "https://files.pythonhosted.org/packages/1a/9d/5ae7e07279ca690e4964471c23a3b03b60526e1b64b0d230b2993ad9e23d/pyTooling-8.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "448822922827ef42e2defcf7e20a57ecf01f16b6f53dadc54a0c6ff70b70aacd",
"md5": "7618f030dc8f7d8bfe0d4c32f2fc62f3",
"sha256": "b711d2f6003f4e28df6eacbe2b192fefdc951a760d68f0c46cd07fcfd3bfe35a"
},
"downloads": -1,
"filename": "pytooling-8.0.3.tar.gz",
"has_sig": false,
"md5_digest": "7618f030dc8f7d8bfe0d4c32f2fc62f3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 121760,
"upload_time": "2024-11-17T17:05:21",
"upload_time_iso_8601": "2024-11-17T17:05:21.075307Z",
"url": "https://files.pythonhosted.org/packages/44/88/22922827ef42e2defcf7e20a57ecf01f16b6f53dadc54a0c6ff70b70aacd/pytooling-8.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-17 17:05:21",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "pytooling"
}