Source code for hikari.undefined

# -*- coding: utf-8 -*-
# cython: language_level=3
# Copyright (c) 2020 Nekokatt
# Copyright (c) 2021-present davfsa
#
# 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.
"""Singleton used throughout the library to denote values that are not present."""

from __future__ import annotations

__all__: typing.Sequence[str] = (
    "UNDEFINED",
    "UndefinedNoneOr",
    "UndefinedOr",
    "UndefinedType",
    "all_undefined",
    "any_undefined",
    "count",
)

import typing

if typing.TYPE_CHECKING:
    from typing_extensions import Self


[docs]class UndefinedType: """The type of the `UNDEFINED` singleton sentinel value.""" __slots__: typing.Sequence[str] = () def __bool__(self) -> typing.Literal[False]: return False def __copy__(self) -> Self: # This is meant to be a singleton return self def __deepcopy__(self, memo: typing.MutableMapping[int, typing.Any]) -> Self: memo[id(self)] = self # This is meant to be a singleton return self def __getstate__(self) -> typing.Any: # Returning False tells pickle to not call `__setstate__` on unpickling. return False def __repr__(self) -> str: return "UNDEFINED" def __reduce__(self) -> str: # Returning a string makes pickle fetch from the module namespace. return "UNDEFINED" def __str__(self) -> str: return "UNDEFINED"
[docs]UNDEFINED = UndefinedType()
"""A sentinel singleton that denotes a missing or omitted value.""" def __new__(cls: UndefinedType) -> typing.NoReturn: # pragma: nocover raise TypeError("Cannot initialize multiple instances of singleton UNDEFINED") UndefinedType.__new__ = __new__ del __new__ T = typing.TypeVar("T", covariant=True)
[docs]UndefinedOr = typing.Union[T, UndefinedType]
"""Type hint to mark a type as being semantically optional. **NOTE THAT THIS IS NOT THE SAME AS `typing.Optional` BY DEFINITION**. If you see a type with this marker, it may be `UNDEFINED` or the value it wraps. For example, `UndefinedOr[float]` would mean the value could be a `float`, or the literal `UNDEFINED` value. On the other hand, `typing.Optional[float]` would mean the value could be a `float`, or the literal `None` value. The reason for using this is in some places, there is a semantic difference between specifying something as being `None`, i.e. "no value", and having a default to specify that the value has just not been mentioned. The main example of this is in `edit` endpoints where the contents will only be changed if they are explicitly mentioned in the call. Editing a message content and setting it to `None` would be expected to clear the content, whereas setting it to `UNDEFINED` would be expected to leave the value as it is without changing it. Consider `UndefinedOr[T]` semantically equivalent to `undefined` versus `null` in JavaScript, or `Optional<T>` versus `null` in Java and C#. If in doubt, remember: - `UNDEFINED` means there is no value present, or that it has been left to the default value. - `None` means the value is present and explicitly empty/null/void, where this has a deterministic documented behaviour and no differentiation is made between a `None` value, and one that has been omitted. """
[docs]UndefinedNoneOr = typing.Union[UndefinedOr[T], None]
"""Type hint for a value that may be `undefined.UNDEFINED`, or `None`. `UndefinedNoneOr[T]` is simply an alias for `UndefinedOr[typing.Optional[T]]`, which would expand to `typing.Union[UndefinedType, T, None]`. """
[docs]def all_undefined(*items: typing.Any) -> bool: """Get if all of the provided items are `UNDEFINED`.""" return all(item is UNDEFINED for item in items)
[docs]def any_undefined(*items: typing.Any) -> bool: """Get if any of the provided items are `UNDEFINED`.""" return any(item is UNDEFINED for item in items)
[docs]def count(*items: typing.Any) -> int: """Count the number of items that are provided that are `UNDEFINED`.""" return sum(item is UNDEFINED for item in items)