Giter Site home page Giter Site logo

hatch-requirements-txt's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

hatch-requirements-txt's Issues

Won't read files generated by pip-compile

Description

I have requirements files generated by pip-tools' compiler, which include index URLS, hashes and \ line wrap markers. The packaging module used by hatch-requirements-txt won't read these.

Steps to Reproduce

Example file:

alembic==1.9.1 \
    --hash=sha256:a9781ed0979a20341c2cbb56bd22bd8db4fc1913f955e705444bd3a97c59fa32 \
    --hash=sha256:f9f76e41061f5ebe27d4fe92600df9dd612521a7683f904dab328ba02cffa5a2

Actual result:

The tail end of the traceback:

  File "/home/juledwar/.local/share/hatch/env/virtual/helios/mzodncRb/helios-build/lib/python3.10/site-packages/hatch_requirements_txt/__init__.py", line 65, in parse_requirements
    req = Requirement(line)
  File "/home/juledwar/.local/share/hatch/env/virtual/helios/mzodncRb/helios-build/lib/python3.10/site-packages/packaging/requirements.py", line 37, in __init__
    raise InvalidRequirement(str(e)) from e
packaging.requirements.InvalidRequirement: Expected end or semicolon (after version specifier)
    alembic==1.9.1 \

Expected result:

A parsed requirements file.

Reproduces how often:

Trivially.

Version

  • Operating System: Linux
  • Python: 3.10
  • hatch-requirements-txt: latest

Installation source

pypi

Other Additional Information:

If there's a --index at the top of the file (a valid pip directive) it also fails to parse.

It seems like there's a large gap between what pip can use and what this project can handle.

Infer `files` from dependencies or support globs

Can't files be inferred from dependencies and optional-dependecies by checking if the dependency has an extension (.txt or .in)?

If we really can't remove files, it'd be great to support globs/regular expressions so that one can do:

files = ["requirements/*.txt"]

Info to add optional-dependencies in readme is missing.

Description

The readme.rst file does not mention that you need to add the optional-dependencies to the dynamic list for it to work.

Steps to Reproduce

  1. Follow instructions as per readme for adding plugin
  2. use optional dependencies.
  3. Try to install (pip install -e .)

Actual result:

ValueError: Cannot specify 'optional-dependencies' in [tool.hatch.metadata.hooks.requirements_txt] when 'optional-dependencies' is not listed in 'project.dynamic'.

Expected result:

Successfully installed...`

Reproduces how often:

Easily reproduced

Version

  • Operating System: Ubuntu on WSL
  • Python: 3.10
  • hatch-requirements-txt: 0.4.0

Installation source

Other Additional Information:

If this is an omission in the readme, this is easily fixed by adding a note saying "optional-dependencies" needs to be added to the dynamic list.

Recommend setting upper pin on hatch-requirements-txt

In build-system.requires I think we should pin hatch-requirements-txt<2 in order to leverage semver so that we can publish breaking changes (like deprecation). But we are in this weird <1.0 pre-release realm, so maybe it would make sense to also do a 1.0 release? I don't really have strong feelings, but I wanted to float the idea in the context of the changes being currently proposed.

Parse error on indented comments (e.g. pip-compile output)

Description

In requirements.txt, comments preceded by whitespace are not recognized as comment lines. pip-tools is one tool that outputs indented comments, which pip has no difficulty with.

Steps to Reproduce

Add a line such as:

    # Indented comment

to your requirements.txt and build.

Actual result:

> pip wheel -w dist --no-deps .
Processing [redacted]
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [44 lines of output]
      Traceback (most recent call last):
        File "/usr/lib/python3/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 156, in prepare_metadata_for_build_wheel
          hook = backend.prepare_metadata_for_build_wheel
      AttributeError: module 'hatchling.build' has no attribute 'prepare_metadata_for_build_wheel'
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/usr/lib/python3/dist-packages/packaging/requirements.py", line 102, in __init__
          req = REQUIREMENT.parseString(requirement_string)
        File "/usr/lib/python3/dist-packages/pyparsing.py", line 1955, in parseString
          raise exc
        File "/usr/lib/python3/dist-packages/pyparsing.py", line 3250, in parseImpl
          raise ParseException(instring, loc, self.errmsg, self)
      pyparsing.ParseException: Expected W:(abcd...), found '#'  (at char 4), (line:1, col:5)
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/usr/lib/python3/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
          main()
        File "/usr/lib/python3/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/usr/lib/python3/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 160, in prepare_metadata_for_build_wheel
          whl_basename = backend.build_wheel(metadata_directory, config_settings)
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatchling/build.py", line 41, in build_wheel
          return os.path.basename(next(builder.build(wheel_directory, ['standard'])))
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatchling/builders/plugin/interface.py", line 80, in build
          self.metadata.validate_fields()
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatchling/metadata/core.py", line 167, in validate_fields
          _ = self.version
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatchling/metadata/core.py", line 55, in version
          self._set_version()
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatchling/metadata/core.py", line 145, in _set_version
          core_metadata = self.core
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatchling/metadata/core.py", line 102, in core
          metadata_hook.update(core_metadata)
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatch_requirements_txt/__init__.py", line 88, in update
          requirements, _ = parse_requirements(fp.read().splitlines())
        File "/tmp/pip-build-env-j3mhxl_b/overlay/local/lib/python3.10/dist-packages/hatch_requirements_txt/__init__.py", line 64, in parse_requirements
          req = Requirement(line)
        File "/usr/lib/python3/dist-packages/packaging/requirements.py", line 104, in __init__
          raise InvalidRequirement(
      packaging.requirements.InvalidRequirement: Parse error at "'# via wa'": Expected W:(abcd...)
      [end of output]

Expected result:

Indented comments to be treated as comment lines.

Reproduces how often:

Always.

Version

  • Operating System: Ubuntu 22.04
  • Python: 3.10
  • hatch-requirements-txt: 0.1.0

Installation source

PyPI

Other Additional Information:

Might I suggest something like:

diff --git a/hatch_requirements_txt/__init__.py b/hatch_requirements_txt/__init__.py
index cd9f057..e0d3153 100644
--- a/hatch_requirements_txt/__init__.py
+++ b/hatch_requirements_txt/__init__.py
@@ -28,6 +28,7 @@ Hatchling plugin to read project dependencies from ``requirements.txt``.
 
 # stdlib
 import os
+import re
 from typing import Iterable, List, Tuple, Type
 
 # 3rd party
@@ -57,8 +58,10 @@ def parse_requirements(requirements: Iterable[str], ) -> Tuple[List[Requirement]
 	comments = []
 	parsed_requirements: List[Requirement] = []
 
+	comment_re = re.compile(r'\s*#')
+
 	for line in requirements:
-		if line.startswith('#'):
+		if comment_re.match(line):
 			comments.append(line)
 		elif line:
 			req = Requirement(line)
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 8039844..3d02810 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -37,7 +37,7 @@ def test_wheel(tmp_pathplus: PathPlus):
 	dist_dir.maybe_make()
 
 	(tmp_pathplus / "pyproject.toml").write_clean(pyproject_toml)
-	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
+	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "  # buzz", "baz>1"])
 	(tmp_pathplus / "README.md").touch()
 	(tmp_pathplus / "LICENSE").touch()
 	(tmp_pathplus / "demo").maybe_make()
@@ -58,7 +58,7 @@ def test_sdist(tmp_pathplus: PathPlus):
 	dist_dir.maybe_make()
 
 	(tmp_pathplus / "pyproject.toml").write_clean(pyproject_toml)
-	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "# fizz", "bar", "baz>1"])
+	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "# fizz", "bar", "  # buzz", "baz>1"])
 	(tmp_pathplus / "README.md").touch()
 	(tmp_pathplus / "LICENSE").touch()
 	(tmp_pathplus / "demo").maybe_make()

UnknownPluginError when running `hatch dep show table`

Description

Configured the plugin in my pyproject.toml as suggested here.
Trying to print the dependencies on console.

Steps to Reproduce

  1. Run hatch dep show table
  2. crash

I noticed that the result is slightly different ( hatch prints only the immediate dependencies of the [tool.hatch.envs.default] section without the dependencies from requirements.txt instead of crashing ) if the following snippet is missing in my pyproject.toml:

[tool.hatch.metadata.hooks.requirements_txt]
filename = "requirements.txt"

Actual result:

Hatch crashes with exception

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/hatch/cli/__init__.py:203 in  │
│ main                                                                                             │
│                                                                                                  │
│   200                                                                                            │
│   201 def main():  # no cov                                                                      │
│   202 │   try:                                                                                   │
│ ❱ 203 │   │   return hatch(windows_expand_args=False)                                            │
│   204 │   except Exception:                                                                      │
│   205 │   │   from rich.console import Console                                                   │
│   206                                                                                            │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:1130 in         │
│ __call__                                                                                         │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:1055 in main    │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:1657 in invoke  │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:1657 in invoke  │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:1657 in invoke  │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:1404 in invoke  │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/core.py:760 in invoke   │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/click/decorators.py:38 in     │
│ new_func                                                                                         │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/hatch/cli/dep/__init__.py:66  │
│ in table                                                                                         │
│                                                                                                  │
│    63 │   │   environment = app.get_environment()                                                │
│    64 │   │   environment_dependencies.extend(environment.environment_dependencies)              │
│    65 │   else:                                                                                  │
│ ❱  66 │   │   project_dependencies.extend(app.project.metadata.core.dependencies)                │
│    67 │   │                                                                                      │
│    68 │   │   environment = app.get_environment()                                                │
│    69 │   │   environment_dependencies.extend(environment.environment_dependencies)              │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/hatchling/metadata/core.py:94 │
│ in core                                                                                          │
│                                                                                                  │
│     91 │   │   │                                                                                 │
│     92 │   │   │   metadata = CoreMetadata(self.root, core_metadata, self.hatch.metadata, self.  │
│     93 │   │   │                                                                                 │
│ ❱   94 │   │   │   metadata_hooks = self.hatch.metadata.hooks                                    │
│     95 │   │   │   if metadata_hooks:                                                            │
│     96 │   │   │   │   static_fields = set(core_metadata)                                        │
│     97 │   │   │   │   if 'version' in self.hatch.config:                                        │
│                                                                                                  │
│ /usr/local/Cellar/hatch/1.3.1/libexec/lib/python3.10/site-packages/hatchling/metadata/core.py:13 │
│ 19 in hooks                                                                                      │
│                                                                                                  │
│   1316 │   │   │   │   if metadata_hook is None:                                                 │
│   1317 │   │   │   │   │   from hatchling.plugin.exceptions import UnknownPluginError            │
│   1318 │   │   │   │   │                                                                         │
│ ❱ 1319 │   │   │   │   │   raise UnknownPluginError(f'Unknown metadata hook: {hook_name}')       │
│   1320 │   │   │   │                                                                             │
│   1321 │   │   │   │   configured_hooks[hook_name] = metadata_hook(self.root, config)            │
│   1322                                                                                           │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
UnknownPluginError: Unknown metadata hook: requirements_txt

Expected result:

Dependencies ( incl the ones from my requirements.txt ) will be printed on console.

Reproduces how often:

Instantly, hatch seems to crash on any command I try to invoke with the same plugin error.

Version

  • Operating System: macOs 12.5.1 Monterey
  • Python: 3.10.6
  • hatch-requirements-txt: Don't know how to get the actual used version of the plugin, hatch is 1.3.1 installed via brew install hatch

Question

How to install the plugin if hatch uses its own python interpreter ( as the callstack in the traceback suggests ) ?

0.3.0: pytest warnings

Looks like pytest shpws some DeprecationWarning warnings

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-hatch-requirements-txt-0.3.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-hatch-requirements-txt-0.3.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -m 'not network'
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.8.16, pytest-7.2.1, pluggy-1.0.0
Test session started at 18:04:54
rootdir: /home/tkloczko/rpmbuild/BUILD/hatch-requirements-txt-0.3.0, configfile: tox.ini
plugins: datadir-1.4.1, regressions-2.4.2, timeout-2.1.0
timeout: 300.0s
timeout method: signal
timeout func_only: False
collected 54 items

tests/test_errors.py ........................                                                                                                                                         [ 44%]
tests/test_metadata.py ..............................                                                                                                                                 [100%]

===================================================================================== warnings summary ======================================================================================
tests/test_errors.py::test_filename_parameter_not_str[build_wheel]
tests/test_errors.py::test_filename_parameter_not_str[build_sdist]
tests/test_metadata.py::test_build_with_filename[build_wheel]
tests/test_metadata.py::test_build_with_filename[build_sdist]
  /home/tkloczko/rpmbuild/BUILD/hatch-requirements-txt-0.3.0/hatch_requirements_txt/__init__.py:149: DeprecationWarning: The 'filename' option in [tool.hatch.metadata.hooks.requirements_txt] is deprecated. Please instead use the list 'files'.
    warnings.warn(

tests/test_metadata.py::test_build_unspecified[build_wheel]
tests/test_metadata.py::test_build_unspecified[build_sdist]
  /home/tkloczko/rpmbuild/BUILD/hatch-requirements-txt-0.3.0/hatch_requirements_txt/__init__.py:136: DeprecationWarning: Please explicitly specify 'files' in [tool.hatch.metadata.hooks.requirements_txt]. Defaulting to ['requirements.txt'] is deprecated.
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================================================================================== slowest 25 durations ====================================================================================
0.05s call     tests/test_metadata.py::test_build_files_in_subdirectory[build_wheel]
0.04s call     tests/test_metadata.py::test_build_files_in_subdirectory[build_sdist]
0.04s call     tests/test_metadata.py::test_optional_dependencies[build_sdist]
0.03s call     tests/test_errors.py::test_filename_deprecation[build_wheel]
0.03s call     tests/test_errors.py::test_missing_requirements_txt[build_wheel]
0.03s call     tests/test_metadata.py::test_optional_dependencies[build_wheel]
0.03s call     tests/test_metadata.py::test_build_with_files[build_wheel]
0.02s call     tests/test_errors.py::test_no_files_or_filename_deprecation[build_wheel]
0.02s call     tests/test_metadata.py::test_build_with_filename[build_wheel]
0.02s call     tests/test_metadata.py::test_build_unspecified[build_wheel]
0.02s call     tests/test_metadata.py::test_using_project_deps_and_optional_deps[build_wheel]
0.02s call     tests/test_metadata.py::test_build_with_files[build_sdist]
0.02s call     tests/test_metadata.py::test_build_with_filename[build_sdist]
0.02s call     tests/test_metadata.py::test_using_project_deps_and_optional_deps[build_sdist]
0.02s call     tests/test_metadata.py::test_build_unspecified[build_sdist]
0.02s call     tests/test_errors.py::test_filename_deprecation[build_sdist]
0.02s call     tests/test_errors.py::test_no_files_or_filename_deprecation[build_sdist]
0.02s call     tests/test_errors.py::test_optional_already_given[build_wheel]
0.02s call     tests/test_errors.py::test_not_dynamic_but_files_defined[build_sdist]
0.02s call     tests/test_errors.py::test_missing_invalid_requirements[build_sdist]
0.02s call     tests/test_errors.py::test_missing_requirements_txt[build_sdist]
0.02s call     tests/test_errors.py::test_optional_not_dynamic[build_wheel]
0.02s call     tests/test_errors.py::test_missing_invalid_requirements[build_wheel]
0.02s call     tests/test_errors.py::test_filename_parameter_not_str[build_wheel]
0.02s call     tests/test_errors.py::test_optional_already_given[build_sdist]
============================================================================== 54 passed, 6 warnings in 1.09s ===============================================================================

Support for features / optional dependencies

Hey, great plugin!

For example this https://github.com/aws/sagemaker-python-sdk/blob/49c664893339b42815b2fe8a91d912194199e8ba/setup.py#L64-L72 might become:

[tool.hatch.metadata.hooks.requirements_txt.features]
local = ["requirements/extras/local_requirements.txt"]
scipy = ["requirements/extras/scipy_requirements.txt"]
all = [
  "requirements/extras/local_requirements.txt",
  "requirements/extras/scipy_requirements.txt",
]
test = [
  "requirements/extras/local_requirements.txt",
  "requirements/extras/scipy_requirements.txt",
  "requirements/extras/test_requirements.txt",
]

& maybe the top-level option should become an array too?

[tool.hatch.metadata.hooks.requirements_txt]
files = ["requirements.txt"]

Support editable installs

Description

In the README, I see that editable installs are not support. I'm curious as to why that is, and whether you think it's an insurmountable limitation.

Add conda-forge package

I noticed that you're using your own channel to publish this as a Conda package. It's easy to contribute to Conda-Forge... I threw together conda-forge/staged-recipes#20484 in about 2 minutes...

  • Fork and clone staged-recipes
  • Create a new branch e.g. hatch-requirements-txt
  • Install Grayskull
  • Change into the recipes/ directory and run grayskull pypi hatch-requirements-txt
  • Add recipes/hatch-requirements-txt/meta.yaml, commit, and push.

@domdfcoding, may I add you there as a feedstock maintainer for this hatch-requirements-txt package?

Allow requirement file in hatch environment depenedencies

Description

Add feature to allow use of requirements file when specifying hatch environments.

[tool.hatch.envs.<env>.dependencies]
dependency-file = "requirements.txt"

Other Additional Information:

My use case is docs environment where I have to keep a separate requirements/docs.txt file for local build and CI build of docs.
The CI is from RTD which only allows requirement files. I have other options which I'd like to not explore right now.

Tests fail with hatchling 1.22.4

Description

1aa21b8 doesn't seem to have been enough, tests fail with 1.22.4.

Now that Debian has updated hatchling to 1.22.4, hatch-requirements-txt has failing tests.

Actual result:

============================= test session starts ==============================
platform linux -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0
Test session started at 14:34:32
rootdir: /<<PKGBUILDDIR>>
configfile: tox.ini
plugins: cov-4.1.0, datadir-1.4.1+ds, regressions-2.5.0+ds, timeout-2.3.1
timeout: 300.0s
timeout method: signal
timeout func_only: False
collected 62 items

tests/test_errors.py ....xx..xxXX................                        [ 45%]
tests/test_metadata.py FFFFFFFFFFFF..FFss............FFFF                [100%]

=================================== FAILURES ===================================
____________________ test_build_with_filename[build_wheel] _____________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_with_filename_build0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_with_filename(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    filename = "requirements.txt"
    """
    	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
    
    	deprecation_warning_msg = r"The 'filename' option in \[tool.hatch.metadata.hooks.requirements_txt] is deprecated. Please instead use the list 'files'"
    	with pytest.warns(DeprecationWarning, match=deprecation_warning_msg):
    		info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
    
>   	assert info.requires_dist == ["bar", "baz>1", "foo"]
E    AssertionError: assert () == ['bar', 'baz>1', 'foo']
E      
E      Right contains 3 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:80: AssertionError
____________________ test_build_with_filename[build_sdist] _____________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_with_filename_build1')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_with_filename(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    filename = "requirements.txt"
    """
    	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
    
    	deprecation_warning_msg = r"The 'filename' option in \[tool.hatch.metadata.hooks.requirements_txt] is deprecated. Please instead use the list 'files'"
    	with pytest.warns(DeprecationWarning, match=deprecation_warning_msg):
    		info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
    
>   	assert info.requires_dist == ["bar", "baz>1", "foo"]
E    AssertionError: assert () == ['bar', 'baz>1', 'foo']
E      
E      Right contains 3 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:80: AssertionError
_______________________ test_build_comments[build_wheel] _______________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_comments_build_whee0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_comments(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements.txt"]
    
    [tool.hatch.metadata]
    allow-direct-references = true
    """
    	(tmp_pathplus / "requirements.txt").write_lines([
    			"Foo",
    			"bar",
    			"# fizz",
    			"baz>1  # this is a comment",
    			"pip@ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686"
    			])
    
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == [
    			"bar",
    			"baz>1",
    			"foo",
    			"pip@ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686"
    			]
E    AssertionError: assert () == ['bar', 'baz>...940a148ea686']
E      
E      Right contains 4 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:102: AssertionError
_______________________ test_build_comments[build_sdist] _______________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_comments_build_sdis0')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_comments(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements.txt"]
    
    [tool.hatch.metadata]
    allow-direct-references = true
    """
    	(tmp_pathplus / "requirements.txt").write_lines([
    			"Foo",
    			"bar",
    			"# fizz",
    			"baz>1  # this is a comment",
    			"pip@ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686"
    			])
    
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == [
    			"bar",
    			"baz>1",
    			"foo",
    			"pip@ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686"
    			]
E    AssertionError: assert () == ['bar', 'baz>...940a148ea686']
E      
E      Right contains 4 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:102: AssertionError
__________________ test_build_pip_compile_style[build_wheel] ___________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_pip_compile_style_b0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_pip_compile_style(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements.txt"]
    """
    	(tmp_pathplus / "requirements.txt").write_lines([
    			"--index http://localhost:3141",
    			"alembic==1.9.1 \\",
    			"    --hash=sha256:a9781ed0979a20341c2cbb56bd22bd8db4fc1913f955e705444bd3a97c59fa32 \\",
    			"    --hash=sha256:f9f76e41061f5ebe27d4fe92600df9dd612521a7683f904dab328ba02cffa5a2",
    			"hatch-requirements-txt",
    			])
    
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == [
    			"alembic==1.9.1",
    			"hatch-requirements-txt",
    			]
E    AssertionError: assert () == ['alembic==1....irements-txt']
E      
E      Right contains 2 more items, first extra item: 'alembic==1.9.1'
E      Use -v to get more diff

tests/test_metadata.py:126: AssertionError
__________________ test_build_pip_compile_style[build_sdist] ___________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_pip_compile_style_b1')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_pip_compile_style(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements.txt"]
    """
    	(tmp_pathplus / "requirements.txt").write_lines([
    			"--index http://localhost:3141",
    			"alembic==1.9.1 \\",
    			"    --hash=sha256:a9781ed0979a20341c2cbb56bd22bd8db4fc1913f955e705444bd3a97c59fa32 \\",
    			"    --hash=sha256:f9f76e41061f5ebe27d4fe92600df9dd612521a7683f904dab328ba02cffa5a2",
    			"hatch-requirements-txt",
    			])
    
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == [
    			"alembic==1.9.1",
    			"hatch-requirements-txt",
    			]
E    AssertionError: assert () == ['alembic==1....irements-txt']
E      
E      Right contains 2 more items, first extra item: 'alembic==1.9.1'
E      Use -v to get more diff

tests/test_metadata.py:126: AssertionError
_____________________ test_build_unspecified[build_wheel] ______________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_unspecified_build_w0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_unspecified(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    # files = ["requirements.txt"]
    """
    	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
    
    	deprecation_warning_msg = r"Please explicitly specify 'files' in \[tool.hatch.metadata.hooks.requirements_txt]. Defaulting to \['requirements.txt'] is deprecated"
    	with pytest.warns(DeprecationWarning, match=deprecation_warning_msg):
    		info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
    
>   	assert info.requires_dist == ["bar", "baz>1", "foo"]
E    AssertionError: assert () == ['bar', 'baz>1', 'foo']
E      
E      Right contains 3 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:145: AssertionError
_____________________ test_build_unspecified[build_sdist] ______________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_unspecified_build_s0')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_unspecified(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    # files = ["requirements.txt"]
    """
    	(tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
    
    	deprecation_warning_msg = r"Please explicitly specify 'files' in \[tool.hatch.metadata.hooks.requirements_txt]. Defaulting to \['requirements.txt'] is deprecated"
    	with pytest.warns(DeprecationWarning, match=deprecation_warning_msg):
    		info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
    
>   	assert info.requires_dist == ["bar", "baz>1", "foo"]
E    AssertionError: assert () == ['bar', 'baz>1', 'foo']
E      
E      Right contains 3 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:145: AssertionError
______________________ test_build_with_files[build_wheel] ______________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_with_files_build_wh0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_with_files(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements1.txt", "requirements2.txt"]
    """
    	(tmp_pathplus / "requirements1.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
    	(tmp_pathplus / "requirements2.txt").write_lines(["beep", "bop", "boop"])
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["bar", "baz>1", "beep", "boop", "bop", "foo"]
E    AssertionError: assert () == ['bar', 'baz>... 'bop', 'foo']
E      
E      Right contains 6 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:158: AssertionError
______________________ test_build_with_files[build_sdist] ______________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_with_files_build_sd0')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_with_files(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements1.txt", "requirements2.txt"]
    """
    	(tmp_pathplus / "requirements1.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
    	(tmp_pathplus / "requirements2.txt").write_lines(["beep", "bop", "boop"])
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["bar", "baz>1", "beep", "boop", "bop", "foo"]
E    AssertionError: assert () == ['bar', 'baz>... 'bop', 'foo']
E      
E      Right contains 6 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:158: AssertionError
________________ test_build_files_in_subdirectory[build_wheel] _________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_files_in_subdirecto0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_files_in_subdirectory(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements/dev.txt", "requirements/docs.txt", "requirements/tests.txt"]
    """
    	reqs_subdir = tmp_pathplus / "requirements"
    	reqs_subdir.maybe_make()
    	(reqs_subdir / "dev.txt").write_lines(["pre-commit"])
    	(reqs_subdir / "docs.txt").write_lines(["mkdocs"])
    	(reqs_subdir / "tests.txt").write_lines(["pytest"])
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["mkdocs", "pre-commit", "pytest"]
E    AssertionError: assert () == ['mkdocs', 'p...it', 'pytest']
E      
E      Right contains 3 more items, first extra item: 'mkdocs'
E      Use -v to get more diff

tests/test_metadata.py:174: AssertionError
________________ test_build_files_in_subdirectory[build_sdist] _________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_build_files_in_subdirecto1')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_build_files_in_subdirectory(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements/dev.txt", "requirements/docs.txt", "requirements/tests.txt"]
    """
    	reqs_subdir = tmp_pathplus / "requirements"
    	reqs_subdir.maybe_make()
    	(reqs_subdir / "dev.txt").write_lines(["pre-commit"])
    	(reqs_subdir / "docs.txt").write_lines(["mkdocs"])
    	(reqs_subdir / "tests.txt").write_lines(["pytest"])
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["mkdocs", "pre-commit", "pytest"]
E    AssertionError: assert () == ['mkdocs', 'p...it', 'pytest']
E      
E      Right contains 3 more items, first extra item: 'mkdocs'
E      Use -v to get more diff

tests/test_metadata.py:174: AssertionError
______________ test_not_dynamic_project_dependencies[build_wheel] ______________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_not_dynamic_project_depen0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_not_dynamic_project_dependencies(tmp_pathplus: PathPlus, build_func: Callable):
    
    	dist_dir = tmp_pathplus / "dist"
    	dist_dir.maybe_make()
    
    	pyproject_toml = pyproject_toml_header.replace(
    			'dynamic = ["dependencies"]', 'dependencies = ["foo", "bar", "baz>1"]'
    			)
    	(tmp_pathplus / "README.md").touch()
    	(tmp_pathplus / "LICENSE").touch()
    	(tmp_pathplus / "demo").maybe_make()
    	(tmp_pathplus / "demo" / "__init__.py").touch()
    
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["bar", "baz>1", "foo"]
E    AssertionError: assert () == ['bar', 'baz>1', 'foo']
E      
E      Right contains 3 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:228: AssertionError
______________ test_not_dynamic_project_dependencies[build_sdist] ______________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_not_dynamic_project_depen1')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_not_dynamic_project_dependencies(tmp_pathplus: PathPlus, build_func: Callable):
    
    	dist_dir = tmp_pathplus / "dist"
    	dist_dir.maybe_make()
    
    	pyproject_toml = pyproject_toml_header.replace(
    			'dynamic = ["dependencies"]', 'dependencies = ["foo", "bar", "baz>1"]'
    			)
    	(tmp_pathplus / "README.md").touch()
    	(tmp_pathplus / "LICENSE").touch()
    	(tmp_pathplus / "demo").maybe_make()
    	(tmp_pathplus / "demo" / "__init__.py").touch()
    
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["bar", "baz>1", "foo"]
E    AssertionError: assert () == ['bar', 'baz>1', 'foo']
E      
E      Right contains 3 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:228: AssertionError
_________________ test_using_project_dependencies[build_wheel] _________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_using_project_dependencie0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_using_project_dependencies(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header.replace(
    			'dynamic = ["dependencies"]', """
    dynamic = []
    dependencies = ["foo", "bar"]
       """
    			)
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["bar", "foo"]
E    AssertionError: assert () == ['bar', 'foo']
E      
E      Right contains 2 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:357: AssertionError
_________________ test_using_project_dependencies[build_sdist] _________________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_using_project_dependencie1')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_using_project_dependencies(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header.replace(
    			'dynamic = ["dependencies"]', """
    dynamic = []
    dependencies = ["foo", "bar"]
       """
    			)
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.requires_dist == ["bar", "foo"]
E    AssertionError: assert () == ['bar', 'foo']
E      
E      Right contains 2 more items, first extra item: 'bar'
E      Use -v to get more diff

tests/test_metadata.py:357: AssertionError
____________ test_using_project_deps_and_optional_deps[build_wheel] ____________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_using_project_deps_and_op0')
build_func = <function build_wheel at 0x7f587f60e020>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_using_project_deps_and_optional_deps(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header.replace(
    			'dynamic = ["dependencies"]',
    			"""
    dynamic = ["optional-dependencies"]
    dependencies = ["foo", "bar"]
       """
    			) + """
    [tool.hatch.metadata.hooks.requirements_txt.optional-dependencies]
    crypto = ["requirements-crypto.txt"]
    """
    	(tmp_pathplus / "requirements-crypto.txt").write_lines(["PyJWT", "cryptography"])
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.provides_extras == ["crypto"]
E    AssertionError: assert () == ['crypto']
E      
E      Right contains one more item: 'crypto'
E      Use -v to get more diff

tests/test_metadata.py:375: AssertionError
____________ test_using_project_deps_and_optional_deps[build_sdist] ____________

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-stefanor/pytest-0/test_using_project_deps_and_op1')
build_func = <function build_sdist at 0x7f587f60dee0>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_using_project_deps_and_optional_deps(tmp_pathplus: PathPlus, build_func: Callable):
    
    	pyproject_toml = pyproject_toml_header.replace(
    			'dynamic = ["dependencies"]',
    			"""
    dynamic = ["optional-dependencies"]
    dependencies = ["foo", "bar"]
       """
    			) + """
    [tool.hatch.metadata.hooks.requirements_txt.optional-dependencies]
    crypto = ["requirements-crypto.txt"]
    """
    	(tmp_pathplus / "requirements-crypto.txt").write_lines(["PyJWT", "cryptography"])
    	info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
>   	assert info.provides_extras == ["crypto"]
E    AssertionError: assert () == ['crypto']
E      
E      Right contains one more item: 'crypto'
E      Use -v to get more diff

tests/test_metadata.py:375: AssertionError
============================= slowest 25 durations =============================
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_not_dynamic_but_files_defined[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_missing_requirements_txt[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_using_project_deps_and_optional_deps[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_using_project_dependencies[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_with_filename[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_files_in_subdirectory[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_with_files[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_pip_compile_style[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_comments[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_unspecified[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_no_files_or_filename_deprecation[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_filename_deprecation[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_not_dynamic_but_filename_defined[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_files_in_subdirectory[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_with_files[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_using_project_deps_and_optional_deps[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_not_dynamic_project_dependencies[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_comments[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_using_project_dependencies[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_with_filename[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_not_dynamic_no_explicit_files[build_wheel]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_unspecified[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_metadata.py::test_build_pip_compile_style[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_no_files_or_filename_deprecation[build_sdist]
0.01s call     .pybuild/cpython3_3.12/build/tests/test_errors.py::test_filename_deprecation[build_sdist]
=========================== short test summary info ============================
FAILED tests/test_metadata.py::test_build_with_filename[build_wheel] - AssertionError: assert () == ['bar', 'baz>1', 'foo']
FAILED tests/test_metadata.py::test_build_with_filename[build_sdist] - AssertionError: assert () == ['bar', 'baz>1', 'foo']
FAILED tests/test_metadata.py::test_build_comments[build_wheel] - AssertionError: assert () == ['bar', 'baz>...940a148ea686']
FAILED tests/test_metadata.py::test_build_comments[build_sdist] - AssertionError: assert () == ['bar', 'baz>...940a148ea686']
FAILED tests/test_metadata.py::test_build_pip_compile_style[build_wheel] - AssertionError: assert () == ['alembic==1....irements-txt']
FAILED tests/test_metadata.py::test_build_pip_compile_style[build_sdist] - AssertionError: assert () == ['alembic==1....irements-txt']
FAILED tests/test_metadata.py::test_build_unspecified[build_wheel] - AssertionError: assert () == ['bar', 'baz>1', 'foo']
FAILED tests/test_metadata.py::test_build_unspecified[build_sdist] - AssertionError: assert () == ['bar', 'baz>1', 'foo']
FAILED tests/test_metadata.py::test_build_with_files[build_wheel] - AssertionError: assert () == ['bar', 'baz>... 'bop', 'foo']
FAILED tests/test_metadata.py::test_build_with_files[build_sdist] - AssertionError: assert () == ['bar', 'baz>... 'bop', 'foo']
FAILED tests/test_metadata.py::test_build_files_in_subdirectory[build_wheel] - AssertionError: assert () == ['mkdocs', 'p...it', 'pytest']
FAILED tests/test_metadata.py::test_build_files_in_subdirectory[build_sdist] - AssertionError: assert () == ['mkdocs', 'p...it', 'pytest']
FAILED tests/test_metadata.py::test_not_dynamic_project_dependencies[build_wheel] - AssertionError: assert () == ['bar', 'baz>1', 'foo']
FAILED tests/test_metadata.py::test_not_dynamic_project_dependencies[build_sdist] - AssertionError: assert () == ['bar', 'baz>1', 'foo']
FAILED tests/test_metadata.py::test_using_project_dependencies[build_wheel] - AssertionError: assert () == ['bar', 'foo']
FAILED tests/test_metadata.py::test_using_project_dependencies[build_sdist] - AssertionError: assert () == ['bar', 'foo']
FAILED tests/test_metadata.py::test_using_project_deps_and_optional_deps[build_wheel] - AssertionError: assert () == ['crypto']
FAILED tests/test_metadata.py::test_using_project_deps_and_optional_deps[build_sdist] - AssertionError: assert () == ['crypto']
======== 18 failed, 36 passed, 2 skipped, 4 xfailed, 2 xpassed in 0.62s ========

Version

  • Operating System: Debian unstable
  • Python: 3.12
  • hatch-requirements-txt: 0.4.1 + 1aa21b8

Componentized requirement files don't work

I "componentize" my requirement files into common and dev requirements such that my requirements.txt looks like this:

-r requirements/common.txt

hatch-requirement-txt does not appear to support this syntax. Build doesn't fail but my library ends up having no dependencies

Adding support for `python_version`

Sometimes (like in my case) there are different requirements.txt files for different python versions. Currently the only way to enforce package installation based on python version is in the requirements.txt file level i.e.:
requirements.txt

numpy==1.22.0; python_version>="3.8"
pandas==1.5.0; python_version>="3.8"

requirements-python-37.txt

numpy==1.18.0; python_version<"3.8"
pandas==1.0.0; python_version<"3.8"

It will be much cleaner setting the python_version on the hatch level similar to this:

files = [
    { file = "requirements.txt", python_version = ">=3.8" },
    { file = "requirements-python-37.txt", python_version = "<3.8" }
]

And add this capability to [tool.hatch.metadata.hooks.requirements_txt] as well as to [tool.hatch.metadata.hooks.requirements_txt.optional-dependencies]

Test regressions with current dependency versions

Description

On Fedora Linux 39, with current master (a081ba4), two tests fail with tox -e py312. This is probably due to the recent release of hatchling 1.20.0 and hatch 1.8.1.

Steps to Reproduce

  1. gh repo clone repo-helper/hatch-requirements-txt
  2. cd hatch-requirements-txt
  3. tox -e py312

Actual result:

================ test session starts =================
platform linux -- Python 3.12.0, pytest-7.4.3, pluggy-1.3.0
cachedir: .tox/py312/.pytest_cache
Using --randomly-seed=4214831224
Test session started at 12:31:14
rootdir: /home/ben/src/forks/hatch-requirements-txt
configfile: tox.ini
plugins: timeout-2.2.0, randomly-3.15.0, datadir-1.5.0, cov-4.1.0, regressions-2.5.0
timeout: 300.0s
timeout method: signal
timeout func_only: False
collected 58 items                                   

tests/test_errors.py ........................  [ 41%]
tests/test_metadata.py ..........F......F..... [ 81%]
...........                                    [100%]

====================== FAILURES ======================
______ test_optional_dependencies[build_wheel] _______

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-ben/pytest-4/test_optional_dependencies_bui0')
build_func = <function build_wheel at 0x7f37165f3890>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_optional_dependencies(tmp_pathplus: PathPlus, build_func: Callable):

        pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt]
    files = ["requirements.txt"]

    [tool.hatch.metadata.hooks.requirements_txt.optional-dependencies]
    crypto = ["requirements-crypto.txt"]
    fastjson = ["requirements-fastjson.txt"]
    cli = ["requirements-cli.txt"]
    """
        pyproject_toml = pyproject_toml.replace( 
                        'dynamic = ["dependencies"]', 'dynamic = ["dependencies", "optional-dependencies"]'
                        )
        (tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
        (tmp_pathplus / "requirements-crypto.txt").write_lines(["PyJWT", "cryptography"])
        (tmp_pathplus / "requirements-fastjson.txt").write_lines(["orjson"])
        (tmp_pathplus / "requirements-cli.txt").write_lines([
                        "prompt-toolkit", "colorama; platform_system == 'Windows'"
                        ])
        info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
        assert info.provides_extras == ["cli", "crypto", "fastjson"]
>       assert info.requires_dist == [
                        "bar",
                        "baz>1",
                        "foo",
                        "colorama; platform_system == 'Windows' and extra == 'cli'",
                        "prompt-toolkit; extra == 'cli'",
                        "cryptography; extra == 'crypto'",
                        "pyjwt; extra == 'crypto'",
                        "orjson; extra == 'fastjson'"
                        ]
E    assert ['bar', 'baz>...crypto'", ...] == ['bar', 'baz>...crypto'", ...]
E      At index 3 diff: "colorama; (platform_system == 'Windows') and extra == 'cli'" != "colorama; platform_system == 'Windows' and extra == 'cli'"
E      Use -v to get more diff

tests/test_metadata.py:252: AssertionError
______ test_optional_dependencies[build_sdist] _______

tmp_pathplus = PosixPathPlus('/tmp/pytest-of-ben/pytest-4/test_optional_dependencies_bui1')
build_func = <function build_sdist at 0x7f37165f3710>

    @pytest.mark.parametrize("build_func", [build_wheel, build_sdist])
    def test_optional_dependencies(tmp_pathplus: PathPlus, build_func: Callable):

        pyproject_toml = pyproject_toml_header + """
    [tool.hatch.metadata.hooks.requirements_txt] 
    files = ["requirements.txt"]

    [tool.hatch.metadata.hooks.requirements_txt.optional-dependencies]
    crypto = ["requirements-crypto.txt"]
    fastjson = ["requirements-fastjson.txt"]
    cli = ["requirements-cli.txt"]
    """
        pyproject_toml = pyproject_toml.replace( 
                        'dynamic = ["dependencies"]', 'dynamic = ["dependencies", "optional-dependencies"]'
                        )
        (tmp_pathplus / "requirements.txt").write_lines(["Foo", "bar", "# fizz", "baz>1"])
        (tmp_pathplus / "requirements-crypto.txt").write_lines(["PyJWT", "cryptography"])
        (tmp_pathplus / "requirements-fastjson.txt").write_lines(["orjson"])
        (tmp_pathplus / "requirements-cli.txt").write_lines([
                        "prompt-toolkit", "colorama; platform_system == 'Windows'"
                        ])
        info = get_pkginfo(tmp_pathplus, build_func, pyproject_toml)
        assert info.provides_extras == ["cli", "crypto", "fastjson"]
>       assert info.requires_dist == [
                        "bar",
                        "baz>1",
                        "foo",
                        "colorama; platform_system == 'Windows' and extra == 'cli'",
                        "prompt-toolkit; extra == 'cli'",
                        "cryptography; extra == 'crypto'",
                        "pyjwt; extra == 'crypto'",
                        "orjson; extra == 'fastjson'"
                        ]
E    assert ['bar', 'baz>...crypto'", ...] == ['bar', 'baz>...crypto'", ...]
E      At index 3 diff: "colorama; (platform_system == 'Windows') and extra == 'cli'" != "colorama; platform_system == 'Windows' and extra == 'cli'"
E      Use -v to get more diff

tests/test_metadata.py:252: AssertionError

---------- coverage: platform linux, python 3.12.0-final-0 -----------
[… snip …]
================ slowest 25 durations ================
[… snip …]
============== short test summary info ===============
FAILED tests/test_metadata.py::test_optional_dependencies[build_wheel] - assert ['bar', 'baz>...crypto'", ...] == ['bar', ...
FAILED tests/test_metadata.py::test_optional_dependencies[build_sdist] - assert ['bar', 'baz>...crypto'", ...] == ['bar', ...
============ 2 failed, 56 passed in 1.41s ============

Expected result:

All tests pass.

Reproduces how often:

100% reproducible.

Version

  • Operating System: Fedora Linux 39 on x86_64
  • Python: 3.12.0
  • hatch-requirements-txt: a081ba4

Installation source

GitHub repository

Other Additional Information:

I do not expect this issue to be platform-dependent.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.