<commit_before>from __future__ import annotations

import collections
import dataclasses
import functools
import inspect
import typing
from typing import Any, Callable, NamedTuple, Optional, Type, TypeVar

import docstring_parser as dp
from typing_extensions import ParamSpec

from . import helpers, parsing

T = TypeVar("T")
P = ParamSpec("P")


class _Field(NamedTuple):
    name: str
    annotation: Type
    field: dataclasses.Field


def _description_from_docstring(docstring: dp.Docstring) -> str:
    """Construct a description from the short and long description of a docstring."""
    description = ""
    if docstring.short_description:
        description += f"{docstring.short_description}\n"
        if docstring.blank_after_short_description:
            description += "\n"
    if docstring.long_description:
        description += f"{docstring.long_description}\n"
        if docstring.blank_after_long_description:
            description += "\n"
    return description


def main(
    original_function: Optional[Callable[P, T]] = None,
    **sp_kwargs,
) -> Callable[P, T]:
    """Parse a function's arguments using simple-parsing from type annotations."""

    def _decorate_with_cli_args(function: Callable[P, T]) -> Callable[P, T]:
        """Decorate `function` by binding its arguments obtained from simple-parsing."""

        @functools.wraps(function)
        def _wrapper(*other_args: P.args, **other_kwargs: P.kwargs) -> T:
            # Parse signature and parameters
            signature = inspect.signature(function, follow_wrapped=True)
            parameters = signature.parameters

            # Parse docstring to use as help strings<commit_msg>Fix typing for sp.main decorator (#177)<commit_after>from __future__ import annotations

import collections
import dataclasses
import functools
import inspect
import typing
from typing import Any, Callable, NamedTuple, Type

import docstring_parser as dp

from . import helpers, parsing


class _Field(NamedTuple):
    name: str
    annotation: Type
    field: dataclasses.Field


def _description_from_docstring(docstring: dp.Docstring) -> str:
    """Construct a description from the short and long description of a docstring."""
    description = ""
    if docstring.short_description:
        description += f"{docstring.short_description}\n"
        if docstring.blank_after_short_description:
            description += "\n"
    if docstring.long_description:
        description += f"{docstring.long_description}\n"
        if docstring.blank_after_long_description:
            description += "\n"
    return description


@typing.overload
def main(
    original_function: None = None, **sp_kwargs
) -> Callable[..., Callable[..., Any]]:
    ...


@typing.overload
def main(original_function: Callable[..., Any], **sp_kwargs) -> Callable[..., Any]:
    ...


def main(original_function=None, **sp_kwargs):
    """Parse a function's arguments using simple-parsing from type annotations."""

    def _decorate_with_cli_args(function: Callable[..., Any]) -> Callable[..., Any]:
        """Decorate `function` by binding its arguments obtained from simple-parsing."""

        @functools.wraps(function)
        def _wrapper(*other_args, **other_kwargs) -> Any:
            # Parse signature and parameters
            signature = inspect.signature(function, follow_wrapped=True)
            parameters = signature.parameters

            # Parse docstring to use as help strings
{'fraction_non_alphanumeric': 0.09956709956709957, 'fraction_numerical': 0.0008658008658008658, 'mean_word_length': 3.420918367346939, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, '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': '7530353', 'n_tokens_mistral': 964, 'n_tokens_neox': 933, 'n_words': 280}