<commit_before>from abc import ABC, abstractmethod
from contextlib import ExitStack
from shutil import copyfileobj
import os
from tempfile import mkstemp
from types import TracebackType
from typing import Any, BinaryIO, Callable, cast, Dict, Generic, Iterable, List, Optional, Tuple, Type, TypeVar, Union

from .params import ParamSet, Resolvable, resolve
from .io import ensure_writeable, PathType, PrimitivePathType, ReadOpenable, resolve_writable, Writeable, WriteOpenableWrapBinaryIO
from .utils import consume, listify

_T = TypeVar('_T')
_S = TypeVar('_S')
_T_contra = TypeVar('_T_contra', contravariant=True)

# TODO: Check covariant-ness
# Does that even matter? No information about individual results is
# extractable from Collector instances and Collector instances are not
# commonly passed as arguments to other functions.
# In that sense, a Collector is a write-only container. Write-only containers
# should be contra-variant: A function accepting a Collector for type _T
# elements will happily work with an collector for any super-type of _T.
# The elements written by the function are both an instance of _T and of any super-type of _T


class Collector(Generic[_T_contra], ABC):
    """Collects and processes per-parameter set results.

    Collector provides the context manager interface. Each collector is a
    non-reentrent context manager. Any long-held resources will only be
    acquired upon entering the context manager, i.e. by opening an aggregation
    file. These resources will be released when exiting the context manager,
    i.e. closing all open files.
    """

    def __enter__(self) -> 'Collector[_T_contra]':
        pass

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]] = None,
        exc_val: Optional[BaseException] = None,
        exc_tb: Optional[TracebackType] = None,
    ) -> Optional[bool]:
        return None

    @abstractmethod
    def collect(self, results: Iterable[Tuple[ParamSet, _T_contra]]) -> None:
        """Collects and processes all elements within ``results``.

        This method **must** be called while the context manager is in the
        open state.

        Collect may be called never, once or multiple times.

        Args:
            results: Iterable over tuples of the parameter set with the
                associated result.
        """

        raise NotImplementedError()

<commit_msg>Fix __enter__() method in Collector base class<commit_after>from abc import ABC, abstractmethod
from contextlib import ExitStack
from shutil import copyfileobj
import os
from tempfile import mkstemp
from types import TracebackType
from typing import Any, BinaryIO, Callable, cast, Dict, Generic, Iterable, List, Optional, Tuple, Type, TypeVar, Union

from .params import ParamSet, Resolvable, resolve
from .io import ensure_writeable, PathType, PrimitivePathType, ReadOpenable, resolve_writable, Writeable, WriteOpenableWrapBinaryIO
from .utils import consume, listify

_T = TypeVar('_T')
_S = TypeVar('_S')
_T_contra = TypeVar('_T_contra', contravariant=True)

# TODO: Check covariant-ness
# Does that even matter? No information about individual results is
# extractable from Collector instances and Collector instances are not
# commonly passed as arguments to other functions.
# In that sense, a Collector is a write-only container. Write-only containers
# should be contra-variant: A function accepting a Collector for type _T
# elements will happily work with an collector for any super-type of _T.
# The elements written by the function are both an instance of _T and of any super-type of _T


class Collector(Generic[_T_contra], ABC):
    """Collects and processes per-parameter set results.

    Collector provides the context manager interface. Each collector is a
    non-reentrent context manager. Any long-held resources will only be
    acquired upon entering the context manager, i.e. by opening an aggregation
    file. These resources will be released when exiting the context manager,
    i.e. closing all open files.
    """

    def __enter__(self) -> 'Collector[_T_contra]':
        return self

    def __exit__(
        self,
        exc_type: Optional[Type[BaseException]] = None,
        exc_val: Optional[BaseException] = None,
        exc_tb: Optional[TracebackType] = None,
    ) -> Optional[bool]:
        return None

    @abstractmethod
    def collect(self, results: Iterable[Tuple[ParamSet, _T_contra]]) -> None:
        """Collects and processes all elements within ``results``.

        This method **must** be called while the context manager is in the
        open state.

        Collect may be called never, once or multiple times.

        Args:
            results: Iterable over tuples of the parameter set with the
                associated result.
        """

        raise NotImplementedError()


{'fraction_non_alphanumeric': 0.06727197688815519, 'fraction_numerical': 0.0, 'mean_word_length': 3.633843212237094, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, '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': '4188455', 'n_tokens_mistral': 1294, 'n_tokens_neox': 1262, 'n_words': 555}