from typing import Any, Dict, Iterable, Iterator, Self, Tuple, Type, TypeVar, Union

_T = TypeVar('_T')
_EnumType = TypeVar('_EnumType', bound=Type[Enum])

class EnumMeta(type, Iterable):
  def __iter__(self: Type[_T]) -> Iterator[_T]: ...
  def __getitem__(cls: EnumMeta, name: str) -> Any: ...
  def __contains__(self, member: Enum) -> bool: ...
  def __len__(self) -> int: ...
  def __new__(
      metacls: type[Self], cls: str, bases: tuple[type, ...], classdict: dict[str, Any], **kwds: Any
  ) -> Self: ...

class Enum(metaclass=EnumMeta):
  __members__: collections.OrderedDict[str, Enum]
  # These are copies of `name` and `value`. These are occasionally used in
  # methods on the enum, so set them here to guarantee pytype sees them.
  # Unlike `name` and `value`, these are never valid enum member names, so it's
  # fine to set them here.
  _name_: str
  _value_: Any
  name: str
  value: Any
  def __eq__(self, other: Any, /) -> bool: ...
  def __new__(cls, value: str, names: Union[str, Iterable[str], Iterable[Tuple[str, Any]], Dict[str, Any]], module = ..., type: type = ..., start: complex = ...) -> Type[Enum]: ...
  def __new__(cls: Type[_T], value) -> _T: ...

class IntEnum(int, Enum): ...

def unique(enumeration: _EnumType) -> _EnumType: ...

_auto_null: Any

class auto:
  value: Any
  def __init__(self) -> None: ...
  def __or__(self: _T, other: _T) -> _T: ...
  def __and__(self: _T, other: _T) -> _T: ...
  def __xor__(self: _T, other: _T) -> _T: ...
  def __invert__(self: _T) -> _T: ...

class Flag(Enum):
  def __contains__(self: _T, other: _T) -> bool: ...
  def __repr__(self) -> str: ...
  def __str__(self) -> str: ...
  def __bool__(self) -> bool: ...
  def __or__(self: _T, other: _T) -> _T: ...
  def __and__(self: _T, other: _T) -> _T: ...
  def __xor__(self: _T, other: _T) -> _T: ...
  def __invert__(self: _T) -> _T: ...

class IntFlag(int, Flag):
  def __or__(self: _T, other: Union[int, _T]) -> _T: ...
  def __and__(self: _T, other: Union[int, _T]) -> _T: ...
  def __xor__(self: _T, other: Union[int, _T]) -> _T: ...
  __ror__ = __or__
  __rand__ = __and__
  __rxor__ = __xor__

# 3.11: Not supported yet.
EnumType = EnumMeta

class StrEnum(str, Enum):
  # Workaround for b/201603421.
  @classmethod
  def __iter__(cls: Type[_T]) -> Iterator[_T]: ...

class ReprEnum: ...
class EnumCheck: ...
class FlagBoundary: ...
def verify(): ...
def property(): ...
def member(): ...
def nonmember(): ...
def global_enum(): ...
def show_flag_values(): ...
