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

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.3.0.tar.gz (19.3 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.3.0-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cflowpy-0.3.0.tar.gz
  • Upload date:
  • Size: 19.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.3 cpython/3.13.5 HTTPX/0.28.1

File hashes

Hashes for cflowpy-0.3.0.tar.gz
Algorithm Hash digest
SHA256 6364255f3706f570016c6d1d3456657455b63ecd47b1d3ce3edccfe02792351e
MD5 71f4f5183c4fcfe355f78daa72ca5b76
BLAKE2b-256 69e58f2abd9a320cb1002d2d7656cc74616986476535b34f5bb185087bfa9916

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cflowpy-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.3 cpython/3.13.5 HTTPX/0.28.1

File hashes

Hashes for cflowpy-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 773d801902dafd85249731fc0f26e0e448163191658acdd38ec4855a69a1528f
MD5 416813bd4360f4a8d18152b2ea2165b8
BLAKE2b-256 8c86b57b575f82e9bf8ebc8a451d8fc6c39a7ae9798de0953ec79f2707b3a524

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