Skip to main content

Control flow constructs for python.

Project description

cflowpy - Control Flow Objects for Python

Features

Option Type

  • Represent optional values, freeing None to be a usable value.

    from cflowpy import Option, Some, Nothing
    val: Option[int] = Some(42)
    empty: Option[int] = Nothing()
    
  • Pattern Matching: Destructure option.

    match val:
        case Some(x):
            print(x)
        case Nothing():
            print("Empty")
    
  • Functional Methods: Transform inner values.

    val.map(lambda x: x * 2)  # Some(84)
    empty.map_or(lambda x: x * 2, 0)  # 0
    
  • Unwrapping: Extract inner value.

    x: int = val.unwrap()  # 42
    empty.unwrap()  # raises UnpackingException
    y: int = empty.unwrap_or(0)  # 0
    
  • For Loop unpacking: Run code in a block if the value is some, using for loops

    some: Option[str] = Some("a")
    nothing: Option[str] = Nothing()
    
    for value in some:
        print("This messag will be printed.")
    
    for value in nothing:
        print("This message will not be printed.")
    
  • Default Value Sentinel (nothing): Define default parameter values without type checker warnings.

    from cflowpy import Option, nothing
    
    def func(val: Option[int] = nothing):
        pass
    

Result Type

  • Represent success or error values.

    from cflowpy import Result, Ok, Err
    success: Result[int, str] = Ok(42)
    failure: Result[int, str] = Err("Error message")
    
  • Pattern Matching: Destructure result.

    match success:
        case Ok(x):
            print(x)
        case Err(err):
            print(err)
    
  • Functional Methods: Transform inner values.

    success.map(lambda x: x * 2)  # Ok(84)
    failure.map_err(lambda err: f"Error: {err}")  # Err("Error: Error message")
    
  • Unwrapping: Extract inner value.

    x: int = success.unwrap()  # 42
    failure.unwrap()  # raises UnpackingException
    failure.unwrap_or_raise()  # raises wrapped exception
    y: int = failure.unwrap_or(0)  # 0
    
  • For Loop unpacking: Run code in a block if the value is ok, using for loops.

    success: Result[str, int] = Ok("a")
    failure: Result[str, int] = Err(1)
    
    for value in success:
        print("This message will be printed.")
    
    for value in failure:
        print("This message will not be printed.")
    

Architecture

  • All classes / functions are re-exported to the packages __init__.py

--> There is only one place to import everything

from cflowpy import Option, Unit
  • The actual definitions are done in private modules. F.e _options.py

Development Environment

Dependencies

Environment Setup

On every session start, call:

source env
  • Adds relative directory scripts/ to PATH
  • Calls scripts/setup and checks for system dependecies
  • Creates .venv and syncs dependencies

On the first startup, this should setup the dev environment completely. Otherwise you can call scripts/setup manually.

Development Tools

  • Linting: ruff
  • Type-checking: basedpyright

Internal Dev Commands

Some Commands that might be useful:

  • style-check: Runs linter and type checker
  • style-format: Runs formatter
  • test-all: Run the tests.
    • The tests contain calls to other typecheckers. This can be skipped by passing the --skip-typing flag.
    • Use the test-all --help command for more information.

Supported Type Checker

While ty is mainly used during the development, the tests also run additional typecheckers to see how the type-inference works.
The following table contains a summary of the support. Some type checkerr have additional information in a subsection below.

type checker is tested for functionality
ty Missing feature in ty for match value unpacking.
pyrefly Failing the exhaustiveness checks in the match statement.
pyright ✓ + Non-speced feature: Complain on Nothing in a with statement.
basedpyright ? + Non-speced feature: Complain on Nothing in a with statement.
mypy ?

ty

  • ty =< 0.0.16 currently does not infer the type of an unpacked value in a match statement
from typing import assert_type, assert_never
from cflowpy import Option

# snip...: some code that sets some_value

some_value: Option[int]

match some_value:
    case Some(unpacked_value):
        # ty will complain here
        # its infered type is @Todo
        assert_type(unpacked_value, int)
    case Nothing():
        pass
    case _:
        assert_never(some_value)

There is a test that will test this case. It will currently always fail.
A workaround requires the typing.cast function. Simply adding the typehint unpacked_value: int will not work.

from typing import assert_type, assert_never, cast
from cflowpy import Option

# snip...: some code that sets some_value

some_value: Option[int]

match some_value:
    case Some(unpacked_value):
        unpacked_value = cast(int, unpacked_value)
        assert_type(unpacked_value, int)
    case Nothing():
        pass
    case _:
        assert_never(some_value)

This has the drawback of not giving a typeerror when the some_value ever switches in type.

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

cflowpy-0.4.0.tar.gz (19.9 kB view details)

Uploaded Source

Built Distribution

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

cflowpy-0.4.0-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

Details for the file cflowpy-0.4.0.tar.gz.

File metadata

  • Download URL: cflowpy-0.4.0.tar.gz
  • Upload date:
  • Size: 19.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.17.0 {"ci":null,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Pop!_OS","version":"24.04"},"implementation":{"name":"CPython","version":"3.13.5"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.16 11 Feb 2025","python":"3.13.5","system":{"name":"Linux","release":"7.0.11-76070011-generic"}} HTTPX2/2.5.0

File hashes

Hashes for cflowpy-0.4.0.tar.gz
Algorithm Hash digest
SHA256 ff23fefd36ef5c6fc3f1436f4aa240df40cc4ccc4e47bc1a90fb6251420b134e
MD5 8d8e61f6b12ad017cc8b9ac3280c2715
BLAKE2b-256 58a2e3c64f1e8a2515df331cea83eedd79c21de4c2812a666878193fcfacd559

See more details on using hashes here.

File details

Details for the file cflowpy-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: cflowpy-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 20.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.17.0 {"ci":null,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Pop!_OS","version":"24.04"},"implementation":{"name":"CPython","version":"3.13.5"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.16 11 Feb 2025","python":"3.13.5","system":{"name":"Linux","release":"7.0.11-76070011-generic"}} HTTPX2/2.5.0

File hashes

Hashes for cflowpy-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 43df21eda32edb543fe8cafdb42dd06156da7c6f76439881c841af450e0e8139
MD5 b91bd0da6c004a59f91a6a755e82be4c
BLAKE2b-256 41678d956b88bfe0c187409e0bbe1b96d5efb53862ff4041e9909e11b62291cd

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