New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add python poetry support #995
base: master
Are you sure you want to change the base?
Conversation
PYPROJECT_TOML="${PYPROJECT_TOML:-pyproject.toml}" | ||
if [[ ! -f "$PYPROJECT_TOML" ]]; then | ||
log_error "No pyproject.toml found. Executing \`poetry init\` to create a \`$PYPROJECT_TOML\` first." | ||
poetry init |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I included poetry init
here as you queried whether such a command existed for pipenv
in PR #314. This line could be improved further with something like the following:
# Specify the active python rather than the one used to install poetry in case they are not the same.
poetry init --python ^$(python3 --version 2>/dev/null | cut -d' ' -f2 | cut -d. -f1-2)
But I didn't include it based on your reservations in PR #770.
I'm only learning to programme (starting with python) so I suggest you take extra care in considering this PR. It seems to work for me with this in my I noted in PRs #371 and #510 that With regard to the man files I noted the copyright is still given as 2019. I thought about changing this to the range 2019-2022 but decided in the end to ask first. I can update it to the range if you agree and update this PR. I also took the liberty of updating the CHANGELOG as well. I hope that is okay. Thanks for your time and this package. Edit: |
3df1721
to
8bb214b
Compare
8bb214b
to
19344c3
Compare
layout_poetry() { | ||
PYPROJECT_TOML="${PYPROJECT_TOML:-pyproject.toml}" | ||
if [[ ! -f "$PYPROJECT_TOML" ]]; then | ||
log_status "No pyproject.toml found. Executing \`poetry init\` to create a \`$PYPROJECT_TOML\` first." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems log_msg
does not exist but log_status
does so have used that instead to avoid alarming the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! It looks quite similar to my own implementation. I prefer less automatic command execution, especially for commands that might potentially run for several minutes on large projects.
I also proposed a somewhat hackish short-circuit condition that avoids the need for invoking poetry env info
. The poetry
CLI is slow, and I've found that invoking it when loading the direnv environment is quite annoying/jarring.
Feel free to ignore my comments 😅
PYPROJECT_TOML="${PYPROJECT_TOML:-pyproject.toml}" | ||
if [[ ! -f "$PYPROJECT_TOML" ]]; then | ||
log_status "No pyproject.toml found. Executing \`poetry init\` to create a \`$PYPROJECT_TOML\` first." | ||
poetry init |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better (and less surprising) if we inform the user that they need to run poetry init
instead of automatically executing that command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed the older revisions on the wiki had only a log_error
message advising the user to either execute poetry new
or poetry init
to create the pyproject.toml
file. I included the poetry init
command as @zimbatm had queried whether such a command existed for pipenv
in PR #314. I presumed they would make the same query about poetry
if unfamiliar with it. I can remove it and revert back to just a log_error
message if that is preferable.
My only argument for keeping it as is, is that with a log_error
message we exit the layout_poetry()
function and so the remainder of the function is not executed unless the user cd
s out of and then back into their project directory which is inefficient. I suppose one could argue poetry
users would know they should follow a poetry new
or poetry init
command with something like a poetry install
command before they start to work but beginners (such as myself) may not. (I would of course know having learnt how these tools work in putting this PR together.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running poetry init
in a non-Poetry-project directory starts an interactive guide which asks the user questions about how they want to configure their new project. I personally think it's not a good idea to run such a thing automatically.
Running poetry init --quiet
or poetry init --no-interaction
will create a minimal project without asking questions, but still better to let the user run the command how they themselves choose in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running poetry init in a non-Poetry-project directory starts an interactive guide which asks the user questions about how they want to configure their new project.
One could argue that in running that command the user intends to covert their project into a poetry managed project and the command interaction allows them to tailor it to their tastes.
Running poetry init --quiet or poetry init --no-interaction will create a minimal project without asking questions
Yes, and it is an improvement I mentioned in the wiki. I've not included in the PR yet as I was waiting to hear @zimbatm thoughts about such options considering they asked about such options when the pipenv
support was being added.
but still better to let the user run the command how they themselves choose in my opinion.
Happy to revert to just a log_status message if that is the majority view. Please see my reasons for including it in the first place here.
|
||
if [[ -z $VIRTUAL_ENV || ! -d $VIRTUAL_ENV ]]; then | ||
log_status "No virtual environment exists. Executing \`poetry install\` to create one." | ||
poetry install |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my earlier comment on automatically executing commands. I realize this is not how e.g., layout_pipenv()
is implemented, but I would prefer less automatic execution of commands that might potentially run for several minutes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted, and some context provided in my earlier reply. I've not found poetry install
to be slow but I really just have it install the active python version to the virtual environment and add my projects dependencies or dev dependencies later with poetry add
. But I agree others may have it install everything they need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
poetry install
has a multitude of options to install different groups of packages etc. While an argument could be made to install the default set of packages, how do you know if the user wants to run poetry install
or perhaps poetry install --no-root
? Better to let the user choose here as well I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to let the user choose here as well I think.
Happy to revert to just a log_status message if that is the majority view. Please see my reasons for including it in the first place here.
stdlib.sh
Outdated
poetry init | ||
fi | ||
|
||
VIRTUAL_ENV=$(poetry env info --path 2>/dev/null ; true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my own custom version of layout_poetry()
I've added a short-circuiting branch here to avoid invoking the poetry
CLI because it's so slow. Note that my short-circuit approach is entirely based upon running Poetry with the virtualenvs.in-project
config option set to true
. It might be possible to adapt it for the false
case as well, but I haven't invested any time towards that.
VIRTUAL_ENV=$(poetry env info --path 2>/dev/null ; true) | |
# Try to short-circuit the need to invoke poetry because it's slow. | |
# If we find an "in-project" virtual env, assume it's what we're looking for. | |
if [[ -d ".venv" ]]; then | |
VIRTUAL_ENV="$(pwd)/.venv" | |
else | |
VIRTUAL_ENV="$(poetry env info --path 2>/dev/null ; true)" | |
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
poetry
CLI because it's so slow
Indeed, I even suggested in the wiki to use the --no-interaction
option with the init
command (i.e. poetry --no-interaction init
) to get a basic pyproject.toml
rather than have the user answer the prompts to create it and risk direnv
complain the process is taking too long for its liking.
I've not found poetry install
to be slow but I really just have it install the active python version to the virtual environment and add my projects dependencies or dev dependencies later with poetry add
.
It might be possible to adapt it for the false case as well, but I haven't invested any time towards that.
Which false case do you mean here. The case where the virtualenvs.in-project
setting is false
but the .venv
exists or where the setting is false
and the virtual environment exists in {cache-dir}/virtualenvs
. Would the former case cause issues for poetry in knowing where to install packages? The latter case may be difficult as poetry
names the virtual environment based on what the user has named their project directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my own custom version of
layout_poetry()
I've added a short-circuiting branch here to avoid invoking thepoetry
CLI because it's so slow.
This is a great idea. We also use .venv in projects, so this has fixed my issue, as I was just digging into why this step was slow and thought it was the poetry env step. I think it's a great tip, so I added it to the wiki as a note.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe include it in the layout_poetry
function in the wiki directly? I can update the PR in the same way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, PR updated to reflect this check.
Edit: Wiki updated in the same way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this check for .venv
. This is very idiosyncratic. Some people call it venv
; others call it ENV
. See https://github.com/github/gitignore/blob/4488915eec0b3a45b5c63ead28f286819c0917de/Python.gitignore#L123-L127
Also, direnv's stdlib makes no mention of what seems like an arbitrary choice of .venv
. Here's what's used instead:
Line 827 in 7608dae
VIRTUAL_ENV=$(direnv_layout_dir)/python-$python_version |
It seems this would be mixing different layout models, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, it might make sense to support a custom VIRTUAL_ENV
that's already defined, as in:
Lines 822 to 826 in 7608dae
if [[ -n "${VIRTUAL_ENV:-}" ]]; then | |
local REPLY | |
realpath.absolute "$VIRTUAL_ENV" | |
VIRTUAL_ENV=$REPLY | |
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this check for
.venv
. This is very idiosyncratic. Some people call itvenv
; others call itENV
.
The check is on .venv
because that is what poetry
will look for when the virtual environment is in-project. See here.
It seems this would be mixing different layout models, no?
Not really. One can either allow direnv
or poetry
to manage the virtual environments. There will be no conflict but it is probably best practice to be consistent in your choice to avoid confusion.
Resolves: direnv#592
19344c3
to
4f14b54
Compare
I have this |
I had to change the script I found on the wiki because it doesnt work if you never installed poetry... so this is how it looks like now:
could this also be included in this PR? |
I'd be happy to update the PR in this regard if @zimbatm agrees but do we want |
uff I didnt think about that you are right. That could just be documented as well or you could add some optional value to auto install... This is completely out of my depth so I will just see where the thread goes :) |
I cannot speak for all users, but I would definitely never pipe a shell script downloaded from |
I emphatically agree with haplo here; having a direnv .envrc file reach out to the internet to pull code would be unacceptable to me; in this case, I don't use Poetry, really, but I'd hate to see this precedent merged. |
I can understand what you mean but you are using the wrong argument.
Poetry install goes to the internet to download a shit ton of packages
depending on your project.
Either way I have no say in this since I am not a maintainer of this
library.
I'm just happy this is going to exist :)
I also would like to ask one question:
How are the locations of the virtual envs managed?
Is this direnv or poetry?
…On Wed, Jan 11, 2023, 20:55 Chris Rose ***@***.***> wrote:
I emphatically agree with haplo here; having a direnv .envrc file reach
out to the internet to pull code would be unacceptable to me; in this case,
I don't use Poetry, really, but I'd hate to see this precedent merged.
—
Reply to this email directly, view it on GitHub
<#995 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AD7WGRYSJXZTRJ6YEBK7ZZLWR4M4NANCNFSM6AAAAAAREKHKWM>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Ah! Could we just add an if then that shows a message that you need to
install poetry if it's not found?
…On Wed, Jan 11, 2023, 23:50 David Maia ***@***.***> wrote:
I can understand what you mean but you are using the wrong argument.
Poetry install goes to the internet to download a shit ton of packages
depending on your project.
Either way I have no say in this since I am not a maintainer of this
library.
I'm just happy this is going to exist :)
I also would like to ask one question:
How are the locations of the virtual envs managed?
Is this direnv or poetry?
On Wed, Jan 11, 2023, 20:55 Chris Rose ***@***.***> wrote:
> I emphatically agree with haplo here; having a direnv .envrc file reach
> out to the internet to pull code would be unacceptable to me; in this case,
> I don't use Poetry, really, but I'd hate to see this precedent merged.
>
> —
> Reply to this email directly, view it on GitHub
> <#995 (comment)>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AD7WGRYSJXZTRJ6YEBK7ZZLWR4M4NANCNFSM6AAAAAAREKHKWM>
> .
> You are receiving this because you are subscribed to this thread.Message
> ID: ***@***.***>
>
|
@dagadbm there is a world of difference between a package manager that installs code from relatively trusted package registries through a protocol that is documented and that installs structured contents that you explicitly requested as part of your package and a Poetry doesn't, actually, necessarily go to the internet to install packages, although it often does; that's entirely a function of your project configuration. Anyway, the correct thing here, I think, would be for this direnv tool to gracefully degrade and notify the user that they need to install poetry in their |
I agree with you so there is no need to continue providing arguments. I was
just saying that the problem is not "going to the internet" per se but
going god knows where to the internet.
…On Thu, Jan 12, 2023 at 12:44 AM Chris Rose ***@***.***> wrote:
@dagadbm <https://github.com/dagadbm> there is a world of difference
between a package manager that installs code from relatively trusted
package registries through a protocol that is documented and that installs
structured contents that you explicitly requested as part of your package
and a curl ... | bash with no signing or contents verification,
installing an arbitrary and unbounded version of a tool that may or may not
be the right thing.
Poetry doesn't, actually, necessarily go to the internet to install
packages, although it often does; that's entirely a function of your
project configuration.
Anyway, the correct thing here, I think, would be for this direnv tool to
gracefully degrade and notify the user that they need to install poetry in
their PATH and then to run direnv reload
—
Reply to this email directly, view it on GitHub
<#995 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AD7WGR36OQTGDFTVCV5NXKDWR5HVHANCNFSM6AAAAAAREKHKWM>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
if [[ -d ".venv" ]]; then | ||
VIRTUAL_ENV="$(pwd)/.venv" | ||
else | ||
VIRTUAL_ENV=$(poetry env info --path 2>/dev/null ; true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add double quotes:
VIRTUAL_ENV=$(poetry env info --path 2>/dev/null ; true) | |
VIRTUAL_ENV="$(poetry env info --path 2>/dev/null; true)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I omitted such quotes in keeping with the style already used within the stdlib.sh
.
if [[ -z $VIRTUAL_ENV || ! -d $VIRTUAL_ENV ]]; then | ||
log_status "No virtual environment exists. Executing \`poetry install\` to create one." | ||
poetry install | ||
VIRTUAL_ENV=$(poetry env info --path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add double quotes:
VIRTUAL_ENV=$(poetry env info --path) | |
VIRTUAL_ENV="$(poetry env info --path)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
I've been using this for a couple of days, and it works well. My only issue is that poetry allows for multiple environments to be associated with a project, when one switches from one environment to another, using for example –
direnv will still have the old environment activated. I'm not sure whether there is an easy solution to this. Just thought I'd point this out, because it is quite confusing. |
Does it? I've not had a reason to use this command so don't know but reading the docs doesn't it update your
Right, because it is looking for changes to your
Rather than using that poetry command, if you edit your |
This is a minimal example:
you can then create a few environments with:
So you have three environments associated with the project and 1 "active"
direnv will successfully activate the right environment for you. you may wan to "activate" a different one
but at this point, direnv will still have the python 3.11 environment activated |
This patch tracks my custom direnv layout for Poetry projects. There is ongoing work towards getting a variant of this function added to the direnv stdlib. Until that work is done, this function is necessary. Ref: direnv/direnv#995
as
|
fi | ||
|
||
PATH_add "$VIRTUAL_ENV/bin" | ||
export POETRY_ACTIVE=1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to use a generic ENV_VAR name here such as VENV_ACTIVE since POETRY_ACTIVE is set when one executes poetry shell
but we don't do this here?
Convenience for users of direnv, let's keep it out of the repo, especially that direnv lacks support for Poetry in its stdlib [1, 2]. [1]: https://github.com/direnv/direnv/wiki/Python#poetry [2]: direnv/direnv#995
Convenience for users of direnv, let's keep it out of the repo, especially that direnv lacks support for Poetry in its stdlib [1, 2]. [1]: https://github.com/direnv/direnv/wiki/Python#poetry [2]: direnv/direnv#995
Convenience for users of direnv, let's keep it out of the repo, especially that direnv lacks support for Poetry in its stdlib [1, 2]. [1]: https://github.com/direnv/direnv/wiki/Python#poetry [2]: direnv/direnv#995
Convenience for users of direnv, let's keep it out of the repo, especially that direnv lacks support for Poetry in its stdlib [1, 2]. [1]: https://github.com/direnv/direnv/wiki/Python#poetry [2]: direnv/direnv#995
Convenience for users of direnv, let's keep it out of the repo, especially that direnv lacks support for Poetry in its stdlib [1, 2]. [1]: https://github.com/direnv/direnv/wiki/Python#poetry [2]: direnv/direnv#995
i was noticing that by default the VIRTUAL_ENV of python layout (and i imagine direnv in general?) is actually I would like to ask why this is not the case with this script since he is checking for |
Because I based this PR on the
It checks for the presence of a If you really want to use a poetry config virtualenvs.path .direnv --local The echo -e 'poetry config virtualenvs.path .direnv --local\nlayout poetry' > .envrc |
Brings in WIP from direnv, see direnv/direnv#995
Resolves: #592