Repository: psf/black
File: src/black/files.py (Python)

Code before:

    return config


def infer_target_version(pyproject_toml: Dict[str, Any]) -> Optional[TargetVersion]:
    """Infer Black's target version from the project metadata in pyproject.toml.

    If target version cannot be inferred, returns None.
    """
    requires_python = get_req_python(pyproject_toml)
    if requires_python is not None:
        return parse_req_python(requires_python)
    return None


def get_req_python(pyproject_toml: Dict[str, Any]) -> Optional[str]:
    """Get the required Python version from the project metadata.

    Currently only supports the PyPA standard format:
    https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#requires-python

    If the field is not present or cannot be parsed, returns None.
    """
    project_metadata = pyproject_toml.get("project", {})
    requires_python: Optional[str] = project_metadata.get("requires-python", None)
    return requires_python


def parse_req_python(requires_python: str) -> Optional[TargetVersion]:
    """Parse the requires-python field to determine Black's target version.

    If the field cannot be parsed, returns None.
    """
    try:
        return parse_req_python_version(requires_python)
    except InvalidVersion:
        pass
    try:
        return parse_req_python_specifier(requires_python)
    except InvalidSpecifier:
        pass
    return None


def parse_req_python_version(requires_python: str) -> Optional[TargetVersion]:
    """Parse a version string (i.e. ``"3.7"``) to a TargetVersion.

    If parsing fails, will raise a packaging.version.InvalidVersion error.
    If the parsed version cannot be mapped to a valid TargetVersion, returns None.
    """
    version = Version(requires_python)

Review comment (suggestion):
I'd prefer merging `get_req_python` into `infer_target_version` since IMO this module is gaining way too many tiny functions that it's actually hurting readability.

Code after:

    return config


def infer_target_version(
    pyproject_toml: Dict[str, Any]
) -> Optional[List[TargetVersion]]:
    """Infer Black's target version from the project metadata in pyproject.toml.

    Supports the PyPA standard format (PEP 621):
    https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#requires-python

    If the target version cannot be inferred, returns None.
    """
    project_metadata = pyproject_toml.get("project", {})
    requires_python = project_metadata.get("requires-python", None)
    if requires_python is not None:
        try:
            return parse_req_python_version(requires_python)
        except InvalidVersion:
            pass
        try:
            return parse_req_python_specifier(requires_python)
        except (InvalidSpecifier, InvalidVersion):
            pass

    return None


def parse_req_python_version(requires_python: str) -> Optional[List[TargetVersion]]:
    """Parse a version string (i.e. ``"3.7"``) to a list of TargetVersion.

    If parsing fails, will raise a packaging.version.InvalidVersion error.
    If the parsed version cannot be mapped to a valid TargetVersion, returns None.
    """
    version = Version(requires_python)
    if version.release[0] != 3:
        return None
    try:
        return [TargetVersion(version.release[1])]
    except (IndexError, ValueError):
        return None


def parse_req_python_specifier(requires_python: str) -> Optional[List[TargetVersion]]:
    """Parse a specifier string (i.e. ``">=3.7,<3.10"``) to a list of TargetVersion.

    If parsing fails, will raise a packaging.specifiers.InvalidSpecifier error.
    If the parsed specifier cannot be mapped to a valid TargetVersion, returns None.
    """
    specifier_set = strip_specifier_set(SpecifierSet(requires_python))