Skip to content

Conversation

dbrattli
Copy link
Collaborator

@dbrattli dbrattli commented Aug 5, 2025

Overview

Introduce a new [<Decorate>] attribute that adds Python decorators to generated classes, enabling integration with Python frameworks like dataclasses, attrs, functools, and any other decorator-based libraries.

Purpose

F# doesn't have a direct equivalent to Python decorators, but they're essential for integrating with the Python ecosystem. The [<Decorate>] attribute bridges this gap by allowing F# developers to specify Python decorators that should be applied to the generated class.

⚠️ Important: Python Interop Only

The [<Decorate>] attribute is purely for Python interop and does NOT affect F# compilation behavior.

What it DOES (Python interop):

  • Adds decorators to the generated Python code
  • Enables integration with Python libraries that require decorators
  • Makes the transpiled Python work with Python ecosystem tools

What it DOESN'T do (F# side):

  • Does NOT change how your F# code compiles or behaves
  • Does NOT add decorator functionality to F# code
  • Does NOT make Python decorator features available in F# compilation
[<Decorate("dataclasses.dataclass")>]
type User() =
    member val Name: string = "" with get, set

// This is still regular F# - no dataclass behavior here
let user = User()
user.Name <- "Alice"  // Standard F# property access

// The @dataclass behavior only exists in the generated Python

Basic Usage

Simple Decorator

F# Input

[<Decorate("dataclasses.dataclass")>]
type User() =
    member val Name: string = "" with get, set
    member val Age: int = 0 with get, set

Generated Output

from dataclasses import dataclass

@dataclass
class User:
    Name: str = ""
    Age: int = 0

Multiple Decorators

F# Input

[<Decorate("dataclasses.dataclass")>]
[<Decorate("functools.total_ordering")>]
type User() =
    member val Name: string = "" with get, set

Generated Output

from dataclasses import dataclass
from functools import total_ordering

@total_ordering
@dataclass
class User:
    Name: str = ""

Decorators with Parameters

Basic Parameters

F# Input

[<Decorate("functools.lru_cache", "maxsize=128")>]
type CachedClass() =
    member val Value: string = "" with get, set

Generated Output

from functools import lru_cache

@lru_cache(maxsize=128)
class CachedClass:
    Value: str = ""

Complex Parameters

F# Input

[<Decorate("attrs.define", "auto_attribs=True, slots=True")>]
type OptimizedClass() =
    member val Data: string = "" with get, set

Generated Output

import attrs

@attrs.define(auto_attribs=True, slots=True)
class OptimizedClass:
    Data: str = ""

Framework Integration Examples

Dataclasses

[<Decorate("dataclasses.dataclass")>]
type Point() =
    member val X: float = 0.0 with get, set
    member val Y: float = 0.0 with get, set
from dataclasses import dataclass

@dataclass
class Point:
    X: float = 0.0
    Y: float = 0.0

Attrs Library

[<Decorate("attrs.frozen")>]
type ImmutablePoint() =
    member val X: float = 0.0 with get, set
    member val Y: float = 0.0 with get, set
import attrs

@attrs.frozen
class ImmutablePoint:
    X: float = 0.0
    Y: float = 0.0

@dbrattli dbrattli changed the title [WIP/Python] Add Decorate attribute [Python] Add Decorate attribute Aug 5, 2025
@dbrattli dbrattli merged commit f49e20e into main Aug 6, 2025
20 checks passed
@dbrattli dbrattli deleted the python-decorate-attribute branch August 6, 2025 08:43
@MangelMaxime
Copy link
Member

@dbrattli We probably need to update the documentation on Fable website too

@dbrattli
Copy link
Collaborator Author

@MangelMaxime Yes, I was wondering if it should be done before or after Fable 5 is released, but I can probably do it now and tag it with (New in Fable 5)?

@MangelMaxime
Copy link
Member

@dbrattli IHMO we can document it now, so we don't forget about it.

If you want to you can add a "tag" with the next version in it:

image

@dbrattli
Copy link
Collaborator Author

Thanks, I'll add it later today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants