pipx
pipx copied to clipboard
Add a command to emit a path to the Python executable in an env, or delegate to it
Feature request: emit the path to a Pipx-managed env, or delegate commands to a Pipx-managed Python binary
How would this feature be useful?
There have been a few cases (https://github.com/pipxproject/pipx/issues/177, https://github.com/pipxproject/pipx/issues/600, https://github.com/pipxproject/pipx/pull/602, and https://github.com/microsoft/debugpy/pull/508) where it would be beneficial for the user to be able to customize how a "tool" installed by Pipx is invoked.
Describe the solution you'd like
My proposed solution is:
- Allow the user (at their specific request) to install packages that don't contain any entry points, maybe
pipx install --no-apps. - Provide a new subcommand so that the user can access the underlying Python for a given environment, one or both of:
a.
pipx prefix <env-name>, which just prints the path to the environment prefix, so the user can write commands like$( pipx prefix foo )/bin/python -m foo.invoke. b.pipx python <env-name>, which passes all its args to the underlying Python, so the user can write commands likepipx python foo -m foo.invoke.
I believe this is the most general and flexible solution to the problem. It solves the specific problems laid out here with a minimum of excess verbosity on the command line, while also providing a general and relatively low-level "primitive" with which end users could their own interesting and sophisticated functionality on top of Pipx.
Describe alternatives you've considered
- Support a
-mfeature, as described in #177. - Support a special type of Setuptools entry point, as described in #600 and draft implemented in #602.
- Allow the user to specify, at install time (and later modify) custom entry points to be added to those exposed by the installed package; as a corollary, they could also be able to selectively whitelist entry points, perhaps to limit which entry points are recognized by
--include-deps.
I think Option 1 is an instance of the sororicide antipattern being too use-case-specific without solving the general problem.
Option 2 causes a weird inversion of the dependency graph between tools, and does not solve the problem where end-users are dependent on upstream package developers for Pipx compatibility.
Option 3 could be potentially useful in cases where 2 different packages expose entry points with identical names, as well as the case where --include-deps creates many more entry points than expected. I think Pipx could and should give the user the ability to exercise finer control over what is actually installed. But I still see usefulness in the current proposal, and I think this Option 3 proposal would make sense in addition to the current propsal.
In general, I'd like to see more "low-level" plumbing style interfaces in Pipx, similar to those in Homebrew, like brew link, brew --prefix, etc. If the end user has access to a carefully-chosen set of low-level primitives, it becomes easier for the user to build high-level functionality, and the tool itself becomes more powerful without becoming more complicated.
I would be very happy to work on the features in this PR, if there is interest from the Pipx devs.
In general I'm personally less interested in this direction. At some point, if you understand all the low-level plumbing that this would give you access to, you may as well just make the venv yourself, and have access to the full freedom of python.
In general I'm personally less interested in this direction. At some point, if you understand all the low-level plumbing that this would give you access to, you may as well just make the venv yourself, and have access to the full freedom of python.
That's fair, although I'm less interested in writing my own version of Pipx than I am in contributing back to Pipx :)
What about something like virtualenvwrapper? It seems like this would take care of a lot of your use case, centralizing venvs, but allowing full access.
I appreciate the support for pipx! And things like this are worth discussing. The trick is that there needs to be a line drawn somewhere for pipx, where we support many applications but not all. And given that other tools handle some of these use cases (like virtualenvwrapper) it suggests to me that we can omit this functionality.
Keep in mind option 2 is implemented and released, AFAIK.
What about something like virtualenvwrapper? It seems like this would take care of a lot of your use case, centralizing venvs, but allowing full access.
I appreciate the support for pipx! And things like this are worth discussing. The trick is that there needs to be a line drawn somewhere for pipx, where we support many applications but not all. And given that other tools handle some of these use cases (like virtualenvwrapper) it suggests to me that we can omit this functionality.
I understand your desire to restrict the scope of the tool.
The reason I proposed this solution is because it doesn't actually add any new functionality. It just gives people access to an internal mechanism that lets them do more sophisticated things with the tool, using functionality that already exists in the tool. Whereas adding a special delegator to -m and a handler for special Setuptools entry points is new functionality that increases the complexity of the tool.
Like I said, I don't want to write my own version of Pipx. Yes, I could do most of what Pipx does with Virtualenvwrapper and a shell script, or I could do it all with a shell script and just the Venv that ships with Python. Or maybe I could write a Pyenv plugin. Maybe my version would be better, who knows (although I seriously doubt it). But that's not the point of my proposing this feature.
I won't press the issue further. Ultimately, it's not my project and it's not my place to decide. But my final argument in favor of this proposal is that this is not supporting one specific use case, or even any specific use case (although I happened to lay one out in the OP). I can think of many good reasons why someone might want "low-level" access to the Python in each environment, even if it's something as basic as resolving ${PIPX_HOME:-${XDG_DATA_HOME:-$HOME/.local/share}/pipx}/${env_name}. If anything, it could potentially head off or obviate a lot of other feature requests, since it will be easy to say "use pipx prefix and do it yourself with the underlying Python, we won't add special support for that use case."
~~Heck, it would have obviated the new feature that was just merged into Pipx (the 2nd option from the OP).~~ (not true; see https://github.com/pipxproject/pipx/issues/639#issuecomment-789393622)
Heck, it would have obviated the new feature that was just merged into Pipx (the 2nd option from the OP).
Huh? The new feature allows pipx run —spec build pyproject-build to be written as pipx run build. I don’t see how your proposal would allow that at all. You want access to the Python in an installed environment, that was about running from temporary environments.
Heck, it would have obviated the new feature that was just merged into Pipx (the 2nd option from the OP).
Huh? The new feature allows
pipx run —spec build pyproject-buildto be written aspipx run build. I don’t see how your proposal would allow that at all. You want access to the Python in an installed environment, that was about running from temporary environments.
You're right, thanks for correcting my mistake.
However, one could also add this functionality to temporary environments :)
Heck, it would have obviated the new feature that was just merged into Pipx (the 2nd option from the OP).
Huh? The new feature allows
pipx run —spec build pyproject-buildto be written aspipx run build. I don’t see how your proposal would allow that at all. You want access to the Python in an installed environment, that was about running from temporary environments.