Skip to main content

A collection of utlities that can be used in other projects.

Project description

from tramp.as_completed import AsCompleted

Tramp

A collection of useful utilities that can be used in any project.

Installation

pip install tramp

Annotations

A utility for evaluating string annotations with support for forward references when a name cannot be evaluated. Forward references can be evaluated later by calling the forward reference's evaluate method. This is a similar API to PEP 649, although it is not fully compatible and only emulates the behavior of Format.FORWARDREF. Certain things are not possible (at least not without some serious hacking) such as using ForwardRef instances as that would break many annotation types from the typing module. To help with this limitation the tramp.annotations.ForwardRefMeta type overrides the isinstance check to return True when Tramp's version of the ForwardRef class is used in an instance check (isinstance or a match/case). The goal is to implement the most essential parts of the PEP to begin reaping the benefits of forward references now with the least necessary refactoring later.

On Python 3.14 Tramp falls through to the PEP 649 implementation.

from tramp.annotations import get_annotations


class Foo:
    bar: "Bar"


annotations = get_annotations(Foo)  # {'bar': <ForwardRef 'Bar'>}


class Bar:
    pass


annotations["bar"].evaluate()  # <class '__main__.Bar'>

It supports generic types, metadata, function calls/class instantiation, etc.

class Foo:
    bar: "list[int]"
    baz: "Callable[[int], str]"
    qux: "Annotated[int, Bar('baz')]"

As Completed

The AsCompleted type is a wrapper around asyncio.as_completed that adds an async iterator over the results from each task. This simplifies iterating over tasks, eliminating the need to await the next result.

from tramp.as_completed import AsCompleted
...
tasks = [...]
async for result in AsCompleted(*tasks):
    ...

Additionally it is possible to use AsCompleted in the same way that as_completed operates.

for next_result in AsCompleted(*tasks):
    result = await next_result

Async Batch Iterators

The AsyncBatchIterator type is an async iterator that yields results one at a time from batches. It takes a coroutine that returns batches at a batch index. The coroutine can return either a Iterable or an AsyncIterable. If the coroutine returns None or an empty batch, the batched iterator stops.

async def get_batch(batch_index: int) -> Iterable[int] | None:
    if batch_index > 1:
        return
    
    return range(batch_index * 2, (batch_index + 1) * 2)
    
async def main():
    async for result in AsyncBatchIterator(get_batch):
        print(result)

Containers

A container acts a reference to a changeable value.

from tramp.containers import Container

container = Container[int](0)
container.set(1)

print(container.value)  # 1

An empty container can also be created. Attempting to access the value raises a ValueError. The error can be avoided by using the value_or method or by checking the never_set boolean property.

Modules

Helper functions for working with modules

from tramp import modules
from typing import Any

ns: dict[str, Any] = modules.get_module_namespace("some_module")

Optionals

An optional type that can be used with match statements.

from tramp.optionals import Optional

def foo(x: int) -> Optional[int]:
    if x > 0:
        return Optional.Some(x)
        
    return Optional.Nothing()

result = foo(1)
print(result.value) # 1

result = foo(-1)
print(result.value) # Raises an exception

result = foo(-1)
print(result.value_or(0)) # 0

...

match foo(1):
    case Optional.Some(x):
        print(x)

    case Optional.Nothing():
        print("Nothing")

# Output: 1

match foo(-1):
    case Optional.Some(x):
        print(x)

    case Optional.Nothing():
        print("Nothing")

# Output: Nothing

Protected Strings

A protected string type that can be used to store sensitive information. The string is redacted when rendered into a string. The value can be accessed using the value property.

from tramp.protected_strings import ProtectedString

password = ProtectedString("password", name="password")
print(password)  # <Redacted>

print(f"Password: {password}")  # Password: <Redacted>
print(f"Password: {password.value}")  # Password: password
print(f"Password: {password:***}")  # Password: ***
print(f"Password: {password:***$password}")  # Password: password
print(f"Password: {password:$password}")  # Password: password

ProtectedStrings can be combined with other strings to create a ProtectedStringBuilder which can combine and format multiple protected strings with each other and normal strings.

from tramp.protected_strings import ProtectedString

foo = ProtectedString("Hello", name="foo")
bar = ProtectedString("World", name="bar")
builder = foo + " " + bar + "!!!"
print(f"{builder}")  # <Redacted Foo> <Redacted Bar>!!!
print(f"{builder:***}")  # *** ***!!!
print(f"{builder:$foo}")  # Hello <Redacted Bar>!!!
print(f"{builder:***$foo}")  # Hello ***!!!
print(f"{builder:$foo,bar}")  # Hello World!!!
print(f"{builder:***$foo,bar}")  # Hello World!!!

Results

A result type that can be used with match statements. Works the same as Optionals with an added error property.

from tramp.results import Result

with Result.build() as result:
    result.value = 1

print(result.value) # 1
print(result.error) # None

with Result.build() as result:
    raise Execption("Error")

print(result.value) # Raises an exception
print(result.value_or(0)) # 0
print(result.error) # Exception("Error")

Sentinel

A sentinel value that can be used to represent a unique value. Useful for creating NotSet types. Instantiating any sentinel type will always return the same singleton instance of that type allowing for is checks.

from tramp.sentinels import sentinel

NotSet = sentinel("NotSet")


def foo(x: int | NotSet = NotSet()) -> int:
    if x is NotSet():
        return 0

    return x

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tramp-0.1.17.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tramp-0.1.17-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file tramp-0.1.17.tar.gz.

File metadata

  • Download URL: tramp-0.1.17.tar.gz
  • Upload date:
  • Size: 10.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: poetry/1.8.4 CPython/3.12.7 Linux/6.5.0-1025-azure

File hashes

Hashes for tramp-0.1.17.tar.gz
Algorithm Hash digest
SHA256 2e3dc7f7306234759fd3d7d62715b210501e93d7d5e04a1a6aed68c138f8b076
MD5 eecc8fc92fa1b309cc8819f72acdf4d1
BLAKE2b-256 4145ecca5aa652c74a71c71e8d99768af5c967b777b01b2c76c9e1a50fd07549

See more details on using hashes here.

File details

Details for the file tramp-0.1.17-py3-none-any.whl.

File metadata

  • Download URL: tramp-0.1.17-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: poetry/1.8.4 CPython/3.12.7 Linux/6.5.0-1025-azure

File hashes

Hashes for tramp-0.1.17-py3-none-any.whl
Algorithm Hash digest
SHA256 51a0a5de7174440d53686976298bf039f71fc0f84f759adc8416ef56d2af876d
MD5 1245fd52a0924e252fb9dcb0a337148d
BLAKE2b-256 9abf1bf52c8637729aa98785fb141f0c73f9f4830664142dbc873b31fba812f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page