Skip to main content

Seamlessly handle type conversion during operations in Python

Project description

๐ŸŒŠ TypeFlow

Because Life's Too Short for TypeError Exceptions!

Python Versions Version License
from typeflow import flow, TypeFlowContext

with TypeFlowContext():
    answer = flow(42) + " is the answer to everything"  # Works like magic! ๐Ÿช„
    print(answer)  # "42 is the answer to everything"
Output
42 is the answer to everything

What is TypeFlow?

TypeFlow is a Python package that makes type conversion seamless and painless. Say goodbye to those annoying TypeError: can only concatenate str (not "int") to str exceptions that haunt your dreams!

Why Do I Need This in My Life?

Ever tried to:

  • Add a number to a string?
  • Concatenate a list with text?
  • Do math with values from JSON or CSV files without checking types?

TypeFlow handles all these scenarios with grace, so you can focus on building cool stuff instead of writing repetitive type conversion code.

Why Use TypeFlow?

๐Ÿš€ Boost Development Speed

  • Write Less Code: No more manual type checking and conversion
  • Reduce Bugs: Eliminate an entire class of type-related errors
  • Faster Prototyping: Focus on features, not type compatibility

๐Ÿ›ก๏ธ Improve Code Quality

  • More Readable Code: Express your intent clearly without conversion noise
  • Easier Maintenance: Less code means less to maintain
  • Better Error Handling: Consistent approach to type conversion issues

๐Ÿ’ช Handle Real-World Challenges

  • Messy Input Data: Process API responses with inconsistent types
  • Form Data: Handle form submissions where all values are strings
  • CSV/JSON Imports: Process tabular data without type headaches
  • Database Results: Work with query results that might return mixed types
  • Configuration Files: Parse config values without type validation

๐ŸŽ“ Great for Learning

  • Perfect for Beginners: Remove frustrating type errors that discourage new Python programmers
  • Educational Tool: Learn about Python's type system in a forgiving environment
  • Teaching Aid: Explain type conversion without getting bogged down in details

TypeFlow strikes the perfect balance between Python's dynamic nature and the safety of strong typing. It respects the "principle of least surprise" while adding powerful capabilities to your code.

Installation

pip install typeflow

PyPI Version License Python Versions

TypeFlow Demo

current version:0.13.6

Quick Start Guide

TypeFlow offers multiple ways to handle type conversions based on your needs:

from typeflow import flow, TypeFlowContext, with_typeflow

# Method 1: Use flow() directly - the most explicit approach
result1 = flow(42) + " unicorns"
print(result1)  # "42 unicorns"

# Method 2: Use TypeFlowContext for a block of code
with TypeFlowContext():
    # Remember to wrap values with flow() inside the context
    num = flow(123)
    text = " in context"
    result2 = num + text
    print(result2)  # "123 in context"

# Method 3: Use decorator for functions
@with_typeflow
def make_sandwich(bread, fillings):
    # Arguments are auto-wrapped - no need for flow()
    return bread + fillings

print(make_sandwich("Wheat bread with ", 3))  # "Wheat bread with 3"
Output
42 unicorns
123 in context
Wheat bread with 3

๐Ÿงฐ API Reference

Core Functions

flow(value)

Wraps any value in a TypeFlow type for seamless operations. This is the foundation of TypeFlow.

num = flow(42)
text = flow("answer")
print(num + text)  # "42answer"

# Works with all major types
list_flow = flow([1, 2, 3])
print(list_flow + " items")  # "1, 2, 3 items"
Output
42answer
1, 2, 3 items

enable() and disable()

Controls TypeFlow globally - use with caution.

from typeflow import enable, disable

# Enable TypeFlow globally (affects new objects created after enabling)
enable()

# Create new variables using built-in constructors
new_int = int(42)
text = " answers"
print(new_int + text)  # "42 answers"

# Disable when done to restore normal Python behavior
disable()
Output
42 answers

Note: When using enable(), use the built-in constructors (int(), str(), etc.) to create values that can properly handle mixed operations.

Context Managers

TypeFlowContext(verbose=None, raise_errors=None)

Creates a safe playground where TypeFlow is active.

with TypeFlowContext(verbose=True):  # See what's happening under the hood
    # Use flow() to wrap existing values
    result = flow([1, 2, 3]) + " items in cart"
    print(result)

    # Or create new values with type constructors inside the context
    new_value = int(456)
    print(new_value + " is a new value")
Output
typeflow - INFO - Converting list to string for concatenation with string: [1, 2, 3] -> '1, 2, 3'
1, 2, 3 items in cart
typeflow - INFO - Converting int to string for concatenation with string: 456 -> '456'
456 is a new value

Decorators

@with_typeflow(verbose=None, raise_errors=None, auto_flow=True)

Makes functions automatically handle mixed types.

# Arguments are automatically wrapped with flow()
@with_typeflow
def calculate_total(quantity, price, coupon=0):
    # All arguments are pre-wrapped, so operations just work
    return "Total: $" + (quantity * price) - coupon

print(calculate_total(3, 9.99, 5))  # "Total: $24.97"

# For manual control, disable auto_flow
@with_typeflow(auto_flow=False)
def manual_calculate(a, b):
    # Here you need to use flow() manually
    return flow(a) * flow(b)

print(manual_calculate(5, "6"))  # Will convert "6" to a number and multiply
Output
Total: $24.97
30

Configuration

configure(verbose=None, raise_errors=None, log_level=None)

Customize TypeFlow's behavior to your liking.

from typeflow import configure, flow
import logging

# Set up verbose logging to see what TypeFlow is doing
configure(verbose=True, log_level=logging.INFO)

# Try a conversion that requires type handling
result = flow(42) + " magic beans"
print(result)

# Be strict and raise errors on conversion problems
configure(raise_errors=True)
Output
typeflow - INFO - Converting int to string for concatenation with string: 42 -> '42'
42 magic beans

Custom Converters

register_converter(target_type, source_type, converter_function)

Teach TypeFlow how to handle your custom classes.

from typeflow import register_converter, flow, TypeFlowContext

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# Register how to convert Person to string
register_converter('str', Person, lambda p: f"{p.name} ({p.age})")
register_converter('int', Person, lambda p: p.age)

with TypeFlowContext():
    person = Person("Alice", 30)
    # Now you can do string concatenation with a Person
    greeting = flow("Hello, ") + person  # "Hello, Alice (30)"
    print(greeting)

    # And numeric operations using the age
    age_in_months = flow(person) * 12  # 360
    print(f"Age in months: {age_in_months}")
Output
Hello, Alice (30)
Age in months: 360

Real-World Examples

Data Processing

from typeflow import flow

# Mixed data from a CSV file or API
user_data = [
    {"id": "1001", "visits": 5, "active": "true"},
    {"id": 1002, "visits": "12", "active": 1},
    {"id": 1003, "visits": None, "active": "false"}
]

# Process without worrying about types
def process_user(user):
    activity_score = flow(user["visits"]) * (1 if flow(user["active"]) else 0.5)
    return f"User {user['id']} has a score of {activity_score}"

for user in user_data:
    print(process_user(user))
Output
User 1001 has a score of 5.0
User 1002 has a score of 12.0
User 1003 has a score of 0.0

Form Input Processing

from typeflow import with_typeflow

# Input values from a web form
form_data = {
    "quantity": "3",
    "price": 24.99,
    "discount": "5",
    "is_member": "true"
}

@with_typeflow
def calculate_order(quantity, price, discount=0, is_member=False):
    subtotal = quantity * price
    member_discount = subtotal * 0.1 if is_member else 0
    return subtotal - discount - member_discount

total = calculate_order(
    form_data["quantity"],
    form_data["price"],
    form_data["discount"],
    form_data["is_member"]
)
print(f"Order total: ${total:.2f}")
Output
Order total: $62.47

Command-Line Interface

TypeFlow comes with a simple command-line interface:

# Show version information
typeflow --version

# Enable TypeFlow globally
typeflow --enable

# Enable with verbose mode
typeflow --enable --verbose

# Disable TypeFlow
typeflow --disable
Output
TypeFlow version 0.13.6

# When enabling:
TypeFlow has been enabled globally

# When disabling:
TypeFlow has been disabled globally

Limitations

  • Currently, TypeFlow works best when explicitly wrapping values with flow(). Global enable() works but requires creating new values using type constructors.
  • Due to Python's immutable built-in types, patching existing values directly isn't possible in all cases.
  • Performance impact is minimal for most operations, but may be noticeable in tight loops with many conversions.

Uploading to PyPI

If you've made improvements to TypeFlow and want to share them with the world, here's how to upload your package to PyPI:

1. Prepare your package

Make sure your package structure is correct:

TypeFlow/
โ”œโ”€โ”€ typeflow/
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ core.py
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ setup.py
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ LICENSE

2. Install build tools

pip install build twine

3. Build distribution packages

From the project root directory, run:

python -m build

This creates distribution packages in the dist/ directory.

4. Upload to PyPI

Test PyPI first (recommended)

python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*

Upload to production PyPI

python -m twine upload dist/*

You'll need to provide your PyPI username and password or API token.

5. Verify installation

# From test PyPI
pip install --index-url https://test.pypi.org/simple/ typeflow

# From production PyPI
pip install typeflow
Example Output
Uploading distributions to https://upload.pypi.org/legacy/
Uploading typeflow-0.13.6-py3-none-any.whl
100% โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” 21.3/21.3 kB โ€ข 00:00 โ€ข ?
Uploading typeflow-0.13.6.tar.gz
100% โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” 19.4/19.4 kB โ€ข 00:00 โ€ข ?

View at: https://pypi.org/project/typeflow/0.13.6/

Publishing with GitHub Actions

TypeFlow uses GitHub Actions for automated publishing to PyPI. To set up your own fork for publishing:

  1. Create a PyPI API token:

  2. Set up GitHub repository:

    • In your repository, go to Settings > Environments
    • Create a new environment named pypi
    • Add a secret called PYPI_API_TOKEN with your PyPI token value
  3. Set up PyPI Trusted Publisher:

    • In PyPI project settings, add a new "Trusted Publisher"
    • Configure with these values:
      • PyPI Project Name: typeflow
      • Owner: your GitHub username or organization name
      • Repository name: typeflow
      • Workflow name: publish.yml
      • Environment name: pypi
  4. Publish a new version:

    • Update version in setup.py
    • Create a new GitHub Release
    • The workflow will automatically publish to PyPI

This implements modern OIDC authentication between GitHub and PyPI, eliminating the need for long-lived API tokens.

Philosophy

TypeFlow follows the "batteries included" and "it should just work" philosophy of Python, tackling one of the few remaining pain points in Python's smooth developer experience.


Built with love

"In Python, we trust; with TypeFlow, we flow."

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

python_typeflow-0.13.6.tar.gz (19.5 kB view details)

Uploaded Source

Built Distribution

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

python_typeflow-0.13.6-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file python_typeflow-0.13.6.tar.gz.

File metadata

  • Download URL: python_typeflow-0.13.6.tar.gz
  • Upload date:
  • Size: 19.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for python_typeflow-0.13.6.tar.gz
Algorithm Hash digest
SHA256 02c9fd65bb9dc927bb156585c7dd5a8860b7f94ad336fb25e38ea1a99145236a
MD5 2408d2e1034069223a9d7d8b1e98ad8b
BLAKE2b-256 eab93e172111665f4157cb57c41d1d249423fb7083a07525379e62a351d219ce

See more details on using hashes here.

File details

Details for the file python_typeflow-0.13.6-py3-none-any.whl.

File metadata

File hashes

Hashes for python_typeflow-0.13.6-py3-none-any.whl
Algorithm Hash digest
SHA256 cf6827287900905bfa37c09513b9215eacb32fea6530601e5552452f1945b826
MD5 80a5db759ca15e4ff829a9fa36a13263
BLAKE2b-256 c9f940a9e8afd40d3e5b53b7618b624f5777e510c38bd159b2f4e23e7e3667c9

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