コード例 #1
0
ファイル: typing.py プロジェクト: shaunc/xarray-dataclasses
def get_dims(type_: Type[DataArrayLike[D, T]]) -> Tuple[str, ...]:
    """Extract dimensions (dims) from DataArrayLike[D, T]."""
    if get_origin(type_) is Annotated:
        type_ = get_args(type_)[0]

    dims_ = get_args(get_args(type_)[0])[0]

    if get_origin(dims_) is tuple:
        dims_ = get_args(dims_)
    else:
        dims_ = (dims_, )

    dims: List[str] = []

    for dim_ in dims_:
        if dim_ == () or dim_ is NoneType:
            continue

        if isinstance(dim_, ForwardRef):
            dims.append(dim_.__forward_arg__)
            continue

        if get_origin(dim_) is Literal:
            dims.append(str(get_args(dim_)[0]))
            continue

        raise TypeError("Could not extract dimension.")

    return tuple(dims)
コード例 #2
0
def is_subtype(a: BoundType, b: BoundType) -> bool:  # noqa: C901
    """
    Return True if ``a`` is a subtype of ``b``. Supports single-level typing.Unions
    and intersections represented as tuples respectively without nesting.

    The cases that this function deals with can be divided into the following cases,
    where T is neither a union or intersection:

    1. Union, Union: Success if all types in a have a subclass in b.
    2. T, Union: Success if a is a subclass of one or more types in b.
    3. Union, T: Always fails (except when a single-type union, see 9).
    4. T, Intersection: Success if a is a subclass of all types in b.
    5. Intersection, T: Success if one type in a is a subclass of b.
    6. Intersection, Union: Success if one type in a is a subclass of one type in b.
    7. Union, Intersection: Always fails (except when a is a single-type union see 4).
    8. Intersection, Intersection: Success if all items in b have a subclass in a.
    9. T, T: Success if a is a subclass of b.
    """

    if _is_union(a) and _is_union(b):
        for a_part in get_args(a):
            for b_part in get_args(b):
                if issubclass(a_part, b_part):
                    break
            else:
                return False
        return True
    elif _is_intersection(a) and _is_union(b):
        assert isinstance(a, tuple)
        for a_part, b_part in product(a, get_args(b)):
            if issubclass(a_part, b_part):
                return True
        return False
    elif _is_intersection(a) and _is_intersection(b):
        assert isinstance(a, tuple)
        assert isinstance(b, tuple)
        for b_part in b:
            for a_part in a:
                if issubclass(a_part, b_part):
                    break
            else:
                return False
        return True
    elif _is_union(a):
        return False
    elif _is_union(b):
        assert isinstance(a, type)
        return any(issubclass(a, b_part) for b_part in get_args(b))
    elif _is_intersection(b):
        assert isinstance(a, type)
        assert isinstance(b, tuple)
        return all(issubclass(a, b_part) for b_part in b)
    elif _is_intersection(a):
        assert isinstance(a, tuple)
        return any(issubclass(a_part, b) for a_part in a)
    assert isinstance(a, type)
    return issubclass(a, b)
コード例 #3
0
    async def _convert(
        self,
        ctx: "Context",
        converter: Union[converters.Converter, type, Callable[[str], Any]],
        param: inspect.Parameter,
        argument: str,
    ) -> Any:
        if isinstance(converter, converters.Converter):
            try:
                converter = converter() if callable(converter) else converter
                return await converter.convert(ctx, argument)
            except Exception as exc:
                try:
                    name = converter.__name__
                except AttributeError:
                    name = converter.__class__.__name__
                raise BadArgument(
                    f"{argument} failed to convert to {name}") from exc
        else:
            if converter is bool:
                return to_bool(argument)
            origin = get_origin(converter)
            if origin is not None:
                for arg in get_args(converter):
                    converter = self._get_converter(arg)
                    try:
                        return await self._convert(ctx, converter, argument)
                    except BadArgument:
                        if origin is Union:
                            continue
                        raise
                else:
                    if origin is Union and type(None) in get_args(
                            converter):  # typing.Optional
                        try:
                            return self._get_default(
                                ctx, param)  # get the default if possible
                        except MissingRequiredArgument:
                            return None  # fall back to None
                    raise BadArgument(
                        f"Failed to parse {argument} to any type")

            try:
                return converter(argument)
            except Exception as exc:
                try:
                    name = converter.__name__
                except AttributeError:
                    name = converter.__class__.__name__
                raise BadArgument(
                    f"{argument!r} failed to convert to {name}") from exc
コード例 #4
0
def get_runtime_pattern_arg_types():
    runtime_generic_types = []
    for type_ in get_args(T_PatternArg):

        if type_ is Union:  # T_SegmentClass
            runtime_generic_types.extend(get_args(type_))

        else:  # str, bool, int, float
            runtime_generic_types.append(type_)

    # debug(runtime_generic_types)
    runtime_class_types = tuple(
        map(lambda generic: get_args(generic)[0], runtime_generic_types))
    # debug(runtime_class_types)
    return runtime_class_types
コード例 #5
0
def add_future_data(gui, future: Future, return_type, _from_tuple=True):
    """Process a Future object from a magicgui widget.

    This function will be called when a magicgui-decorated function has a
    return annotation of one of the `napari.types.<layer_name>Data` ... and
    will add the data in ``result`` to the current viewer as the corresponding
    layer type.

    Parameters
    ----------
    gui : FunctionGui
        The instantiated magicgui widget.  May or may not be docked in a
        dock widget.
    future : Future
        An instance of `concurrent.futures.Future` (or any third-party) object
        with the same interface, that provides `add_done_callback` and `result`
        methods.  When the future is `done()`, the `result()` will be added
        to the viewer.
    return_type : type
        The return annotation that was used in the decorated function.
    _from_tuple : bool, optional
        (only for internal use). True if the future returns `LayerDataTuple`,
        False if it returns one of the `LayerData` types.
    """
    from ..utils._injection._processors import _add_future_data

    if viewer := find_viewer_ancestor(gui):
        _add_future_data(
            future,
            return_type=get_args(return_type)[0],
            _from_tuple=_from_tuple,
            viewer=viewer,
            source={'widget': gui},
        )
コード例 #6
0
ファイル: resources.py プロジェクト: olivier-membrive/bokeh
 def log_level(self, level: LogLevel) -> None:
     valid_levels = get_args(LogLevel)
     if not (level is None or level in valid_levels):
         raise ValueError(
             f"Unknown log level '{level}', valid levels are: {valid_levels}"
         )
     self._log_level = level
コード例 #7
0
def args_to_matchers(
    function: Callable[..., Any], ) -> Dict[str, libcst_typing.Matcher]:
    """Extract node matchers from the function arguments.

    Untyped arguments will get a `DoNotCare` matcher, while arguments typed and
    annoated with a `BaseMatcherNode` will return that matcher.
    """
    matchers: Dict[str, libcst_typing.Matcher] = {}

    # Create default matchers for all arguments
    args = function.__code__.co_varnames[:function.__code__.co_argcount]
    if args:
        for name in args:
            if name == "self":
                continue
            matchers[name] = libcst.matchers.DoNotCare()

    # Check if any of the arguments was annotated with a Matcher
    for name, type_declaration in typing_extensions.get_type_hints(
            function, include_extras=True).items():
        if typing_extensions.get_origin(type_declaration) is Annotated:
            # Check if there is a matcher
            arg = typing_extensions.get_args(type_declaration)[1]
            if isinstance(arg, libcst.matchers.BaseMatcherNode):
                matchers[name] = arg

    return matchers
コード例 #8
0
ファイル: private.py プロジェクト: DoctorJohn/strawberry
def is_private(type_: object) -> bool:
    if get_origin(type_) is Annotated:
        return any(
            isinstance(argument, StrawberryPrivate) for argument in get_args(type_)
        )

    return False
コード例 #9
0
def _register_types_with_magicgui():
    """Register ``napari.types`` objects with magicgui."""
    import sys
    from concurrent.futures import Future

    from magicgui import register_type

    from .utils import _magicgui as _mgui

    for _type in (LayerDataTuple, List[LayerDataTuple]):
        register_type(
            _type,
            return_callback=_mgui.add_layer_data_tuples_to_viewer,
        )
        if sys.version_info >= (3, 9):
            future_type = Future[_type]  # type: ignore
            register_type(future_type, return_callback=_mgui.add_future_data)

    for data_type in get_args(_LayerData):
        register_type(
            data_type,
            choices=_mgui.get_layers_data,
            return_callback=_mgui.add_layer_data_to_viewer,
        )
        if sys.version_info >= (3, 9):
            register_type(
                Future[data_type],  # type: ignore
                choices=_mgui.get_layers_data,
                return_callback=partial(_mgui.add_future_data,
                                        _from_tuple=False),
            )
コード例 #10
0
ファイル: commands.py プロジェクト: Gobot1234/steam.py
    async def _parse_var_keyword_argument(self, ctx: Context,
                                          param: inspect.Parameter,
                                          kwargs: dict[str, Any]) -> None:
        kv_pairs = [arg.split("=") for arg in ctx.lex]
        if not kv_pairs:
            raise MissingRequiredArgument(param)  # defaults don't work here

        key_type, value_type = (
            (str,
             str) if param.annotation in (param.empty,
                                          dict) else get_args(param.annotation)
        )  # default to dict[str, str]

        key_converter = self._get_converter(key_type)
        value_converter = self._get_converter(value_type)
        try:
            for key_arg, value_arg in kv_pairs:
                if key_arg in kwargs:
                    raise DuplicateKeywordArgument(key_arg)
                kwargs.update({
                    await self._convert(ctx, key_converter, param,
                                        key_arg.strip()):
                    await self._convert(ctx, value_converter, param,
                                        value_arg.strip())
                })
        except ValueError:
            raise UnmatchedKeyValuePair(
                "Unmatched key-value pair passed") from None
コード例 #11
0
def parse_inner_type_of_optional(optional_type: Any) -> Type:

    args = get_args(optional_type)
    if not (len(args) == 2 and any(arg is _NoneType for arg in args)):
        raise TypeError(f"Unsupported type: {optional_type}.")

    return next(arg for arg in args if arg is not _NoneType)
コード例 #12
0
def get_inner(hint: Any, *indexes: int) -> Any:
    """Return an inner type hint by indexes."""
    if not indexes:
        return hint

    index, indexes = indexes[0], indexes[1:]
    return get_inner(get_args(hint)[index], *indexes)
コード例 #13
0
 def convert_to_union(self, ctx: typing.Optional[click.Context],
                      param: typing.Optional[click.Parameter],
                      value: typing.Any) -> Literal:
     lt = self._literal_type
     for i in range(len(self._literal_type.union_type.variants)):
         variant = self._literal_type.union_type.variants[i]
         python_type = get_args(self._python_type)[i]
         converter = FlyteLiteralConverter(
             ctx,
             self._flyte_ctx,
             variant,
             python_type,
             self._create_upload_fn,
         )
         try:
             # Here we use click converter to convert the input in command line to native python type,
             # and then use flyte converter to convert it to literal.
             python_val = converter._click_type.convert(value, param, ctx)
             literal = converter.convert_to_literal(ctx, param, python_val)
             self._python_type = python_type
             return literal
         except (Exception or AttributeError) as e:
             logging.debug(
                 f"Failed to convert python type {python_type} to literal type {variant}",
                 e)
     raise ValueError(
         f"Failed to convert python type {self._python_type} to literal type {lt}"
     )
コード例 #14
0
ファイル: typing.py プロジェクト: shaunc/xarray-dataclasses
def get_dtype(type_: Type[DataArrayLike[D, T]]) -> Union[type, str, None]:
    """Extract a data type (dtype) from DataArrayLike[D, T]."""
    if get_origin(type_) is Annotated:
        type_ = get_args(type_)[0]

    dtype_ = get_args(get_args(type_)[0])[1]

    if dtype_ is Any:
        return None

    if isinstance(dtype_, ForwardRef):
        return dtype_.__forward_arg__

    if get_origin(dtype_) is Literal:
        return get_args(dtype_)[0]

    return cast(type, dtype_)
コード例 #15
0
def _attr_to_optparse_option(at: Field, default: Any) -> Tuple[dict, str]:
    """Convert a field into a Docutils optparse options dict."""
    if at.type is int:
        return {"metavar": "<int>", "validator": _validate_int}, f"(default: {default})"
    if at.type is bool:
        return {
            "metavar": "<boolean>",
            "validator": frontend.validate_boolean,
        }, f"(default: {default})"
    if at.type is str:
        return {
            "metavar": "<str>",
        }, f"(default: '{default}')"
    if get_origin(at.type) is Literal and all(
        isinstance(a, str) for a in get_args(at.type)
    ):
        args = get_args(at.type)
        return {
            "metavar": f"<{'|'.join(repr(a) for a in args)}>",
            "type": "choice",
            "choices": args,
        }, f"(default: {default!r})"
    if at.type in (Iterable[str], Sequence[str]):
        return {
            "metavar": "<comma-delimited>",
            "validator": frontend.validate_comma_separated_list,
        }, f"(default: '{','.join(default)}')"
    if at.type == Tuple[str, str]:
        return {
            "metavar": "<str,str>",
            "validator": _create_validate_tuple(2),
        }, f"(default: '{','.join(default)}')"
    if at.type == Union[int, type(None)]:
        return {
            "metavar": "<null|int>",
            "validator": _validate_int,
        }, f"(default: {default})"
    if at.type == Union[Iterable[str], type(None)]:
        default_str = ",".join(default) if default else ""
        return {
            "metavar": "<null|comma-delimited>",
            "validator": frontend.validate_comma_separated_list,
        }, f"(default: {default_str!r})"
    raise AssertionError(
        f"Configuration option {at.name} not set up for use in docutils.conf."
    )
コード例 #16
0
def provider(func: C) -> C:
    """Decorator that declares `func` as a provider of its return type.

    Note, If func returns `Optional[Type]`, it will be registered as a provider
    for Type.

    Examples
    --------
    >>> @provider
    >>> def provides_int() -> int:
    ...     return 42
    """
    return_hint = get_type_hints(func).get('return')
    if get_origin(return_hint) == Union:
        if ((args := get_args(return_hint)) and len(args) == 2
                and type(None) in args):
            return_hint = next(a for a in args if a is not type(None))  # noqa
コード例 #17
0
def extract_config(t: Type[TensorFlow2ONNX]) -> Tuple[Type[TensorFlow2ONNX], TensorFlow2ONNXConfig]:
    config = None
    if get_origin(t) is Annotated:
        base_type, config = get_args(t)
        if isinstance(config, TensorFlow2ONNXConfig):
            return base_type, config
        else:
            raise TypeTransformerFailedError(f"{t}'s config isn't of type TensorFlow2ONNX")
    return t, config
コード例 #18
0
ファイル: enums.py プロジェクト: SteffyPerilla/hyperblog
def enumeration(*values: Any,
                case_sensitive: bool = True,
                quote: bool = False) -> Enumeration:
    ''' Create an |Enumeration| object from a sequence of values.

    Call ``enumeration`` with a sequence of (unique) strings to create an
    Enumeration object:

    .. code-block:: python

        #: Specify the horizontal alignment for rendering text
        TextAlign = enumeration("left", "right", "center")

    Args:
        values (str) : string enumeration values, passed as positional arguments

            The order of arguments is the order of the enumeration, and the
            first element will be considered the default value when used
            to create |Enum| properties.

    Keyword Args:
        case_sensitive (bool, optional) :
            Whether validation should consider case or not (default: True)

        quote (bool, optional):
            Whether values should be quoted in the string representations
            (default: False)

    Raises:
        ValueError if values empty, if any value is not a string or not unique

    Returns:
        Enumeration

    '''
    if len(values) == 1 and hasattr(values[0], "__args__"):
        values = get_args(values[0])

    if not (values
            and all(isinstance(value, str) and value for value in values)):
        raise ValueError(
            f"expected a non-empty sequence of strings, got {nice_join(values)}"
        )

    if len(values) != len(set(values)):
        raise ValueError(
            f"enumeration items must be unique, got {nice_join(values)}")

    attrs: Dict[str, Any] = {value: value for value in values}
    attrs.update({
        "_values": list(values),
        "_default": values[0],
        "_case_sensitive": case_sensitive,
        "_quote": quote,
    })

    return type("Enumeration", (Enumeration, ), attrs)()
コード例 #19
0
ファイル: tcp.py プロジェクト: rho2/alpyro
    def _decode_value(self, msg: RosMessage, buffer: bytes, offset, typ):
        o = get_origin(typ)
        val: Any = None

        if o is None and issubclass(typ, RosMessage):
            val = typ()
            offset = self.decode(val, buffer, offset)
            return val, offset

        base, size, signed = get_args(typ)

        if base == str:
            l = int.from_bytes(buffer[offset : offset + 4], "little", signed=False)
            val = buffer[offset + 4 : offset + 4 + l].decode("utf-8")
            offset += 4 + l
        elif base == int:
            val = int.from_bytes(buffer[offset : offset + size], "little", signed=signed)
            offset += size
        elif base == float:
            val, *_ = struct.unpack("<f" if size == 4 else "<d", buffer[offset : offset + size])
            offset += size
        elif base == bytes:
            if size == 0:
                size = int.from_bytes(buffer[offset : offset + 4], "little", signed=False)
                offset += 4
            val = buffer[offset : offset + size]
            offset += size
        elif base == Time or base == Duration:
            secs = int.from_bytes(buffer[offset : offset + 4], "little", signed=False)
            nsecs = int.from_bytes(buffer[offset + 4 : offset + 8], "little", signed=False)
            val = base(secs, nsecs)
            offset += 8
        elif get_origin(base) == list:
            t, *_ = get_args(base)
            if size == 0:
                size = int.from_bytes(buffer[offset : offset + 4], "little", signed=False)
                offset += 4

            val = []
            for _ in range(size):
                v, offset = self._decode_value(msg, buffer, offset, t)
                val.append(v)

        return val, offset
コード例 #20
0
ファイル: commands.py プロジェクト: Gobot1234/steam.py
    async def _convert(
        self,
        ctx: Context,
        converter: converters.Converters,
        param: inspect.Parameter,
        argument: str,
    ) -> Any:
        if isinstance(converter, converters.ConverterBase):
            if isinstance(converter, type):  # needs to be instantiated
                converter = converter()
            try:
                return await converter.convert(ctx, argument)
            except Exception as exc:
                try:
                    name = converter.__name__
                except AttributeError:
                    name = converter.__class__.__name__
                raise BadArgument(
                    f"{argument!r} failed to convert to {name}") from exc
        origin = get_origin(converter)
        if origin is not None:
            args = get_args(converter)
            for arg in args:
                converter = self._get_converter(arg)
                try:
                    ret = await self._convert(ctx, converter, param, argument)
                except BadArgument:
                    if origin is not Union:
                        raise
                else:
                    if origin is not Literal:
                        return ret
                    if arg == ret:
                        return ret

            if origin is Union and args[-1] is type(None):  # typing.Optional
                try:
                    return self._get_default(
                        ctx, param)  # get the default if possible
                except MissingRequiredArgument:
                    return None  # fall back to None
            if origin is Literal:
                raise BadArgument(
                    f"Expected one of {', '.join(args)} not {argument!r}")

            raise BadArgument(f"Failed to parse {argument!r} to any type")

        try:
            return converter(argument)
        except Exception as exc:
            try:
                name = converter.__name__
            except AttributeError:
                name = converter.__class__.__name__
            raise BadArgument(
                f"{argument!r} failed to convert to {name}") from exc
コード例 #21
0
def small_validate(value, allowed_type: None | Any = None, name: str | None = None) -> None:
    """Type validation. It also works for Union and validate Literal values.

    Instead of typeguard validation, it define just subset of types, but is simplier
    and needs no extra import, therefore can be faster.

    Args:
        value (Any): Value that will be validated.
        allowed_type (Any, optional): For example int, str or list. It can be also Union or Literal.
            If Literal, validated value has to be one of Literal values. If None, it's skipped.
            Defaults to None.
        name (str | None, optional): If error raised, name will be printed. Defaults to None.

    Raises:
        TypeError: Type does not fit.

    Examples:
        >>> from typing_extensions import Literal
        ...
        >>> small_validate(1, int)
        >>> small_validate(None, Union[list, None])
        >>> small_validate("two", Literal["one", "two"])
        >>> small_validate("three", Literal["one", "two"])  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ValidationError: ...
    """
    if allowed_type:
        # If Union
        if get_origin(allowed_type) == Union:

            if type(value) in get_args(allowed_type):
                return
            else:
                raise ValidationError(
                    mylogging.format_str(
                        f"Allowed type for variable '{name}' are {allowed_type}, but you try to set an {type(value)}"
                    )
                )

        # If Literal - parse options
        elif get_origin(allowed_type) == Literal:
            options = getattr(allowed_type, "__args__")
            if value in options:
                return
            else:
                raise ValidationError(
                    f"New value < {value} > for variable < {name} > is not in allowed options {options}."
                )

        else:
            if isinstance(value, allowed_type):  # type: ignore
                return
            else:
                raise ValidationError(
                    f"Allowed allowed_type for variable < {name} > is {allowed_type}, but you try to set an {type(value)}"
                )
コード例 #22
0
ファイル: container.py プロジェクト: Bloodielie/pyject
    def get(self, annotation):
        """Get object from container"""
        type_args = get_args(annotation)
        if type_args:
            annotation = (annotation, type_args)

        for dependency in self._resolver.get_resolved_dependencies(annotation):
            return dependency

        raise DependencyNotFound("Dependency not found")
コード例 #23
0
ファイル: container.py プロジェクト: Bloodielie/pyject
    def get_all(self, annotation):
        """Get all object from container"""
        type_args = get_args(annotation)
        if type_args:
            annotation = (annotation, type_args)

        dependencies = []
        for dependency in self._resolver.get_resolved_dependencies(annotation):
            dependencies.append(dependency)
        return dependencies
コード例 #24
0
def _eval_type(type: Any, globals: Dict[str, Any]) -> Any:
    """Evaluate all forward reverences in the given type."""
    if isinstance(type, str):
        type = ForwardRef(type)
    if isinstance(type, ForwardRef):
        return type._evaluate(globals, {})
    if isinstance(type, _GenericAlias):
        args = tuple(_eval_type(arg, globals) for arg in get_args(type))
        return get_origin(type)[args]
    return type
コード例 #25
0
def _is_valid_typeddict_item(
    td: type[TypedDict], key: str, value: Any  # type: ignore [valid-type]
) -> bool:
    """Check if `key` and `value` form a valid item for the TypedDict `td`."""
    annotations = get_type_hints(td)
    if key not in annotations:
        return False
    if get_origin(annotations[key]) is Literal:
        return value in get_args(annotations[key])
    return isinstance(value, annotations[key])
コード例 #26
0
ファイル: value_widget.py プロジェクト: napari/magicgui
    def annotation(self):
        """Return type annotation for the parameter represented by the widget.

        ForwardRefs will be resolve when setting the annotation.
        If the widget is nullable (had a type annototation of Optional[Type]),
        annotation will return the first argument in the Optional clause.
        """
        annotation = Widget.annotation.fget(self)  # type: ignore
        if self._nullable and get_origin(annotation) is Union:
            return get_args(annotation)[0]
        return annotation
コード例 #27
0
def flatten_greedy(item: T | Greedy[Any]) -> Generator[T, None, None]:
    if get_origin(item) in (Greedy, Union):
        for arg in get_args(item):
            if arg in INVALID_GREEDY_TYPES:
                raise TypeError(f"Greedy[{arg.__name__}] is invalid")
            if get_origin(arg) in (Greedy, Union):
                yield from flatten_greedy(arg)
            else:
                yield arg
    else:
        yield item
コード例 #28
0
def is_str_literal(hint: Any) -> bool:
    """Check if a type hint is Literal[str]."""
    args: Any = get_args(hint)
    origin = get_origin(hint)

    if origin is not Literal:
        return False

    if not len(args) == 1:
        return False

    return isinstance(args[0], str)
コード例 #29
0
def extract_cols_and_format(
    t: typing.Any,
) -> typing.Tuple[Type[T], Optional[typing.OrderedDict[str, Type]],
                  Optional[str], Optional[pa.lib.Schema]]:
    """
    Helper function, just used to iterate through Annotations and extract out the following information:
      - base type, if not Annotated, it will just be the type that was passed in.
      - column information, as a collections.OrderedDict,
      - the storage format, as a ``StructuredDatasetFormat`` (str),
      - pa.lib.Schema

    If more than one of any type of thing is found, an error will be raised.
    If no instances of a given type are found, then None will be returned.

    If we add more things, we should put all the returned items in a dataclass instead of just a tuple.

    :param t: The incoming type which may or may not be Annotated
    :return: Tuple representing
        the original type,
        optional OrderedDict of columns,
        optional str for the format,
        optional pyarrow Schema
    """
    fmt = None
    ordered_dict_cols = None
    pa_schema = None
    if get_origin(t) is Annotated:
        base_type, *annotate_args = get_args(t)
        for aa in annotate_args:
            if isinstance(aa, StructuredDatasetFormat):
                if fmt is not None:
                    raise ValueError(
                        f"A format was already specified {fmt}, cannot use {aa}"
                    )
                fmt = aa
            elif isinstance(aa, collections.OrderedDict):
                if ordered_dict_cols is not None:
                    raise ValueError(
                        f"Column information was already found {ordered_dict_cols}, cannot use {aa}"
                    )
                ordered_dict_cols = aa
            elif isinstance(aa, pyarrow.Schema):
                if pa_schema is not None:
                    raise ValueError(
                        f"Arrow schema was already found {pa_schema}, cannot use {aa}"
                    )
                pa_schema = aa
        return base_type, ordered_dict_cols, fmt, pa_schema

    # We return None as the format instead of parquet or something because the transformer engine may find
    # a better default for the given dataframe type.
    return t, ordered_dict_cols, fmt, pa_schema
コード例 #30
0
ファイル: _magicgui.py プロジェクト: tlambert03/napari
def add_future_data(gui, future, return_type, _from_tuple=True):
    """Process a Future object from a magicgui widget.

    This function will be called when a magicgui-decorated function has a
    return annotation of one of the `napari.types.<layer_name>Data` ... and
    will add the data in ``result`` to the current viewer as the corresponding
    layer type.

    Parameters
    ----------
    gui : FunctionGui
        The instantiated magicgui widget.  May or may not be docked in a
        dock widget.
    future : Future
        An instance of `concurrent.futures.Future` (or any third-party) object
        with the same interface, that provides `add_done_callback` and `result`
        methods.  When the future is `done()`, the `result()` will be added
        to the viewer.
    return_type : type
        The return annotation that was used in the decorated function.
    _from_tuple : bool, optional
        (only for internal use). True if the future returns `LayerDataTuple`,
        False if it returns one of the `LayerData` types.
    """
    from .._qt.utils import Sentry

    # get the actual return type from the Future type annotation
    _return_type = get_args(return_type)[0]

    if _from_tuple:
        # when the future is done, add layer data to viewer, dispatching
        # to the appropriate method based on the Future data type.

        def _on_future_ready():
            add_layer_data_tuples_to_viewer(gui, future.result(), return_type)
            _FUTURES.discard(future)

    else:

        def _on_future_ready():
            add_layer_data_to_viewer(gui, future.result(), _return_type)
            _FUTURES.discard(future)

    # some future types (such as a dask Future) will call the callback in
    # another thread, which wont always work here.  So we create a very small
    # QObject that can signal back to the main thread to call `_on_done`.
    sentry = Sentry()
    sentry.alerted.connect(_on_future_ready)
    future.add_done_callback(sentry.alert)
    _FUTURES.add(future)