Skip to content

Commit c437a7c

Browse files
authored
Fix getting dynamic metadata from hooks for environments (#563)
1 parent dbcf6e7 commit c437a7c

File tree

9 files changed

+40
-16
lines changed

9 files changed

+40
-16
lines changed

docs/history.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1010

1111
### Unreleased
1212

13+
***Fixed:***
14+
15+
- Fix getting dynamic metadata from hooks for environments when dependencies are not dynamic
16+
1317
### [1.6.1](https://github.com/pypa/hatch/releases/tag/hatch-v1.6.1) - 2022-10-16 ### {: #hatch-v1.6.1 }
1418

1519
***Fixed:***

src/hatch/cli/version/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ def version(app, desired_version):
1616
from hatchling.dep.core import dependencies_in_sync
1717

1818
with app.project.location.as_cwd():
19-
dynamic_version = 'version' in app.project.metadata.dynamic
20-
if not dynamic_version or dependencies_in_sync(app.project.metadata.build.requires_complex):
19+
if not app.project.metadata.hatch.metadata.hook_config or dependencies_in_sync(
20+
app.project.metadata.build.requires_complex
21+
):
2122
source = app.project.metadata.hatch.version.source
2223

2324
version_data = source.get_version_data()

src/hatch/env/plugin/interface.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,6 @@ def features(self):
440440
if not isinstance(features, list):
441441
raise TypeError(f'Field `tool.hatch.envs.{self.name}.features` must be an array of strings')
442442

443-
dynamic_features = 'optional-dependencies' in self.metadata.dynamic
444443
all_features = set()
445444
for i, feature in enumerate(features, 1):
446445
if not isinstance(feature, str):
@@ -452,7 +451,10 @@ def features(self):
452451

453452
if not self.metadata.hatch.metadata.allow_ambiguous_features:
454453
feature = normalize_project_name(feature)
455-
if not dynamic_features and feature not in self.metadata.core.optional_dependencies:
454+
if (
455+
not self.metadata.hatch.metadata.hook_config
456+
and feature not in self.metadata.core.optional_dependencies
457+
):
456458
raise ValueError(
457459
f'Feature `{feature}` of field `tool.hatch.envs.{self.name}.features` is not '
458460
f'defined in field `project.optional-dependencies`'

src/hatch/utils/dep.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@ def get_project_dependencies_complex(environment):
1717
dependencies_complex = {}
1818
optional_dependencies_complex = {}
1919

20-
dynamic_fields = environment.metadata.dynamic
21-
if 'dependencies' not in dynamic_fields and 'optional-dependencies' not in dynamic_fields:
22-
dependencies_complex.update(environment.metadata.core.dependencies_complex)
23-
optional_dependencies_complex.update(environment.metadata.core.optional_dependencies_complex)
24-
elif dependencies_in_sync(environment.metadata.build.requires_complex):
20+
if not environment.metadata.hatch.metadata.hook_config or dependencies_in_sync(
21+
environment.metadata.build.requires_complex
22+
):
2523
dependencies_complex.update(environment.metadata.core.dependencies_complex)
2624
optional_dependencies_complex.update(environment.metadata.core.optional_dependencies_complex)
2725
else:

tests/cli/dep/show/test_requirements.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def test_incompatible_environment(hatch, temp_dir, helpers):
1313
project = Project(path)
1414
config = dict(project.raw_config)
1515
config['build-system']['requires'].append('foo')
16-
config['project']['dynamic'].append('dependencies')
16+
config['tool']['hatch']['metadata'] = {'hooks': {'custom': {}}}
1717
project.save_config(config)
1818
helpers.update_project_environment(
1919
project, 'default', {'skip-install': True, 'python': '9000', **project.config.envs['default']}

tests/cli/dep/show/test_table.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def test_incompatible_environment(hatch, temp_dir, helpers):
2222
project = Project(path)
2323
config = dict(project.raw_config)
2424
config['build-system']['requires'].append('foo')
25-
config['project']['dynamic'].append('dependencies')
25+
config['tool']['hatch']['metadata'] = {'hooks': {'custom': {}}}
2626
project.save_config(config)
2727
helpers.update_project_environment(
2828
project, 'default', {'skip-install': True, 'python': '9000', **project.config.envs['default']}

tests/cli/dep/test_hash.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def test_incompatible_environment(hatch, temp_dir, helpers):
1515
project = Project(path)
1616
config = dict(project.raw_config)
1717
config['build-system']['requires'].append('foo')
18-
config['project']['dynamic'].append('dependencies')
18+
config['tool']['hatch']['metadata'] = {'hooks': {'custom': {}}}
1919
project.save_config(config)
2020
helpers.update_project_environment(
2121
project, 'default', {'skip-install': True, 'python': '9000', **project.config.envs['default']}

tests/cli/version/test_version.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def test_incompatible_environment(hatch, temp_dir, helpers):
1414
project = Project(path)
1515
config = dict(project.raw_config)
1616
config['build-system']['requires'].append('foo')
17+
config['tool']['hatch']['metadata'] = {'hooks': {'custom': {}}}
1718
project.save_config(config)
1819
helpers.update_project_environment(
1920
project, 'default', {'skip-install': True, 'python': '9000', **project.config.envs['default']}

tests/env/plugin/test_interface.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from hatch.env.plugin.interface import EnvironmentInterface
55
from hatch.project.core import Project
66
from hatch.utils.structures import EnvVars
7+
from hatchling.utils.constants import DEFAULT_BUILD_SCRIPT
78

89

910
class MockEnvironment(EnvironmentInterface): # no cov
@@ -636,14 +637,31 @@ def test_full_dev_mode(self, isolation, isolated_data_dir, platform):
636637

637638
assert environment.dependencies == ['dep2', 'dep3']
638639

639-
def test_unknown_dynamic_feature(self, isolation, isolated_data_dir, platform):
640+
def test_unknown_dynamic_feature(self, helpers, temp_dir, isolated_data_dir, platform):
640641
config = {
641642
'project': {'name': 'my_app', 'version': '0.0.1', 'dynamic': ['optional-dependencies']},
642-
'tool': {'hatch': {'envs': {'default': {'skip-install': False, 'features': ['foo']}}}},
643+
'tool': {
644+
'hatch': {
645+
'metadata': {'hooks': {'custom': {}}},
646+
'envs': {'default': {'skip-install': False, 'features': ['foo']}},
647+
},
648+
},
643649
}
644-
project = Project(isolation, config=config)
650+
project = Project(temp_dir, config=config)
645651
environment = MockEnvironment(
646-
isolation, project.metadata, 'default', project.config.envs['default'], {}, isolated_data_dir, platform, 0
652+
temp_dir, project.metadata, 'default', project.config.envs['default'], {}, isolated_data_dir, platform, 0
653+
)
654+
655+
build_script = temp_dir / DEFAULT_BUILD_SCRIPT
656+
build_script.write_text(
657+
helpers.dedent(
658+
"""
659+
from hatchling.metadata.plugin.interface import MetadataHookInterface
660+
class CustomHook(MetadataHookInterface):
661+
def update(self, metadata):
662+
metadata['optional-dependencies'] = {'bar': ['binary']}
663+
"""
664+
)
647665
)
648666

649667
with pytest.raises(

0 commit comments

Comments
 (0)