pyAttributes

.NET-like Attributes implemented as Python decorators.


Keywords
decorators, attributes, argparse, annotated-data, mixin, python-decorators, python3
License
Apache-2.0
Install
pip install pyAttributes==2.5.1

Documentation

Sourcecode on GitHub Sourcecode License GitHub tag (latest SemVer incl. pre-release) GitHub release (latest SemVer incl. including pre-releases) GitHub release date Dependents (via libraries.io)
GitHub Workflow - Build and Test Status Codacy - Quality Codacy - Coverage Codecov - Branch Coverage Libraries.io SourceRank
PyPI PyPI - Python Version PyPI - Status Libraries.io status for latest release Requires.io
Documentation License Documentation - Read Now!

pyAttributes

The Python package pyAttributes offers implementations of .NET-like attributes realized with Python decorators. The package also offers a mixin-class to ease using classes having annotated methods.

In addition, an ArgParseAttributes module is provided, which allows users to describe complex argparse command-line argument parser structures in a declarative way.

Attributes can create a complex class hierarchy. This helps in finding and filtering for annotated properties and user-defined data. These search operations can be called globally on the attribute classes or locally within an annotated class. Therefore the provided helper-mixin should be inherited.

Use Cases

Annotate properties and user-defined data to methods.

Derived use cases:

Planned implementations:

  • Annotate user-defined data to classes.
  • Describe test cases and test suits to get a cleaner syntax for Python's unit tests.

Technique

The annotated data is stored in an additional __dict__ entry for each annotated method. By default, the entry is called __pyattr__. Multiple attributes can be applied to the same method.

Creating new Attributes

Simple User-Defined Attribute

class SimpleAttribute(Attribute):
  pass

User-Defined Attribute with Data

class DataAttribute(Attribute):
  data: str = None

  def __init__(self, data:str):
    self.data = data

  @property
  def Data(self):
    return self.data

Applying Attributes to Methods

class ProgramWithHelper(AttributeHelperMixin):
  @SimpleAttribute()
  def Method_1(self):
    """This method is marked as simple."""

  @DataAttribute("hello world")
  def Method_2(self):
    """This method as annotated data."""

Finding Methods with Attributes

Finding Methods with Global Search

methods = SimpleAttribute.GetMethods()
for method, attributes in methods.items():
  print(method)
  for attribute in attributes:
    print("  ", attribute)

Finding Methods with Class-Wide Search

class ProgramWithHelper(AttributeHelperMixin):
  @SimpleAttribute()
  def Method_1(self):
    """This method is marked as simple."""

  @DataAttribute("hello world")
  def Method_2(self):
    """This method as annotated data."""
 
  def test_GetMethods(self):
    methods = self.GetMethods(filter=DataAttribute)
    for method, attributes in methods.items():
      print(method)
      for attribute in attributes:
        print("  ", attribute)

  def test_GetAttributes(self):
    attributes = self.GetAttributes(self.Method_1)
    for attribute in attributes:
      print("  ", attribute)

Contributors

License

This Python package (source code) licensed under Apache License 2.0.
The accompanying documentation is licensed under Creative Commons - Attribution 4.0 (CC-BY 4.0).


SPDX-License-Identifier: Apache-2.0