Skip to main content

Python with enforced static typing

Project description

nakprok - Python with Enforced Static Typing

Same Python syntax. Zero dynamic typing.

nakprok (นาคปรก) is a subset of Python that enforces static type annotations everywhere. It's not a new language, but a stricter runtime for the Python you already know.

Why the name? Nakprok is a depiction of the Buddha sheltered by the multi-headed serpent Nāga in Thai Buddhist art. Just as the Naga protected the Buddha, this project protects your code from untyped or mistyped logic.

🚀 Key Concepts

  1. Explicit is Better than Implicit: If a value's type can't be seen in the code, it shouldn't be there.
  2. Zero Runtime Overhead: Validation happens at the AST level before execution. Once validated, it runs as standard CPython.
  3. Ecosystem Compatibility: Works with all existing Python libraries and tools.
  4. No New Syntax: Uses standard Python 3.10+ type hinting syntax.

🛠️ Implemented Rules

nakprok currently enforces the following rules inside functions (and classes):

1. Function Signatures

  • All parameters must be typed: def add(a: int, b: int) is required.
  • Return types are mandatory: -> None or -> int must be specified.
  • Exceptions: self and cls parameters in methods are exempt.
  • Variadic arguments: *args: str and **kwargs: Any must also have annotations.

2. Variable Declarations

  • Strict Local Typing: Every local variable must be declared with a type.

    • x: int = 10 (Annotated assignment)
    • x: int followed by x = 10 (Declaration then assignment)
  • Re-assignment: Once a variable is typed in the current scope, it can be re-assigned without repeating the annotation.

    x: int = 10
    x = 20  # Valid
    

3. Control Flow

  • For Loops: Loop variables must be previously declared.

    i: int
    for i in range(10): ...
    
  • With Statements: Context manager variables must be previously declared.

    f: TextIO
    with open("file.txt") as f: ...
    
  • Match Case: Variable captures via as in match patterns must be pre-declared with a type annotation:

    val: int
    match data:
        case int() as val:
            print(val)
    

    Star patterns ([*rest]) follow the same rule:

    rest: list[int]
    match items:
        case [*rest]:
            print(rest)
    

    Type-only matches without binding (case int():) are always valid.

4. Global Constants

  • Immutability: UPPERCASE variables are treated as constants and are immutable everywhere. Once assigned a value, any attempt to re-assign or shadow them will result in an error.
  • Exemptions: UPPERCASE constants at the module level are exempt from strict typing by convention (e.g., MAX_SIZE = 100).

5. Prohibited Features

  • Lambdas: Blocked because Python provides no syntax for annotating their parameters or return types.
  • Untyped Unpacking: x, y = (1, 2) is blocked unless x and y were previously declared.

🔮 Future Roadmap

The project aims to become a complete "strict mode" for Python. Future plans include:

  1. Module-Level Enforcement: Extend strict typing to all module-level variables (not just UPPERCASE constants).
  2. Type-Safe Imports: Validate that imported names are used consistently with their types (integration with mypy or pyright stubs).
  3. Strict Class Attributes: Enforce that all class attributes are declared in the class body with types.
  4. Decorator Validation: Ensure decorators preserve type information and are themselves strictly typed.
  5. Linter Integration: A dedicated VS Code / PyCharm extension to show nakprok errors in real-time.

📦 Installation & Usage

Installation

pip install -e .

Usage

# Check and run (default)
nakprok file.py

# Check types only
nakprok check file.py

# Explict run
nakprok run file.py

Example: factorial.py

def factorial(n: int) -> int:
    if n <= 1:
        return 1
    return n * factorial(n - 1)

def main() -> None:
    result: int = factorial(5)
    print(f"5! = {result}")

if __name__ == "__main__":
    main()
$ nakprok factorial.py
5! = 120

🧪 Testing

We maintain a comprehensive test suite to ensure all rules are correctly enforced.

pytest tests/ -v

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

nakprok-0.2.0.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

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

nakprok-0.2.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file nakprok-0.2.0.tar.gz.

File metadata

  • Download URL: nakprok-0.2.0.tar.gz
  • Upload date:
  • Size: 7.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.3 CPython/3.14.3 Linux/6.19.11-200.fc43.x86_64

File hashes

Hashes for nakprok-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c035e28ac37807a12e60770b3df5dee58ee26709fb4509af35c4f9acc9c2f0c5
MD5 2832ffd4be48f0be9bd76f3829103307
BLAKE2b-256 f1c4a2e9f578c3da6d4b1c19e000f2263b563b2a8c130ac626b64a02efb69c3e

See more details on using hashes here.

File details

Details for the file nakprok-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: nakprok-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.3 CPython/3.14.3 Linux/6.19.11-200.fc43.x86_64

File hashes

Hashes for nakprok-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 18316dff78da958c430a315094a31e15d6a5c74d256981ce1c314a45c4c04283
MD5 b1d9cd65e0b7ccbc30d61c51ef5084fb
BLAKE2b-256 086bd7a8fc1ad6d9b91d3366ff5a98be3e92d7c99847f975c4bc4c05c5c0dba8

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