python-poetry / python-poetry/poetry

Wheel building fails with stack trace when symlink to external path is encountered

Open
#7,227 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind/bug status/triage
Dominant language
Python
Stars
34.3k
Forks
2.5k
Avg merge
2d 19h
Merged PRs (30d)
30

Description

  • Poetry version: 1.3.1
  • Python version: 3.8
  • OS version and name: Ubuntu 20.04
  • pyproject.toml: (default generated)
  • I am on the latest stable Poetry version, installed using a recommended method.
  • I have searched the issues of this repo and believe that this is not a duplicate.
  • I have consulted the FAQ and blog for any relevant entries or release notes.
  • If an exception occurs when executing a command, I executed it again in debug mode (-vvv option) and have included the output below.

Issue

If the code directory contains a venv, poetry fails with a ValueError such as '/usr/bin/python3.8' does not start with '/home/konsti/a'. I don't need virtualenv inside the code directory to be supported, but rather a confusing error message; The current one makes it seem like the activated python is badly broken.

$ poetry init -n
$ mkdir a
$ touch a/__init__.py
$ touch README.md
$ poetry build -f wheel
Building a (0.1.0)
  - Building wheel
  - Built a-0.1.0-py3-none-any.whl
$ virtualenv a/.venv
created virtual environment CPython3.8.10.final.0-64 in 159ms
  creator CPython3Posix(dest=/home/konsti/a/a/.venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/konsti/.local/share/virtualenv)
    added seed packages: pip==22.3.1, setuptools==65.6.3, wheel==0.38.4
  activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
$ poetry build -f wheel
Building a (0.1.0)
  - Building wheel

'/usr/bin/python3.8' does not start with '/home/konsti/a'
$ poetry build -f wheel -vvv
Loading configuration file /home/konsti/.config/pypoetry/config.toml
Using virtualenv: /home/konsti/a/.venv
Building a (0.1.0)
  - Building wheel
  - Adding: /home/konsti/a/a/.venv/.gitignore
  - Adding: /home/konsti/a/a/.venv/bin/activate
  - Adding: /home/konsti/a/a/.venv/bin/activate.csh
  - Adding: /home/konsti/a/a/.venv/bin/activate.fish
  - Adding: /home/konsti/a/a/.venv/bin/activate.nu
  - Adding: /home/konsti/a/a/.venv/bin/activate.ps1
  - Adding: /home/konsti/a/a/.venv/bin/activate_this.py
  - Adding: /home/konsti/a/a/.venv/bin/pip
  - Adding: /home/konsti/a/a/.venv/bin/pip-3.8
  - Adding: /home/konsti/a/a/.venv/bin/pip3
  - Adding: /home/konsti/a/a/.venv/bin/pip3.8

  Stack trace:

  13  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/cleo/application.py:327 in run
       325│ 
       326│             try:
     → 327│                 exit_code = self._run(io)
       328│             except BrokenPipeError:
       329│                 # If we are piped to another process, it may close early and send a

  12  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/console/application.py:190 in _run
       188│         self._load_plugins(io)
       189│ 
     → 190│         exit_code: int = super()._run(io)
       191│         return exit_code
       192│ 

  11  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/cleo/application.py:431 in _run
       429│             io.input.interactive(interactive)
       430│ 
     → 431│         exit_code = self._run_command(command, io)
       432│         self._running_command = None
       433│ 

  10  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/cleo/application.py:473 in _run_command
       471│ 
       472│         if error is not None:
     → 473│             raise error
       474│ 
       475│         return terminate_event.exit_code

   9  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/cleo/application.py:457 in _run_command
       455│ 
       456│             if command_event.command_should_run():
     → 457│                 exit_code = command.run(io)
       458│             else:
       459│                 exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED

   8  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/cleo/commands/base_command.py:119 in run
       117│         io.input.validate()
       118│ 
     → 119│         status_code = self.execute(io)
       120│ 
       121│         if status_code is None:

   7  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/cleo/commands/command.py:62 in execute
        60│ 
        61│         try:
     →  62│             return self.handle()
        63│         except KeyboardInterrupt:
        64│             return 1

   6  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/console/commands/build.py:34 in handle
        32│ 
        33│             builder = Builder(self.poetry)
     →  34│             builder.build(fmt, executable=env.python)
        35│ 
        36│         return 0

   5  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/core/masonry/builder.py:33 in build
        31│ 
        32│         for builder in builders:
     →  33│             builder(self._poetry, executable=executable).build()
        34│ 

   4  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/core/masonry/builders/wheel.py:117 in build
       115│                 self._add_pth(zip_file)
       116│             elif self._poetry.package.build_should_generate_setup():
     → 117│                 self._copy_module(zip_file)
       118│                 self._build(zip_file)
       119│             else:

   3  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/core/masonry/builders/wheel.py:232 in _copy_module
       230│ 
       231│     def _copy_module(self, wheel: zipfile.ZipFile) -> None:
     → 232│         to_add = self.find_files_to_add()
       233│ 
       234│         # Walk the files and compress them,

   2  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/core/masonry/builders/builder.py:199 in find_files_to_add
       197│ 
       198│                 if self.is_excluded(
     → 199│                     include_file.relative_to_project_root()
       200│                 ) and isinstance(include, PackageInclude):
       201│                     continue

   1  ~/.local/share/pypoetry/venv/lib/python3.8/site-packages/poetry/core/masonry/builders/builder.py:392 in relative_to_project_root
       390│ 
       391│     def relative_to_project_root(self) -> Path:
     → 392│         return self.path.relative_to(self.project_root)
       393│ 
       394│     def relative_to_source_root(self) -> Path:

  ValueError

  '/usr/bin/python3.8' does not start with '/home/konsti/a'

  at /usr/lib/python3.8/pathlib.py:908 in relative_to
       904│         n = len(to_abs_parts)
       905│         cf = self._flavour.casefold_parts
       906│         if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts):
       907│             formatted = self._format_parsed_parts(to_drv, to_root, to_parts)
    →  908│             raise ValueError("{!r} does not start with {!r}"
       909│                              .format(str(self), str(formatted)))
       910│         return self._from_parsed_parts('', root if n == 1 else '',
       911│                                        abs_parts[n:])
       912│ 

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce with poetry build -f wheel after creating a/.venv, then start at poetry/core/masonry/builders/builder.py:relative_to_project_root and follow the call from poetry/core/masonry/builders/wheel.py:_copy_module. Done means a project containing a venv or external symlink no longer produces the raw ValueError stack trace and instead reports the intended failure clearly.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.