from collections.abc import Iterable, Iterator
from typing import NoReturn
from typing_extensions import Self, TypeAlias

from netaddr.ip import IPAddress, IPNetwork, IPRange, _IPNetworkAddr

_IPIterable: TypeAlias = IPNetwork | IPRange | IPSet | Iterable[_IPNetworkAddr | IPRange | int]

class IPSet:
    def __init__(self, iterable: _IPIterable | None = ..., flags: int = ...) -> None: ...
    def compact(self) -> None: ...
    def __hash__(self) -> NoReturn: ...
    def __contains__(self, ip: _IPNetworkAddr) -> bool: ...
    def __bool__(self) -> bool: ...
    def __iter__(self) -> Iterator[IPAddress]: ...
    def iter_cidrs(self) -> list[IPNetwork]: ...
    def add(self, addr: IPRange | _IPNetworkAddr | int, flags: int = ...) -> None: ...
    def remove(self, addr: IPRange | _IPNetworkAddr | int, flags: int = ...) -> None: ...
    def pop(self) -> IPNetwork: ...
    def isdisjoint(self, other: IPSet) -> bool: ...
    def copy(self) -> Self: ...
    def update(self, iterable: _IPIterable, flags: int = ...) -> None: ...
    def clear(self) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __lt__(self, other: IPSet) -> bool: ...
    def issubset(self, other: IPSet) -> bool: ...
    __le__ = issubset
    def __gt__(self, other: IPSet) -> bool: ...
    def issuperset(self, other: IPSet) -> bool: ...
    __ge__ = issuperset
    def union(self, other: IPSet) -> Self: ...
    __or__ = union
    def intersection(self, other: IPSet) -> IPSet: ...
    __and__ = intersection
    def symmetric_difference(self, other: IPSet) -> IPSet: ...
    __xor__ = symmetric_difference
    def difference(self, other: IPSet) -> IPSet: ...
    __sub__ = difference
    def __len__(self) -> int: ...
    @property
    def size(self) -> int: ...
    def iscontiguous(self) -> bool: ...
    def iprange(self) -> IPRange | None: ...
    def iter_ipranges(self) -> Iterator[IPRange]: ...
