Skip to content

Commit

Permalink
Merge branch 'master' into hatch-pyz
Browse files Browse the repository at this point in the history
  • Loading branch information
djcopley authored Aug 22, 2024
2 parents 843d3e0 + e07d298 commit 0bbcc6a
Show file tree
Hide file tree
Showing 28 changed files with 142 additions and 59 deletions.
4 changes: 2 additions & 2 deletions backend/src/hatchling/builders/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
class CustomBuilder(Generic[PluginManagerBound]):
PLUGIN_NAME = 'custom'

def __new__( # type: ignore
def __new__( # type: ignore[misc]
cls,
root: str,
plugin_manager: PluginManagerBound | None = None,
Expand Down Expand Up @@ -45,7 +45,7 @@ def __new__( # type: ignore
message = f'Build script does not exist: {build_script}'
raise OSError(message)

hook_class = load_plugin_from_script(path, build_script, BuilderInterface, 'builder') # type: ignore
hook_class = load_plugin_from_script(path, build_script, BuilderInterface, 'builder') # type: ignore[type-abstract]
hook = hook_class(root, plugin_manager=plugin_manager, config=config, metadata=metadata, app=app)

# Always keep the name to avoid confusion
Expand Down
2 changes: 1 addition & 1 deletion backend/src/hatchling/builders/hooks/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class CustomBuildHook:
PLUGIN_NAME = 'custom'

def __new__( # type: ignore
def __new__( # type: ignore[misc]
cls,
root: str,
config: dict[str, Any],
Expand Down
2 changes: 1 addition & 1 deletion backend/src/hatchling/builders/hooks/plugin/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@

@hookimpl
def hatch_register_build_hook() -> list[type[BuildHookInterface]]:
return [CustomBuildHook, VersionBuildHook] # type: ignore
return [CustomBuildHook, VersionBuildHook] # type: ignore[list-item]
2 changes: 1 addition & 1 deletion backend/src/hatchling/builders/plugin/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@

@hookimpl
def hatch_register_builder() -> list[type[BuilderInterface]]:
return [AppBuilder, BinaryBuilder, CustomBuilder, SdistBuilder, WheelBuilder] # type: ignore
return [AppBuilder, BinaryBuilder, CustomBuilder, SdistBuilder, WheelBuilder] # type: ignore[list-item]
4 changes: 2 additions & 2 deletions backend/src/hatchling/cli/dep/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def dependencies_in_sync(
if sys_path is None:
sys_path = sys.path
if environment is None:
environment = default_environment() # type: ignore
environment = default_environment() # type: ignore[assignment]

installed_distributions = DistributionCache(sys_path)
return all(dependency_in_sync(requirement, environment, installed_distributions) for requirement in requirements) # type: ignore
return all(dependency_in_sync(requirement, environment, installed_distributions) for requirement in requirements) # type: ignore[arg-type]
4 changes: 2 additions & 2 deletions backend/src/hatchling/metadata/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class CustomMetadataHook:
PLUGIN_NAME = 'custom'

def __new__( # type: ignore
def __new__( # type: ignore[misc]
cls,
root: str,
config: dict[str, Any],
Expand All @@ -32,7 +32,7 @@ def __new__( # type: ignore
message = f'Build script does not exist: {build_script}'
raise OSError(message)

hook_class = load_plugin_from_script(path, build_script, MetadataHookInterface, 'metadata_hook') # type: ignore
hook_class = load_plugin_from_script(path, build_script, MetadataHookInterface, 'metadata_hook') # type: ignore[type-abstract]
hook = hook_class(root, config, *args, **kwargs)

# Always keep the name to avoid confusion
Expand Down
2 changes: 1 addition & 1 deletion backend/src/hatchling/metadata/plugin/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@

@hookimpl
def hatch_register_metadata_hook() -> type[MetadataHookInterface]:
return CustomMetadataHook # type: ignore
return CustomMetadataHook # type: ignore[return-value]
2 changes: 1 addition & 1 deletion backend/src/hatchling/metadata/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def project_metadata_from_core_metadata(core_metadata: str) -> dict[str, Any]:
header_registry = HeaderRegistry()

message = email.message_from_string(core_metadata)
metadata = {}
metadata: dict[str, Any] = {}

if name := message.get('Name'):
metadata['name'] = name
Expand Down
4 changes: 2 additions & 2 deletions backend/src/hatchling/plugin/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ def load_plugin_from_script(path: str, script_name: str, plugin_class: type[T],
from importlib.util import module_from_spec, spec_from_file_location

spec = spec_from_file_location(script_name, path)
module = module_from_spec(spec) # type: ignore
spec.loader.exec_module(module) # type: ignore
module = module_from_spec(spec) # type: ignore[arg-type]
spec.loader.exec_module(module) # type: ignore[union-attr]

plugin_finder = f'get_{plugin_id}'
names = dir(module)
Expand Down
4 changes: 4 additions & 0 deletions backend/src/hatchling/utils/constants.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
DEFAULT_BUILD_SCRIPT = 'hatch_build.py'
DEFAULT_CONFIG_FILE = 'hatch.toml'


class VersionEnvVars:
VALIDATE_BUMP = 'HATCH_VERSION_VALIDATE_BUMP'
2 changes: 1 addition & 1 deletion backend/src/hatchling/version/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def read(self, *, pattern: str | bool) -> str:
return self.__cached_read_data[0]

def set_version(self, version: str) -> None:
_old_version, file_contents, (start, end) = self.__cached_read_data # type: ignore
_old_version, file_contents, (start, end) = self.__cached_read_data # type: ignore[misc]
with open(self.__path, 'w', encoding='utf-8') as f:
f.write(f'{file_contents[:start]}{version}{file_contents[end:]}')

Expand Down
30 changes: 28 additions & 2 deletions backend/src/hatchling/version/scheme/plugin/interface.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import annotations

import os
from abc import ABC, abstractmethod
from functools import cached_property


class VersionSchemeInterface(ABC): # no cov
Expand Down Expand Up @@ -51,9 +53,33 @@ def config(self) -> dict:
"""
return self.__config

@cached_property
def validate_bump(self) -> bool:
"""
This is the value of the `validate-bump` option, with the `HATCH_VERSION_VALIDATE_BUMP`
environment variable taking precedence. Validation is enabled by default.
```toml config-example
[tool.hatch.version]
validate-bump = true
```
"""
from hatchling.utils.constants import VersionEnvVars

if VersionEnvVars.VALIDATE_BUMP in os.environ:
return os.environ[VersionEnvVars.VALIDATE_BUMP] not in {'false', '0'}

validate_bump = self.config.get('validate-bump', True)
if not isinstance(validate_bump, bool):
message = 'option `validate-bump` must be a boolean'
raise TypeError(message)

return validate_bump

@abstractmethod
def update(self, desired_version: str, original_version: str, version_data: dict) -> str:
"""
This should return a normalized form of the desired version and verify that it
is higher than the original version.
This should return a normalized form of the desired version. If the
[validate_bump](reference.md#hatchling.version.scheme.plugin.interface.VersionSchemeInterface.validate_bump)
property is `True`, this method should also verify that the version is higher than the original version.
"""
2 changes: 1 addition & 1 deletion backend/src/hatchling/version/scheme/standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def update(
raise ValueError(message)

next_version = Version(version)
if self.config.get('validate-bump', True) and next_version <= original:
if self.validate_bump and next_version <= original:
message = f'Version `{version}` is not higher than the original version `{original_version}`'
raise ValueError(message)

Expand Down
4 changes: 2 additions & 2 deletions backend/src/hatchling/version/source/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ def get_version_data(self) -> dict:
absolute_search_paths.append(os.path.normpath(os.path.join(self.root, search_path)))

spec = spec_from_file_location(os.path.splitext(path)[0], path)
module = module_from_spec(spec) # type: ignore
module = module_from_spec(spec) # type: ignore[arg-type]

old_search_paths = list(sys.path)
try:
sys.path[:] = [*absolute_search_paths, *old_search_paths]
spec.loader.exec_module(module) # type: ignore
spec.loader.exec_module(module) # type: ignore[union-attr]
finally:
sys.path[:] = old_search_paths

Expand Down
17 changes: 9 additions & 8 deletions docs/community/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The usual process to make a contribution is to:
1. Check for existing related issues
2. Fork the repository and create a new branch
3. Make your changes
4. Make sure formatting, linting and tests passes.
4. Make sure formatting, linting and tests passes.
5. Add tests if possible to cover the lines you added.
6. Commit, and send a Pull Request.

Expand All @@ -15,41 +15,42 @@ Clone the `hatch` repository, `cd` into it, and create a new branch for your con

```bash
cd hatch
git checkout -b add-my-contribution
git switch -c add-my-contribution
```

## Run the tests

Run the test suite while developing:

```bash
hatch run dev
hatch test
```

Run the test suite with coverage report:

```bash
hatch run cov
hatch test --cover
```

Run the extended test suite with coverage:

```bash
hatch run full
hatch test --cover --all
```

## Lint

Run automated formatting:

```bash
hatch run lint:fmt
hatch fmt
```

Run full linting and type checking:

```bash
hatch run lint:all
hatch fmt --check
hatch run types:check
```

## Docs
Expand All @@ -64,4 +65,4 @@ Build and validate the documentation website:

```bash
hatch run docs:build-check
```
```
1 change: 1 addition & 0 deletions docs/history/hatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
***Added:***

- The `version` and `project metadata` commands now support projects that do not use Hatchling as the build backend
- The `version` command accepts a `--force` option, allowing for downgrades when an explicit version number is given.
- Build environments can now be configured, the default build environment is `hatch-build`
- The environment interface now has the following methods and properties in order to better support builds on remote machines: `project_root`, `sep`, `pathsep`, `fs_context`

Expand Down
1 change: 1 addition & 0 deletions docs/plugins/version-scheme/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
- PLUGIN_NAME
- root
- config
- validate_bump
- update
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ exclude = [
[tool.mypy]
disallow_untyped_defs = false
disallow_incomplete_defs = false
enable_error_code = ["ignore-without-code", "truthy-bool"]
follow_imports = "normal"
ignore_missing_imports = true
pretty = true
show_column_numbers = true
show_error_codes = true
warn_no_return = false
warn_unused_ignores = true

Expand Down
8 changes: 4 additions & 4 deletions src/hatch/cli/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def __init__(
is_interactive: bool,
verbosity: int,
spinner_style: str,
waiting_style: Style,
success_style: Style,
waiting_style: Style | str,
success_style: Style | str,
initializer: Callable,
finalizer: Callable,
):
Expand Down Expand Up @@ -331,8 +331,8 @@ def status(self) -> BorrowedStatus:
is_interactive=self.console.is_interactive,
verbosity=self.verbosity,
spinner_style=self._style_spinner,
waiting_style=self._style_level_waiting, # type: ignore[arg-type]
success_style=self._style_level_success, # type: ignore[arg-type]
waiting_style=self._style_level_waiting,
success_style=self._style_level_success,
initializer=lambda: setattr(self.platform, 'displaying_status', True), # type: ignore[attr-defined]
finalizer=lambda: setattr(self.platform, 'displaying_status', False), # type: ignore[attr-defined]
)
Expand Down
30 changes: 11 additions & 19 deletions src/hatch/cli/version/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@

@click.command(short_help="View or set a project's version")
@click.argument('desired_version', required=False)
@click.option(
'--force',
'-f',
is_flag=True,
help='Allow an explicit downgrading version to be given',
)
@click.pass_obj
def version(app: Application, desired_version: str | None):
def version(app: Application, *, desired_version: str | None, force: bool):
"""View or set a project's version."""
if app.project.root is None:
if app.project.chosen_name is None:
Expand All @@ -26,6 +32,7 @@ def version(app: Application, desired_version: str | None):
app.display(app.project.metadata.config['project']['version'])
return

from hatch.config.constants import VersionEnvVars
from hatch.project.constants import BUILD_BACKEND

with app.project.location.as_cwd():
Expand All @@ -40,33 +47,18 @@ def version(app: Application, desired_version: str | None):
project_metadata = app.project.build_frontend.get_core_metadata()

app.display(project_metadata['version'])
elif 'version' not in app.project.metadata.dynamic:
source = app.project.metadata.hatch.version.source

version_data = source.get_version_data()
original_version = version_data['version']

if not desired_version:
app.display(original_version)
return

updated_version = app.project.metadata.hatch.version.scheme.update(
desired_version, original_version, version_data
)
source.set_version(updated_version, version_data)

app.display_info(f'Old: {original_version}')
app.display_info(f'New: {updated_version}')
else:
from hatch.utils.runner import ExecutionContext

app.ensure_environment_plugin_dependencies()
app.project.prepare_build_environment()

context = ExecutionContext(app.project.build_env)
command = ['python', '-u', '-m', 'hatchling', 'version']
if desired_version:
command.append(desired_version)
if force:
context.env_vars[VersionEnvVars.VALIDATE_BUMP] = 'false'

context = ExecutionContext(app.project.build_env)
context.add_shell_command(command)
app.execute_context(context)
4 changes: 4 additions & 0 deletions src/hatch/config/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ class PythonEnvVars:
CUSTOM_SOURCE_PREFIX = 'HATCH_PYTHON_CUSTOM_SOURCE_'
CUSTOM_PATH_PREFIX = 'HATCH_PYTHON_CUSTOM_PATH_'
CUSTOM_VERSION_PREFIX = 'HATCH_PYTHON_CUSTOM_VERSION_'


class VersionEnvVars:
VALIDATE_BUMP = 'HATCH_VERSION_VALIDATE_BUMP'
4 changes: 2 additions & 2 deletions src/hatch/dep/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def dependencies_in_sync(
if sys_path is None:
sys_path = sys.path
if environment is None:
environment = default_environment() # type: ignore
environment = default_environment() # type: ignore[assignment]

installed_distributions = DistributionCache(sys_path)
return all(dependency_in_sync(requirement, environment, installed_distributions) for requirement in requirements) # type: ignore
return all(dependency_in_sync(requirement, environment, installed_distributions) for requirement in requirements) # type: ignore[arg-type]
2 changes: 1 addition & 1 deletion src/hatch/env/collectors/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class CustomEnvironmentCollector:
PLUGIN_NAME = 'custom'

def __new__( # type: ignore
def __new__( # type: ignore[misc]
cls,
root: str,
config: dict[str, Any],
Expand Down
2 changes: 1 addition & 1 deletion src/hatch/env/collectors/plugin/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@

@hookimpl
def hatch_register_environment_collector() -> list[type[EnvironmentCollectorInterface]]:
return [CustomEnvironmentCollector, DefaultEnvironmentCollector] # type: ignore
return [CustomEnvironmentCollector, DefaultEnvironmentCollector] # type: ignore[list-item]
4 changes: 2 additions & 2 deletions src/hatch/plugin/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def load_plugin_from_script(
from importlib.util import module_from_spec, spec_from_file_location

spec = spec_from_file_location(script_name, path)
module = module_from_spec(spec) # type: ignore
spec.loader.exec_module(module) # type: ignore
module = module_from_spec(spec) # type: ignore[arg-type]
spec.loader.exec_module(module) # type: ignore[union-attr]

plugin_finder = f'get_{plugin_id}'
names = dir(module)
Expand Down
Loading

0 comments on commit 0bbcc6a

Please sign in to comment.