Source code for robot.utils.robottypes

#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import sys
import warnings
from collections import UserString
from collections.abc import Iterable, Mapping
from io import IOBase
from typing import _SpecialForm, get_args, get_origin, TypedDict, Union

if sys.version_info < (3, 9):
    try:
        # get_args and get_origin handle at least Annotated wrong in Python 3.8.
        from typing_extensions import get_args, get_origin
    except ImportError:
        pass
if sys.version_info >= (3, 10):
    from types import UnionType  # In Python 3.14+ this is same as typing.Union.
else:
    UnionType = ()

try:
    from typing_extensions import TypedDict as ExtTypedDict
except ImportError:
    ExtTypedDict = None


TRUE_STRINGS = {"TRUE", "YES", "ON", "1"}
FALSE_STRINGS = {"FALSE", "NO", "OFF", "0", "NONE", ""}
typeddict_types = (type(TypedDict("Dummy", {})),)
if ExtTypedDict:
    typeddict_types += (type(ExtTypedDict("Dummy", {})),)


[docs] def is_list_like(item): if isinstance(item, (str, bytes, bytearray, UserString, IOBase)): return False return isinstance(item, Iterable)
[docs] def is_dict_like(item): return isinstance(item, Mapping)
[docs] def is_union(item): return isinstance(item, UnionType) or get_origin(item) is Union
[docs] def type_name(item, capitalize=False): """Return "non-technical" type name for objects and types. For example, 'integer' instead of 'int' and 'file' instead of 'TextIOWrapper'. """ if is_union(item): return "Union" item = get_origin(item) or item if isinstance(item, _SpecialForm): # Prior to Python 3.10, typing special forms (Any, Union, ...) didn't # have `__name__` but instead they had `_name`. name = item.__name__ if hasattr(item, "__name__") else item._name elif isinstance(item, IOBase): name = "file" else: typ = item if isinstance(item, type) else type(item) named_types = { str: "string", bool: "boolean", int: "integer", type(None): "None", dict: "dictionary", } name = named_types.get(typ, typ.__name__.strip("_")) return name.capitalize() if capitalize and name.islower() else name
[docs] def type_repr(typ, nested=True): """Return string representation for types. Aims to look as much as the source code as possible. For example, 'List[Any]' instead of 'typing.List[typing.Any]'. """ if typ is type(None): return "None" if typ is Ellipsis: return "..." if is_union(typ): return " | ".join(type_repr(a) for a in get_args(typ)) if nested else "Union" name = _get_type_name(typ) if nested: # At least Literal and Annotated can have strings in args. args = [repr(a) if isinstance(a, str) else type_repr(a) for a in get_args(typ)] if args: return f"{name}[{', '.join(args)}]" return name
def _get_type_name(typ, try_origin=True): try: return typ.__name__ except AttributeError: # Prior to Python 3.10, all typing constructs (e.g. Any, Union, ...) didn't # have `__name__`, but they had `_name` that we can use instead. if getattr(typ, "__module__", None) in ("typing", "typing_extensions"): name = getattr(typ, "_name", None) if name: return name # Typing constructs may not name themselves, but their origin can still have it. origin = get_origin(typ) if origin and try_origin: return _get_type_name(origin, try_origin=False) return str(typ) # TODO: Remove has_args in RF 8.
[docs] def has_args(type): """Helper to check has type valid ``__args__``. Deprecated in Robot Framework 7.3 and will be removed in Robot Framework 8.0. ``typing.get_args`` can be used instead. """ warnings.warn( "'robot.utils.has_args' is deprecated and will be removed in " "Robot Framework 8.0. Use 'typing.get_args' instead." ) return bool(get_args(type))
[docs] def is_truthy(item): """Returns `True` or `False` depending on is the item considered true or not. Validation rules: - If the value is a string, it is considered false if it is `'FALSE'`, `'NO'`, `'OFF'`, `'0'`, `'NONE'` or `''`, case-insensitively. - Other strings are considered true. - Other values are handled by using the standard `bool()` function. Designed to be used also by external test libraries that want to handle Boolean values similarly as Robot Framework itself. See also :func:`is_falsy`. """ if isinstance(item, str): return item.upper() not in FALSE_STRINGS return bool(item)
[docs] def is_falsy(item): """Opposite of :func:`is_truthy`.""" return not is_truthy(item)