prefix-dev / pixi

Package management made easy
https://pixi.sh
BSD 3-Clause "New" or "Revised" License
2.91k stars 161 forks source link

`pixi init --format pyproject && pixi shell` fails #1941

Closed zbowling closed 1 week ago

zbowling commented 2 weeks ago

Checks

Reproducible example

➜  ~ mkdir test2
➜  ~ pixi init --format pyproject
✔ Created /Users/zbowling/pyproject.toml
➜  ~ pixi shell
  × error updating pypi prefix
  ├─▶ Failed to prepare distributions
  ├─▶ Failed to fetch wheel: zbowling @ file:///Users/zbowling
  ├─▶ Failed to build: `zbowling @ file:///Users/zbowling`
  ╰─▶ Build backend failed to build wheel through `build_editable()` with exit status: 1
      --- stdout:

      --- stderr:
      Traceback (most recent call last):
        File "<string>", line 11, in <module>
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/build.py", line 83, in build_editable
          return os.path.basename(next(builder.build(directory=wheel_directory, versions=['editable'])))
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/plugin/interface.py", line 155, in build
          artifact = version_api[version](directory, **build_data)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/wheel.py", line 494, in build_editable
          return self.build_editable_detection(directory, **build_data)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/wheel.py", line 505, in build_editable_detection
          for included_file in self.recurse_selected_project_files():
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/plugin/interface.py", line 180, in recurse_selected_project_files
          if self.config.only_include:
             ^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/config.py", line 806, in only_include
          only_include = only_include_config.get('only-include', self.default_only_include()) or self.packages
                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/wheel.py", line 260, in default_only_include
          return self.default_file_selection_options.only_include
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/.pixi/envs/default/lib/python3.12/functools.py", line 993, in __get__
          val = self.func(instance)
                ^^^^^^^^^^^^^^^^^^^
        File "/Users/zbowling/Library/Caches/rattler/cache/uv-cache/environments-v0/.tmpK5v58O/lib/python3.12/
      site-packages/hatchling/builders/wheel.py", line 248, in default_file_selection_options
          raise ValueError(message)
      ValueError: Unable to determine which files to ship inside the wheel using the following heuristics:
      https://hatch.pypa.io/latest/plugins/builder/wheel/#default-file-selection

      The most likely cause of this is that there is no directory that matches the name of your project
      (zbowling).

      At least one file selection option must be defined in the `tool.hatch.build.targets.wheel` table, see:
      https://hatch.pypa.io/latest/config/build/

      As an example, if you intend to ship a directory named `foo` that resides within a `src` directory located
      at the root of your project, you can define the following:

      [tool.hatch.build.targets.wheel]
      packages = ["src/foo"]
      ---

Issue description

Hatchling is failing to compile the pyproject which is the default that init produces as a build backend now after a recent commit to swap setuptools to hatchling.build

Change the init to this gets it to work: [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta"

Expected behavior

Should work.

Hofer-Julian commented 2 weeks ago

Hey @zbowling 👋🏻

To be honest, I wonder if what you see here is fine?

The error message is pretty clear and it also makes sense to me that if you have a pyproject.toml that there's also a corresponding python package.

zbowling commented 2 weeks ago

@Hofer-Julian The issue is you can't get into a shell to then use tools within the shell like python to help you generate the actual package since init doesn't generate a full package, just a pyproject.toml. Bit of a chicken and egg issue. Both pixi run and pixi shell shell fail immediately. This creates even more fun in vscode when you open the env in that folder. You get stuck in a loop.

Like if init is something like hatch new and it generates a src/, tests/, etc project with an empty init.py, then it would be fine. There would be enough. But you can't even pixi add --pypi hatch && pixi run hatch new.

setuptools doesn't bark or fail if you don't have any source files.

Hofer-Julian commented 2 weeks ago

Like if init something like hatch new and generated a src/, tests/, etc project with an empty init.py then it would be fine

I thought about it more and I agree with you. Let's adapt pixi init accordingly!

zbowling commented 2 weeks ago

I think we talking about adding a proper init template system at one point. there is a feature bug for that. Something like npm init so we can generate off scaffolds. that would help us down here downstream in mojo a ton :) but then we can have a hatch or poetry or pdm style init generation for different backends. long term bigger solution maybe.

zbowling commented 2 weeks ago

also build backend failures to install the current project by uv into the current env that can prevent a pixi shell and pixi run to execute is also a fun meta problem. You could be in the middle of working on your code, and if your code doesn't work right, then your shell might not start but then you can't use tools in your env to help you debug those issues. Probably makes sense decouple it.

This may require a bit of a rethink of the pyproject integration, but maybe not require <current_project> = { path = ".", editable=true } and just imply that maybe?? The just thinking out loud, but if uv can't install the package for the current directory, then maybe not fail to create a shell? Just hobble along? Would have to re-init your shell once your code does work unless we have an install command inside the env to reinstall the python package? This is gets meta of weird and I don't know the right answer but decoupling failing to install the current folder from the env maybe somehow is probably the right way to fix this deeper?

tdejager commented 2 weeks ago

Related issue: https://github.com/prefix-dev/pixi/issues/1903

Maybe we should just create a source hierarchy for now if it does not exist?

I do agree with @zbowling that there is maybe more to this and we should think about it a bit more, but I feel it might be a good short term solution?