<commit_before>import abc
import collections
import typing
import warnings
from typing import AbstractSet, Deque, Dict, Iterator, Iterable, Optional, Set, Tuple

from ..utils.meta import roundrepr

if typing.TYPE_CHECKING:
    from ..term import Term, TermSet
    from ..relationship import Relationship
    from ..ontology import Ontology


@roundrepr
class Lineage(object):
    """An internal type to store the superclasses and subclasses of a term.

    Used in `Ontology` to cache subclassing relationships between terms since
    only the superclassing relationships are explicitly declared in source
    documents.
    """

    __slots__ = ("sub", "sup")

    def __init__(
        self,
        sub: Optional[AbstractSet[str]] = None,
        sup: Optional[AbstractSet[str]] = None,
    ):
        self.sub: Set[str] = set(sub) if sub is not None else set()  # type: ignore
        self.sup: Set[str] = set(sup) if sup is not None else set()  # type: ignore

    def __eq__(self, other: object) -> bool:
        if isinstance(other, Lineage):
            return self.sub == other.sub and self.sup == other.sup
        return False

    # `Lineage` is mutable so this is the explicit way to tell it's unhashable
    # (see https://docs.python.org/3/reference/datamodel.html#object.__hash__)
    __hash__ = None



class LineageHandler(Iterable["Term"]):

    def __init__(self, term: "Term", distance: int, with_self: Optional[int]):
        self.term = term
        self.distance = distance
        self.with_self = with_self
        # API compatibilty with previous iterator
        self._it = None

    def __next__(self):
        if self._it is None:
            warnings.warn(
                "`Term.subclasses()` and `Term.superclasses()` will not return"
                "iterator in next major version, but iterables. Update your "
                "code to use `iter(...)` if needed.",
                category=DeprecationWarning,
                stacklevel=2,
            )
            self._it = iter(self)
        return next(self._it)

    def to_set(self):
        return iter(self).to_set()

    def _add(self, subclass: "Term", superclass: "Term"):
        if superclass._ontology() is not subclass._ontology():
            raise ValueError("cannot use `Term` instances from different ontologies")
        cache = subclass._ontology()._inheritance
        cache[subclass.id].sup.add(superclass.id)
        cache[superclass.id].sub.add(subclass.id)<commit_msg>Fix type annotation of `LineageHandler` to accept `None` as distance argument<commit_after>import abc
import collections
import typing
import warnings
from typing import AbstractSet, Deque, Dict, Iterator, Iterable, Optional, Set, Tuple

from ..utils.meta import roundrepr

if typing.TYPE_CHECKING:
    from ..term import Term, TermSet
    from ..relationship import Relationship
    from ..ontology import Ontology


@roundrepr
class Lineage(object):
    """An internal type to store the superclasses and subclasses of a term.

    Used in `Ontology` to cache subclassing relationships between terms since
    only the superclassing relationships are explicitly declared in source
    documents.
    """

    __slots__ = ("sub", "sup")

    def __init__(
        self,
        sub: Optional[AbstractSet[str]] = None,
        sup: Optional[AbstractSet[str]] = None,
    ):
        self.sub: Set[str] = set(sub) if sub is not None else set()  # type: ignore
        self.sup: Set[str] = set(sup) if sup is not None else set()  # type: ignore

    def __eq__(self, other: object) -> bool:
        if isinstance(other, Lineage):
            return self.sub == other.sub and self.sup == other.sup
        return False

    # `Lineage` is mutable so this is the explicit way to tell it's unhashable
    # (see https://docs.python.org/3/reference/datamodel.html#object.__hash__)
    __hash__ = None



class LineageHandler(Iterable["Term"]):

    def __init__(self, term: "Term", distance: Optional[int], with_self: Optional[int]):
        self.term = term
        self.distance = distance
        self.with_self = with_self
        # TODO: API compatibilty with previous iterator (remove for v3.0.0)
        self._it = None

    def __next__(self):
        if self._it is None:
            warnings.warn(
                "`Term.subclasses()` and `Term.superclasses()` will not return"
                "iterator in next major version, but iterables. Update your "
                "code to use `iter(...)` if needed.",
                category=DeprecationWarning,
                stacklevel=2,
            )
            self._it = iter(self)
        return next(self._it)

    def to_set(self):
        return iter(self).to_set()

    def _add(self, subclass: "Term", superclass: "Term"):
        if superclass._ontology() is not subclass._ontology():
            raise ValueError("cannot use `Term` instances from different ontologies")
        cache = subclass._ontology()._inheritance
        cache[subclass.id].sup.add(superclass.id)
        cache[superclass.id].sub.add(subclass.id)
{'fraction_non_alphanumeric': 0.10098814229249012, 'fraction_numerical': 0.001383399209486166, 'mean_word_length': 2.6175839885632595, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3914093', 'n_tokens_mistral': 1458, 'n_tokens_neox': 1401, 'n_words': 465}