from collections.abc import Iterator
from typing import Any

def drop_vcs_in_scheme(url: str) -> str: ...
def unsplit_vcs_url(repo_url: str, branch: str | None, subpath: str | None) -> str: ...
def probe_gitlab_host(hostname: str) -> bool: ...
def is_gitlab_site(hostname: str, net_access: bool | None = None) -> bool: ...
def guess_repo_from_url(url: str, net_access: bool | None = None) -> str | None: ...
def probe_gitlabb_host(hostname: str) -> bool: ...
def find_public_repo_url(url: str, net_access: bool | None = None) -> str | None: ...
def browse_url_from_repo_url(
    url: str,
    branch: str | None = None,
    subpath: str | None = None,
    net_access: bool | None = None,
) -> str | None: ...
def plausible_vcs_url(url: str) -> bool: ...
def plausible_vcs_browse_url(url: str) -> bool: ...
def probe_upstream_branch_url(url: str, version: str | None = None) -> bool | None: ...
def canonical_git_repo_url(url: str, net_access: bool | None = None) -> str: ...
def check_repository_url_canonical(url: str, version: str | None = None) -> str: ...
def known_bad_guess(datum: UpstreamDatum) -> bool: ...
def url_from_svn_co_command(command: bytes) -> str | None: ...
def url_from_git_clone_command(command: bytes) -> str | None: ...
def url_from_fossil_clone_command(command: bytes) -> str | None: ...
def url_from_cvs_co_command(command: bytes) -> str | None: ...
def url_from_vcs_command(command: bytes) -> str | None: ...
def find_forge(url: str, net_access: bool | None = None) -> Forge | None: ...
def repo_url_from_merge_request_url(
    url: str, net_access: bool | None = None
) -> str | None: ...
def bug_database_from_issue_url(
    url: str, net_access: bool | None = None
) -> str | None: ...
def guess_bug_database_url_from_repo_url(
    url: str, net_access: bool | None = None
) -> str | None: ...
def bug_database_url_from_bug_submit_url(
    url: str, net_access: bool | None = None
) -> str | None: ...
def bug_submit_url_from_bug_database_url(
    url: str, net_access: bool | None = None
) -> str | None: ...
def check_bug_database_canonical(url: str, net_access: bool | None = None) -> str: ...
def check_bug_submit_url_canonical(url: str, net_access: bool | None = None) -> str: ...
def check_url_canonical(url: str) -> str: ...
def fixup_rcp_style_git_repo_url(url: str) -> str: ...
def check_upstream_metadata(data: UpstreamMetadata) -> None: ...

class ParseError(Exception): ...
class NoSuchForgeProject(Exception): ...

class Forge:
    @classmethod
    def extend_metadata(
        cls, upstream_metadata: UpstreamMetadata, project: str, certainty: str
    ) -> None: ...

    repository_browse_can_be_homepage: bool

class GitHub(Forge): ...
class GitLab(Forge): ...
class SourceForge(Forge): ...
class Launchpad(Forge): ...

SECURE_SCHEMES: list[str]
KNOWN_GITLAB_SITES: list[str]

def find_secure_repo_url(
    url: str, branch: str | None = None, net_access: bool | None = None
) -> str | None: ...
def sanitize_url(url: str) -> str: ...
def convert_cvs_list_to_str(cvs_list: list[str]) -> str: ...
def fixup_broken_git_details(
    url: str, branch: str | None = None, subpath: str | None = None
) -> tuple[str, str | None, str | None]: ...
def guess_upstream_info(
    path: str, trust_package: bool = False
) -> list[UpstreamDatum]: ...
def get_upstream_info(
    path: str,
    trust_package: bool = False,
    net_access: bool | None = None,
    consult_external_directory: bool = True,
    check: bool = True,
) -> UpstreamMetadata: ...
def extend_upstream_metadata(
    upstream_metadata: UpstreamMetadata,
    path: str,
    minimum_certainty: str,
    net_access: bool | None = None,
    consult_external_directory: bool = True,
) -> None: ...
def guess_upstream_metadata(
    path: str,
    trust_package: bool | None = None,
    net_access: bool | None = None,
    consult_external_directory: bool | None = None,
    check: bool | None = None,
) -> UpstreamMetadata: ...
def fix_upstream_metadata(upstream_metadata: UpstreamMetadata) -> None: ...
def guess_upstream_metadata_items(
    path: str, trust_package: bool | None = None, minimum_certainty: str | None = None
) -> Iterator[UpstreamDatum]: ...
def update_from_guesses(
    upstream_metadata: UpstreamMetadata,
    items: list[UpstreamDatum],
) -> list[UpstreamDatum]: ...

class UpstreamMetadata:
    def __init__(self, **kwargs): ...
    ...

    @classmethod
    def from_dict(cls, data, default_certainty: str | None = None): ...

class UpstreamDatum:
    def __init__(self, name, value: Any, certainty: str | None = None): ...  # noqa: ANN401

__version__: str
