Source code for domdf_python_tools.typing

#!/usr/bin/env python
#
#  typing.py
"""
Various type annotation aids.
"""
#
#  Copyright © 2020 Dominic Davis-Foster <dominic@davis-foster.co.uk>
#
#  Permission is hereby granted, free of charge, to any person obtaining a copy
#  of this software and associated documentation files (the "Software"), to deal
#  in the Software without restriction, including without limitation the rights
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#  copies of the Software, and to permit persons to whom the Software is
#  furnished to do so, subject to the following conditions:
#
#  The above copyright notice and this permission notice shall be included in all
#  copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
#  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
#  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
#  OR OTHER DEALINGS IN THE SOFTWARE.
#

# stdlib
import os
import pathlib
from decimal import Decimal
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Type, TypeVar, Union

# 3rd party
from typing_extensions import Protocol, runtime_checkable

# this package
import domdf_python_tools

if TYPE_CHECKING or domdf_python_tools.__docs:  # pragma: no cover
	# stdlib
	from json import JSONDecoder, JSONEncoder

	# 3rd party
	from pandas import DataFrame, Series

	Series.__module__ = "pandas"
	DataFrame.__module__ = "pandas"

	JSONDecoder.__module__ = "json"
	JSONEncoder.__module__ = "json"

#: .. versionadded:: 1.0.0
FrameOrSeries = TypeVar("FrameOrSeries", "Series", "DataFrame")

__all__ = [
		"PathLike",
		"PathType",
		"AnyNumber",
		"WrapperDescriptorType",
		"MethodWrapperType",
		"MethodDescriptorType",
		"ClassMethodDescriptorType",
		"JsonLibrary",
		"HasHead",
		"String",
		"FrameOrSeries",
		"SupportsIndex",
		"SupportsLessThan",
		"SupportsLessEqual",
		"SupportsGreaterThan",
		"SupportsGreaterEqual",
		"check_membership",
		]

PathLike = Union[str, pathlib.Path, os.PathLike]
"""
Type hint for objects that represent filesystem paths.

.. seealso:: :py:obj:`domdf_python_tools.typing.PathType`
"""

PathType = TypeVar("PathType", str, pathlib.Path, os.PathLike)
"""
Type variable for objects that represent filesystem paths.

.. versionadded:: 2.2.0

.. seealso:: :py:obj:`domdf_python_tools.typing.PathLike`
"""

AnyNumber = Union[float, int, Decimal]
"""
Type hint for numbers.

.. versionchanged:: 0.4.6

	Moved from :mod:`domdf_python_tools.pagesizes`
"""


[docs]def check_membership(obj: Any, type_: Union[Type, object]) -> bool: r""" Check if the type of ``obj`` is one of the types in a :py:data:`typing.Union`, :class:`typing.Sequence` etc. :param obj: The object to check the type of :param type\_: A :class:`~typing.Type` that has members, such as a :class:`typing.List`, :py:data:`typing.Union` or :py:class:`typing.Sequence`. """ return isinstance(obj, type_.__args__) # type: ignore
[docs]class JsonLibrary(Protocol): """ :class:`typing.Protocol` for libraries that implement the same API as :mod:`json`. Useful for annotating functions which take a JSON serialisation-deserialisation library as an argument. """
[docs] @staticmethod def dumps( obj: Any, *, skipkeys: bool = ..., ensure_ascii: bool = ..., check_circular: bool = ..., allow_nan: bool = ..., cls: Optional[Type["JSONEncoder"]] = ..., indent: Union[None, int, str] = ..., separators: Optional[Tuple[str, str]] = ..., default: Optional[Callable[[Any], Any]] = ..., sort_keys: bool = ..., **kwds: Any, ) -> str: """ Serialize ``obj`` to a JSON formatted :class:`str`. :param obj: :param skipkeys: :param ensure_ascii: :param check_circular: :param allow_nan: :param cls: :param indent: :param separators: :param default: :param sort_keys: :param kwds: """
[docs] @staticmethod def loads( s: Union[str, bytes], *, cls: Optional[Type["JSONDecoder"]] = ..., object_hook: Optional[Callable[[Dict[Any, Any]], Any]] = ..., parse_float: Optional[Callable[[str], Any]] = ..., parse_int: Optional[Callable[[str], Any]] = ..., parse_constant: Optional[Callable[[str], Any]] = ..., object_pairs_hook: Optional[Callable[[List[Tuple[Any, Any]]], Any]] = ..., **kwds: Any, ) -> Any: """ Deserialize ``s`` to a Python object. :param s: :param cls: :param object_hook: :param parse_float: :param parse_int: :param parse_constant: :param object_pairs_hook: :param kwds: :rtype: .. latex:clearpage:: """
# Backported from https://github.com/python/cpython/blob/master/Lib/types.py # Licensed under the Python Software Foundation License Version 2. # Copyright © 2001-2020 Python Software Foundation. All rights reserved. # Copyright © 2000 BeOpen.com. All rights reserved. # Copyright © 1995-2000 Corporation for National Research Initiatives. All rights reserved. # Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved. WrapperDescriptorType = type(object.__init__) MethodWrapperType = type(object().__str__) MethodDescriptorType = type(str.join) ClassMethodDescriptorType = type(dict.__dict__["fromkeys"])
[docs]@runtime_checkable class String(Protocol): """ :class:`~typing.Protocol` for classes that implement ``__str__``. .. versionchanged:: 0.8.0 Moved from :mod:`domdf_python_tools.stringlist`. """
[docs] def __str__(self) -> str: ...
[docs]@runtime_checkable class HasHead(Protocol): """ :class:`typing.Protocol` for classes that have a ``head`` method. This includes :class:`pandas.DataFrame` and :class:`pandas.Series`. .. versionadded:: 0.8.0 """
[docs] def head(self: "HasHead", n: int = 5) -> "HasHead": """ Return the first n rows. :param n: Number of rows to select. :return: The first n rows of the caller object. """
[docs] def to_string(self, *args, **kwargs) -> Optional[str]: """ Render the object to a console-friendly tabular output. """
# class SupportsLessThan(Protocol): # # def __lt__(self, other: Any) -> bool: # ... # pragma: no cover
[docs]class SupportsIndex(Protocol): """ :class:`typing.Protocol` for classes that support ``__index__``. .. versionadded:: 2.0.0 """
[docs] def __index__(self) -> int: ...
[docs]class SupportsLessThan(Protocol): """ :class:`typing.Protocol` for classes that support ``__lt__``. .. versionadded:: 3.0.0 """
[docs] def __lt__(self, __other: Any) -> bool: """ Return ``self < value``. """
[docs]class SupportsLessEqual(Protocol): """ :class:`typing.Protocol` for classes that support ``__le__``. .. versionadded:: 3.0.0 """
[docs] def __le__(self, __other: Any) -> bool: """ Return ``self <= value``. """
[docs]class SupportsGreaterThan(Protocol): """ :class:`typing.Protocol` for classes that support ``__gt__``. .. versionadded:: 3.0.0 """
[docs] def __gt__(self, __other: Any) -> bool: """ Return ``self > value``. """
[docs]class SupportsGreaterEqual(Protocol): """ :class:`typing.Protocol` for classes that support ``__ge__``. .. versionadded:: 3.0.0 """
[docs] def __ge__(self, __other: Any) -> bool: """ Return ``self >= value``. """