Skip to main content

Control flow constructs for python.

Project description

cflux - Control Flow Objects for Python

Features

Option Type

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

    from cflux 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.")
    

Result Type

  • Represent success or error values.

    from cflux 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 cflux 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 cflux 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 cflux 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

cflux-0.3.0.tar.gz (19.3 kB view details)

Uploaded Source

File details

Details for the file cflux-0.3.0.tar.gz.

File metadata

  • Download URL: cflux-0.3.0.tar.gz
  • Upload date:
  • Size: 19.3 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 cflux-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b2dc3ce78e31f18d657e41d564bc7e127cb994a636b453129abb33bc64fe4e7c
MD5 5b17c44e609f61f051f08131bc03777d
BLAKE2b-256 5801defcf1beb4aec9d15971e63dbed41926cc6a8049268c6410c6c2d866abb7

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