Skip to content

Type Map#

flet_pkg.core.type_map #

Dart-to-Python type mapping.

Converts Dart type annotations to their Python equivalents, handling nullable types, generics, and common Flutter types.

Also provides Flet-aware mappings for UI controls that use native Flet types (ft.Alignment, ft.BoxFit, etc.) and typed Dart getters (getAlignment, getBoxFit, etc.).

map_dart_type #

map_dart_type(dart_type: str) -> str

Map a Dart type annotation to its Python equivalent.

Handles nullable types (String? -> str | None), generics (List<String> -> list[str]), nested generics (Map<String, List<int>> -> dict[str, list[int]]), and Future<T> (unwraps to the inner type).

Parameters:

Name Type Description Default
dart_type str

The Dart type string to convert.

required

Returns:

Type Description
str

The corresponding Python type string.

Source code in src/flet_pkg/core/type_map.py
def map_dart_type(dart_type: str) -> str:
    """Map a Dart type annotation to its Python equivalent.

    Handles nullable types (``String?`` -> ``str | None``), generics
    (``List<String>`` -> ``list[str]``), nested generics
    (``Map<String, List<int>>`` -> ``dict[str, list[int]]``), and
    ``Future<T>`` (unwraps to the inner type).

    Args:
        dart_type: The Dart type string to convert.

    Returns:
        The corresponding Python type string.
    """
    dart_type = dart_type.strip()
    if not dart_type:
        return "Any"

    # Handle nullable
    nullable_match = _NULLABLE_RE.match(dart_type)
    if nullable_match:
        inner = map_dart_type(nullable_match.group(1))
        return f"{inner} | None"

    # Handle generics
    generic_match = _GENERIC_RE.match(dart_type)
    if generic_match:
        outer = generic_match.group(1)
        inner_raw = generic_match.group(2)

        # Future<T> -> unwrap to T
        if outer == "Future":
            return map_dart_type(inner_raw)

        # Split generic params respecting nested angle brackets
        inner_types = _split_generic_params(inner_raw)
        mapped_inner = ", ".join(map_dart_type(t) for t in inner_types)

        if outer == "List":
            return f"list[{mapped_inner}]"
        if outer == "Set":
            return f"set[{mapped_inner}]"
        if outer == "Map":
            return f"dict[{mapped_inner}]"
        if outer == "Iterable":
            return f"list[{mapped_inner}]"

        # Unknown generic: just map the outer
        mapped_outer = _TYPE_MAP.get(outer, outer)
        return f"{mapped_outer}[{mapped_inner}]"

    # Direct lookup
    if dart_type in _TYPE_MAP:
        return _TYPE_MAP[dart_type]

    # Function types
    if "Function" in dart_type:
        return "Any"

    # Unknown type: pass through as-is
    return dart_type

map_return_type #

map_return_type(dart_type: str) -> tuple[str, bool]

Map a Dart return type, detecting if the method is async.

Parameters:

Name Type Description Default
dart_type str

The Dart return type string.

required

Returns:

Type Description
str

A tuple of (python_type, is_async). is_async is True

bool

when the Dart return type is Future<T>.

Source code in src/flet_pkg/core/type_map.py
def map_return_type(dart_type: str) -> tuple[str, bool]:
    """Map a Dart return type, detecting if the method is async.

    Args:
        dart_type: The Dart return type string.

    Returns:
        A tuple of (python_type, is_async). ``is_async`` is True
        when the Dart return type is ``Future<T>``.
    """
    dart_type = dart_type.strip()
    if not dart_type:
        return "None", False

    generic_match = _GENERIC_RE.match(dart_type)
    if generic_match and generic_match.group(1) == "Future":
        inner = generic_match.group(2).strip()
        if inner == "void":
            return "None", True
        return map_dart_type(inner), True

    if dart_type == "Future":
        return "None", True

    return map_dart_type(dart_type), False

map_dart_type_flet #

map_dart_type_flet(dart_type: str) -> str | None

Map a Dart type to its Flet-aware Python equivalent.

Consults _FLET_TYPE_MAP first for native Flet types (e.g. Alignmentft.Alignment), then falls back to map_dart_type().

Returns None when the type should be skipped entirely (e.g. Key).

Source code in src/flet_pkg/core/type_map.py
def map_dart_type_flet(dart_type: str) -> str | None:
    """Map a Dart type to its Flet-aware Python equivalent.

    Consults ``_FLET_TYPE_MAP`` first for native Flet types (e.g.
    ``Alignment`` → ``ft.Alignment``), then falls back to
    ``map_dart_type()``.

    Returns ``None`` when the type should be skipped entirely (e.g.
    ``Key``).
    """
    dart_type = dart_type.strip()
    if not dart_type:
        return "Any"

    # Handle nullable
    nullable_match = _NULLABLE_RE.match(dart_type)
    if nullable_match:
        inner = map_dart_type_flet(nullable_match.group(1))
        if inner is None:
            return None
        return f"{inner} | None"

    # Handle generics
    generic_match = _GENERIC_RE.match(dart_type)
    if generic_match:
        outer = generic_match.group(1)
        inner_raw = generic_match.group(2)

        # Future<T> → unwrap to T
        if outer == "Future":
            return map_dart_type_flet(inner_raw)

        inner_types = _split_generic_params(inner_raw)
        mapped = []
        for t in inner_types:
            m = map_dart_type_flet(t)
            if m is None:
                return None
            mapped.append(m)
        mapped_inner = ", ".join(mapped)

        if outer == "List":
            return f"list[{mapped_inner}]"
        if outer == "Set":
            return f"set[{mapped_inner}]"
        if outer == "Map":
            return f"dict[{mapped_inner}]"
        if outer == "Iterable":
            return f"list[{mapped_inner}]"

        mapped_outer = _FLET_TYPE_MAP.get(outer)
        if mapped_outer is None and outer in _FLET_TYPE_MAP:
            return None  # explicitly skipped
        if mapped_outer is None:
            mapped_outer = _TYPE_MAP.get(outer, outer)
        return f"{mapped_outer}[{mapped_inner}]"

    # Flet type lookup (may return None for skipped types)
    if dart_type in _FLET_TYPE_MAP:
        return _FLET_TYPE_MAP[dart_type]

    # Fallback to standard mapping
    return map_dart_type(dart_type)

get_flet_dart_getter #

get_flet_dart_getter(python_type: str, prop_name: str) -> str

Return the Dart getter expression for a Flet property.

Parameters:

Name Type Description Default
python_type str

The mapped Python type (e.g. "ft.Alignment").

required
prop_name str

The property name (e.g. "alignment").

required

Returns:

Type Description
str

A Dart expression string like control.getAlignment("alignment").

str

Falls back to control.getString("{prop_name}") for unknown types.

Source code in src/flet_pkg/core/type_map.py
def get_flet_dart_getter(python_type: str, prop_name: str) -> str:
    """Return the Dart getter expression for a Flet property.

    Args:
        python_type: The mapped Python type (e.g. ``"ft.Alignment"``).
        prop_name: The property name (e.g. ``"alignment"``).

    Returns:
        A Dart expression string like ``control.getAlignment("alignment")``.
        Falls back to ``control.getString("{prop_name}")`` for unknown types.
    """
    # Strip nullable and list wrappers for lookup
    base = python_type.replace(" | None", "").strip()

    # Handle list types: list[ft.Control] → buildWidgets("{name}")
    if base.startswith("list["):
        inner = base[5:-1]
        if inner == "ft.Control":
            return f'buildWidgets("{prop_name}")'
        return f'control.getString("{prop_name}")'

    template = _FLET_DART_GETTER_MAP.get(base, 'control.getString("{name}")')
    return template.replace("{name}", prop_name)