Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type-hints for hatch/plugin and hatch/template #1693

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ warn_unused_ignores = true
module = [
"*.hatchling.*",
"*.hatch.utils.*",
"hatch.plugin.*",
"hatch.template.*",
]
disallow_untyped_defs = true
disallow_incomplete_defs = true
Expand Down
10 changes: 5 additions & 5 deletions src/hatch/plugin/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@


class PluginManager(_PluginManager):
def initialize(self):
def initialize(self) -> None:
super().initialize()

from hatch.plugin import specs

self.manager.add_hookspecs(specs)

def hatch_register_environment(self):
def hatch_register_environment(self) -> None:
from hatch.env.plugin import hooks

self.manager.register(hooks)

def hatch_register_environment_collector(self):
def hatch_register_environment_collector(self) -> None:
from hatch.env.collectors.plugin import hooks

self.manager.register(hooks)

def hatch_register_publisher(self):
def hatch_register_publisher(self) -> None:
from hatch.publish.plugin import hooks

self.manager.register(hooks)

def hatch_register_template(self):
def hatch_register_template(self) -> None:
from hatch.template.plugin import hooks

self.manager.register(hooks)
10 changes: 5 additions & 5 deletions src/hatch/plugin/specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@


@hookspec
def hatch_register_environment():
def hatch_register_environment() -> None:
"""Register new classes that adhere to the environment interface."""


@hookspec
def hatch_register_environment_collector():
def hatch_register_environment_collector() -> None:
"""Register new classes that adhere to the environment collector interface."""


@hookspec
def hatch_register_version_scheme():
def hatch_register_version_scheme() -> None:
"""Register new classes that adhere to the version scheme interface."""


@hookspec
def hatch_register_publisher():
def hatch_register_publisher() -> None:
"""Register new classes that adhere to the publisher interface."""


@hookspec
def hatch_register_template():
def hatch_register_template() -> None:
"""Register new classes that adhere to the template interface."""
8 changes: 5 additions & 3 deletions src/hatch/template/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from __future__ import annotations

from contextlib import suppress
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Generator

if TYPE_CHECKING:
from types import ModuleType

from hatch.utils.fs import Path


Expand All @@ -13,7 +15,7 @@ def __init__(self, path: Path | None, contents: str = ''):
self.contents = contents
self.feature = None

def write(self, root):
def write(self, root: Path) -> None:
if self.path is None: # no cov
return

Expand All @@ -22,7 +24,7 @@ def write(self, root):
path.write_text(self.contents, encoding='utf-8')


def find_template_files(module):
def find_template_files(module: ModuleType) -> Generator[File, None, None]:
for name in dir(module):
obj = getattr(module, name)
if obj is File:
Expand Down
23 changes: 15 additions & 8 deletions src/hatch/template/default.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any

from hatch.template import File, files_default, find_template_files
from hatch.template.plugin.interface import TemplateInterface
from hatch.utils.fs import Path
from hatch.utils.network import download_file

if TYPE_CHECKING:
from datetime import datetime


class DefaultTemplate(TemplateInterface):
PLUGIN_NAME = 'default'

def __init__(self, *args, **kwargs):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)

self.plugin_config.setdefault('ci', False)
self.plugin_config.setdefault('src-layout', True)
self.plugin_config.setdefault('tests', True)

def initialize_config(self, config):
def initialize_config(self, config: dict) -> None:
# Default values
config['readme_file_path'] = 'README.md'
config['package_metadata_file_path'] = f'src/{config["package_name"]}/__about__.py'

license_data = {}
license_data: dict[str, str] = {}

# Licenses
license_ids = config['licenses']['default']
Expand Down Expand Up @@ -73,7 +80,7 @@ def initialize_config(self, config):
if not self.plugin_config['src-layout']:
config['package_metadata_file_path'] = f'{config["package_metadata_file_path"][4:]}'

def get_files(self, config):
def get_files(self, config: dict) -> list[File]:
files = list(find_template_files(files_default))

# Add any licenses
Expand Down Expand Up @@ -106,19 +113,19 @@ def get_files(self, config):

return files

def finalize_files(self, config, files):
def finalize_files(self, config: dict, files: list[File]) -> None:
if config['licenses']['headers'] and config['license_data']:
for template_file in files:
if template_file.path.name.endswith('.py'):
if template_file.path and template_file.path.name.endswith('.py'):
template_file.contents = config['license_header'] + template_file.contents

if self.plugin_config['src-layout']:
for template_file in files:
if template_file.path.parts[0] == config['package_name']:
if template_file.path and template_file.path.parts[0] == config['package_name']:
template_file.path = Path('src', template_file.path)


def get_license_text(config, license_id, license_text, creation_time):
def get_license_text(config: dict, license_id: str, license_text: str, creation_time: datetime) -> str:
if license_id == 'MIT':
license_text = license_text.replace('<year>', f'{creation_time.year}-present', 1)
license_text = license_text.replace('<copyright holders>', f'{config["name"]} <{config["email"]}>', 1)
Expand Down
9 changes: 8 additions & 1 deletion src/hatch/template/plugin/hooks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from __future__ import annotations

from typing import TYPE_CHECKING

from hatch.template.default import DefaultTemplate
from hatchling.plugin import hookimpl

if TYPE_CHECKING:
from hatch.template.plugin.interface import TemplateInterface


@hookimpl
def hatch_register_template():
def hatch_register_template() -> type[TemplateInterface]:
return DefaultTemplate
19 changes: 15 additions & 4 deletions src/hatch/template/plugin/interface.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from datetime import datetime

from hatch.template import File
from hatch.utils.fs import Path


class TemplateInterface:
PLUGIN_NAME = ''
PRIORITY = 100

def __init__(self, plugin_config: dict, cache_dir, creation_time):
def __init__(self, plugin_config: dict, cache_dir: Path, creation_time: datetime) -> None:
self.plugin_config = plugin_config
self.cache_dir = cache_dir
self.creation_time = creation_time

def initialize_config(self, config):
def initialize_config(self, config: dict) -> None:
"""
Allow modification of the configuration passed to every file for new projects
before the list of files are determined.
"""

def get_files(self, config): # noqa: ARG002, PLR6301
def get_files(self, config: dict) -> list[File]: # noqa: ARG002, PLR6301
"""Add to the list of files for new projects that are written to the file system."""
return []

def finalize_files(self, config, files):
def finalize_files(self, config: dict, files: list[File]) -> None:
"""Allow modification of files for new projects before they are written to the file system."""
Loading