Types & Widgets

The central feature of magicgui is conversion from an argument type declared in a function signature, to an appropriate widget type for the given backend. This page describes the logic used.

type inference

magicgui determines the type of an argument as follows:

  1. If a type hint is provided, it is used (regardless of the type of the default value, if provided).

  2. If no type hint is provided, the type of the default value is used, if one is provided.

  3. If a bare argument is defined without a type annotation or default value, it is assumed to be a string.

# arg is assumed to be a float
def function(arg: float = 1):
    ...

# arg is assumed to be a float
def function(arg = 1.0):
    ...

# arg is assumed to be a str
def function(arg):
    ...

type-to-widget conversion

Using the logic defined in the magicgui.type_map module, magicgui will select an appropriate Widget subclass to display the any given type or type annotation. To see the default type of widget magicgui will for a given value, use the get_widget_class() function:

import datetime
from enum import Enum
from pathlib import Path
from magicgui.type_map import get_widget_class

Animal = Enum('Animal', 'ANT BEE CAT DOG')
values = [
    True, 1, 3.43, 'text', Path.home(),
    datetime.datetime.now(), datetime.time(12, 30),
    datetime.date(2000, 2, 18),
    Animal.ANT, range(10), slice(1,20), lambda x: x
]
for v in values:
    cls, options = get_widget_class(v)
    print(f"The widget for {type(v)} is {cls.__name__!r}")

register_type

To provide custom behavior for a specific object type, you may use the magicgui.type_map.register_type() function to:

  1. register a special widget_type

  2. register a special set of choices used when magicgui encounters that type

  3. control what happens when magicgui encounters a function with a return annotation of your custom type.

Hint

This is how napari registers itself to handle napari-specific types in magicgui functions, as shown in the examples