poetry: Poetry scripts are breaking the documented behavior of sys.argv

  • Poetry version: 1.3.2

  • Python version: 3.10

  • OS version and name: Arch Linux

  • pyproject.toml: Not relevant (more info on the issue)

  • 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

This issue is a follow-up of flask#2588. You can get the full context there.

When running a script, Poetry is mutating the sys.argv. This breaks and violates the documented behavior of sys.argv and, therefore, must be avoided.

Regarding the practical issue (besides breaking the documented behavior of sys.argv), Flask reloader relies on sys.argv to reload the application automatically. Due to this, we can’t launch a Flask application with the reloader enabled due to this issue.

You can replicate this bug by doing the following:

  • Create a new Poetry application
  • Install Flask on it
  • Setup a minimal Flask application
  • Add a poetry script that will launch that application, something like:
[tool.poetry.scripts]
dev = 'my_package.main:run'
  • On your shell, set FLASK_DEBUG=1
  • Execute the Poetry script: poetry run dev
  • You’re going to get an error, saying that Python wasn’t able to open the file called dev (due to the fact that Poetry script is setting sys.argv = ["dev"]
  • Now, set FLASK_DEBUG=0
  • Launch the script again
  • You’ll see that, now, it works as expected

I’ve already opened that issue on Flask, and you can check Flask’s team explanation about why this issue isn’t related to them on this comment

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 32 (18 by maintainers)

Most upvoted comments

I open a discussion at https://github.com/python-poetry/poetry/discussions/7599 to we use to decide what to do with poetry run with unistalled scripts.

Adding to the discussion, I feel the wrongness feeling is being fueled by the fact that poetry run may have different behaviors regarding entry point (installed / non-installed).

So, I feel that poetry should forbid at all to run non installed entry points. What do maintainers think about it?

@wagnerluis1982 I think @davidism was able to create a workaround to handle it on Flask’s side, but I honestly don’t think this is the proper fix for that

I understand that poetry run is supposed to allow us handling anything (not only Python) that is currently in PATH, but this is counterproductive as soon as to do this we need to change Python execution in a way that damages the usability of Python scripts

For example, I have another PR that I think can be related to the same issue. On that issue, if we run a Python application without using Poetry we can successfully attach a debugger to it (using nvim-dap), but if we use Poetry it simply breaks as soon as the server launches

I’m still not 100% sure it is a related issue (I still need to debug it), but based on the current discussion I’m almost sure it is

There are +/- 2 sides here, I think:

  1. Poetry should be consistent in the behaviors of poetry run <script> and poetry shell, <script>. With #6737, this was resolved.
  2. sys.argv must be always self-callable (i.e. follow documented behavior), which in that case Poetry only guarantee with an installed script.

As a side note, I think we can achieve both with Poetry by not rewriting sys.argv on uninstalled scripts.

while you’re developing you’ll have the project installed in editable mode

I’m saying that with the PR sys.argv[0] will be absolute if the project is installed (even in editable mode). As far as I know, poetry does always install the root project in editable mode.