Skip to content
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

New Python template for pip without pipenv #324

Closed
cmclaughlin opened this issue Aug 18, 2020 · 12 comments
Closed

New Python template for pip without pipenv #324

cmclaughlin opened this issue Aug 18, 2020 · 12 comments
Labels
enhancement New feature or request language/python

Comments

@cmclaughlin
Copy link
Contributor

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

pipenv is really slow and sometimes it hangs for a really long time.

Any objection to removing it? I think leaving the Python env setup to the user is fine - and just recommending Pyenv + virtualenv. Perhaps writing out a simple requirements.txt file instead of a Pipfile in new templates and docs.

Example where it hangs for me - perhaps because I'm using a private PyPi instance that makes it worse, but that works fine with plain pip.

Installing dependencies from Pipfile.lock (8d4353)…

References

pypa/pipenv#3827

@cmclaughlin cmclaughlin added the enhancement New feature or request label Aug 18, 2020
cmclaughlin added a commit to cmclaughlin/terraform-cdk that referenced this issue Aug 19, 2020
pipenv is really slow and sometimes it hangs for a really long time.
Perhaps because I'm using a private PyPi instance that makes it worse,
but that works fine with plain pip.

This seems to be a common problem - see and the several other linked
issues there:

pypa/pipenv#3827

So far, this is just the result of grep/search/replace. Haven't
tested this at all. Just want to start by getting some feedback
if this is going to be something that everyone is OK with.

Closes hashicorp#324
cmclaughlin added a commit to cmclaughlin/terraform-cdk that referenced this issue Aug 19, 2020
pipenv is really slow and sometimes it hangs for a really long time.
Perhaps because I'm using a private PyPi instance that makes it worse,
but that works fine with plain pip.

This seems to be a common problem - see and the several other linked
issues there:

pypa/pipenv#3827

So far, this is just the result of grep/search/replace. Haven't
tested this at all and there's more work to do. Just want to start by getting
some feedback if this is going to be something that everyone is OK with.

Closes hashicorp#324
cmclaughlin added a commit to cmclaughlin/terraform-cdk that referenced this issue Aug 19, 2020
pipenv is really slow and sometimes it hangs for a really long time.
Perhaps because I'm using a private PyPi instance that makes it worse,
but that works fine with plain pip.

This seems to be a common problem - see and the several other linked
issues there:

pypa/pipenv#3827

So far, this is just the result of grep/search/replace. Haven't
tested this at all and there's more work to do. Just want to start by getting
some feedback if this is going to be something that everyone is OK with.

Closes hashicorp#324
@cmclaughlin
Copy link
Contributor Author

I have a rough draft PR going here - #327.
Please let me know if there are any concerns.

@skorfmann
Copy link
Contributor

My gut feeling right now is, that this isn't something which we should just do. I'm not a frequent Python user, so I'll have to familiarize myself with the implications this has.

Example where it hangs for me - perhaps because I'm using a private PyPi instance that makes it worse, but that works fine with plain pip.

Why is the private PyPi instance worse?

@cmclaughlin
Copy link
Contributor Author

cmclaughlin commented Aug 19, 2020

I can't imagine why my private PyPi would make the situation worse - it's a CodeArtifact repo hosted by AWS, so it should be fast and reliable. But let's ignore that for now - at my company we have one other non-cdktf project where someone tried to use pipenv - that doesn't use our new private PyPi - and we've had the same sorts of problems with pipenv there. Install and "locking" takes infinitely long for some users at some times and for other users at other times it's only moderately slow. By taking infinitely long, I mean it's so frustratingly slow we might have to walk away from our computer for a while only to come back and control+c to give up. Then we might try the same command later in the day on the same computer and it will work. There's no debug output to even get a better idea why it hangs, so it's super annoying. The slowness seems to be related to pipenv re-downloading all dependencies for every operation just to check the hashes. So as a project grows larger, this problem becomes more common. You might never see it in simple examples, but for larger Python projects I'd consider pipenv not ready for production use.

Personally, I don't see pipenv offering much over plain pip. It seems to mimic some of the features of other package managers from the JavaScript and Ruby communities, but I don't think Python had a problem in this area. It's just a solution looking for a problem and it's only made the situation worse and more confusing. A simple requirements.txt file is simple and good enough for most apps and traditional packaging via setup.py is rock solid. By the way, in case you're under the impression that pipenv is an official package manager for Python (the pipenv docs used to say something like that) -- it's not. pipenv is not common in the Python community and it's certainly not a standard.

This blog post describes the situation very well:

https://chriswarrick.com/blog/2018/07/17/pipenv-promises-a-lot-delivers-very-little/

And here are more references showing how bad it is:

pypa/pipenv#3827
pypa/pipenv#4260
pypa/pipenv#2873
pypa/pipenv#356
pypa/pipenv#2681
pypa/pipenv#3812
pypa/pipenv#3829

https://stackoverflow.com/questions/57646310/is-pythons-pipenv-slow
https://stackoverflow.com/questions/56440090/pipenv-stuck-locking

In closing, my recommendation is pyenv for managing multiple Python interpreter versions (e.g. 3.6.x, 3.7.x, etc) and the pyenv-virtualenv plugin (https://github.com/pyenv/pyenv-virtualenv) for managing application specific environments. Both are easy to install/use (e.g. homebrew), fast and reliable. pipenv has wasted so much of my time that I'm motivated to do the work to rip it out of cdktf, but I don't want to spend a bunch of time on the PR unless you're on board with the idea.

@jsteinich
Copy link
Collaborator

I also ran into pypa/pipenv#1050 when trying to get cdktf python working on Windows.
As it stands now, it is enforcing a more specific version of python to be installed then I think is desired.

@skorfmann
Copy link
Contributor

@cmclaughlin thanks for elaborating on this, very appreciated! I'll go through the links and collect more feedback on this.

@jsteinich

I also ran into pypa/pipenv#1050 when trying to get cdktf python working on Windows.

So you think Pipenv makes it harder to use on Windows?

As it stands now, it is enforcing a more specific version of python to be installed then I think is desired.

Still haven't gotten a precise version compatibility info about Jsii - just saw a comment today stating > 3.7 - but not sure if that's a hard fact.

@jsteinich
Copy link
Collaborator

So you think Pipenv makes it harder to use on Windows?

I don't think it's specific to Windows. Right now the python template says that 3.7 is required. I have 3.8.5 installed. I believe I was hitting #268, but it's been awhile and maybe it wasn't caused by the python version mismatch. Once I get a few other pieces taken care of I can go back and check.

@anubhavmishra
Copy link
Member

anubhavmishra commented Aug 20, 2020

@skorfmann I don't think I have seen issues with pipenv. My python projects have been fairly quick when initializing and synthesizing applications. I think we should gather more feedback, look at what @cmclaughlin has linked and other folks in the community.

@cmclaughlin
Copy link
Contributor Author

I spent some time looking into my specific/recent problem with pipenv... I've determined pipenv is not compatible with AWS Code Artifact... sorry I brushed that off as a possibility earlier. While most cdktf users won't experience this, it certainly frustrates me enough to not want to use pipenv and recommend against anyone else using - because it's not following what the rest of the Python community is doing. Add that to my previous bad experiences with it, heaps of other people that don't like it and the general feeling that it's slow and unnecessary.

Here are more details:

PyPi has a "legacy" API with a "/simple" endpoint.
Despite the name, it's still used.

The PyPi reference implementation supports listing all packages via that endpoint, however as best as I can tell normal pip does not use it.

Here you can see the endpoint is still supported.

$ curl -s https://pypi.org/simple/ | head
<!DOCTYPE html>
<html>
  <head>
    <title>Simple index</title>
  </head>
  <body>
    <a href="/simple/0/">0</a>
    <a href="/simple/0-0/">0-._.-._.-._.-._.-._.-._.-0</a>
    <a href="/simple/00000a/">00000a</a>
    <a href="/simple/0-0-1/">0.0.1</a>

I'm under the impression that normal pip used to parse that HTML response to follow links to packages or perhaps it still uses the HTML response to search/list packages. But I'm pretty sure newer endpoints, such as the JSON API, are used for that now.

I am fairly certain normal pip does not use the /simple endpoint to install packages. Instead it simply gets /simple/$PACKAGE_NAME. I scoured through the pip code to confirm this, but ultimately some simple verbose output shows that installing boto3 goes straight to /simple/boto3/

$ pip --no-cache-dir -v install boto3
https://pypi.org/simple
https://test.pypi.org/simple
Using pip 20.2.2 from /Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pip (python 3.8)
Non-user install because user site-packages disabled
Created temporary directory: /private/var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pip-ephem-wheel-cache-hsm01ybq
Created temporary directory: /private/var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pip-req-tracker-9i8hbanx
Initialized build tracking at /private/var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pip-req-tracker-9i8hbanx
Created build tracker: /private/var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pip-req-tracker-9i8hbanx
Entered build tracker: /private/var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pip-req-tracker-9i8hbanx
Created temporary directory: /private/var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pip-install-vpuyirq2
1 location(s) to search for versions of boto3:
* https://pypi.org/simple/boto3/
Fetching project page and analyzing links: https://pypi.org/simple/boto3/
Getting page https://pypi.org/simple/boto3/
Found index url https://pypi.org/simple
Starting new HTTPS connection (1): pypi.org:443
https://pypi.org:443 "GET /simple/boto3/ HTTP/1.1" 200 114817
  Found link https://files.pythonhosted.org/packages/3f/95/a24847c245befa8c50a9516cbdca309880bd21b5879e7c895e953217e947/boto3-0.0.1-py2.py3-none-any.whl#sha256=bc9b3ce78d3863e45b43a33d076c7b0561f6590205c94f0f8a23a4738e79a13f (from https://pypi.org/simple/boto3/), version: 0.0.1

Now, on to AWS CodeArtifact - it implements the PyPi spec, but it does not support listing packages via the simple API - from https://docs.aws.amazon.com/codeartifact/latest/ug/python-compatibility.html:

"CodeArtifact supports PyPI's Legacy APIs, except the simple API. CodeArtifact does not support PyPI's XML-RPC or JSON APIs."

Clearly AWS left out support for listing the /simple endpoint intentionally - presumably because they knew pip no longer uses it.

This is relevant because when you use a private PyPI with pipenv, you add it as a source to the Pipfile - here's an example:

[[source]]
url = "https://aws:$CODEARTIFACT_AUTH_TOKEN@repo-account_id.d.codeartifact.us-east-1.amazonaws.com/pypi/company/simple/"
verify_ssl = true
name = "code-artifact"

Sadly, pipenv uses the /simple API to list packages. It took me a while to figure this out - here's an example where I waited over two hours with no errors.

$ time pipenv install psycopg2-binary
Courtesy Notice: Pipenv found itself running within a virtual environment, so it will automatically use that environment, instead of creating its own for any project. You can set PIPENV_IGNORE_VIRTUALENVS=1 to force pipenv to ignore that environment and create its own instead. You can set PIPENV_VERBOSITY=-1 to suppress this warning.
Installing psycopg2-binary…
✘
Error:  An error occurred while installing psycopg2-binary!
WARNING: I/O operation on closed file
Traceback (most recent call last):
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/core.py", line 2125, in do_install
    sp.write_err(
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/vistir/spin.py", line 316, in write_err
    self.out_buff.write(decode_output(text, target_stream=self.out_buff))
ValueError: I/O operation on closed file

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/cmclaughlin-local/.pyenv/versions/cdktf/bin/pipenv", line 10, in <module>
    sys.exit(cli())
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/cli/command.py", line 232, in install
    retcode = do_install(
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/core.py", line 2146, in do_install
    sp.write_err(vistir.compat.fs_str(
  File "/Users/cmclaughlin-local/.pyenv/versions/3.8.2/envs/cdktf/lib/python3.8/site-packages/pipenv/vendor/vistir/spin.py", line 316, in write_err
    self.out_buff.write(decode_output(text, target_stream=self.out_buff))
ValueError: I/O operation on closed file

real	143m31.134s
user	0m27.613s
sys	0m4.403s

But after banging on it some more, the error is here in clear sight:

$ pipenv lock
Courtesy Notice: Pipenv found itself running within a virtual environment, so it will automatically use that environment, instead of creating its own for any project. You can set PIPENV_IGNORE_VIRTUALENVS=1 to force pipenv to ignore that environment and create its own instead. You can set PIPENV_VERBOSITY=-1 to suppress this warning.
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Building requirements...
Resolving dependencies...
✘ Locking Failed!
[ResolutionFailure]:   File "/Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pipenv/resolver.py", line 785, in _main
[ResolutionFailure]:       resolve_packages(pre, clear, verbose, system, write, requirements_dir, packages)
[ResolutionFailure]:   File "/Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pipenv/resolver.py", line 746, in resolve_packages
[ResolutionFailure]:       results, resolver = resolve(
[ResolutionFailure]:   File "/Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pipenv/resolver.py", line 728, in resolve
[ResolutionFailure]:       return resolve_deps(
[ResolutionFailure]:   File "/Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pipenv/utils.py", line 1378, in resolve_deps
[ResolutionFailure]:       results, hashes, markers_lookup, resolver, skipped = actually_resolve_deps(
[ResolutionFailure]:   File "/Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pipenv/utils.py", line 1093, in actually_resolve_deps
[ResolutionFailure]:       resolver.resolve()
[ResolutionFailure]:   File "/Users/cmclaughlin-local/.pyenv/versions/3.8.1/envs/cdktf-playground/lib/python3.8/site-packages/pipenv/utils.py", line 818, in resolve
[ResolutionFailure]:       raise ResolutionFailure(message=str(e))
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
  First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
 Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
  Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: Could not find a version that matches ssm-agent (from -r /var/folders/pw/v0cjf_4967q409vfpwg0v3140000gp/T/pipenv9kaeddt2requirements/pipenv-zxr4fo1l-constraints.txt (line 3))
No versions found
Were https://pypi.org/simple or https://aws:[email protected]/pypi/xxxx/simple/ reachable?

At this point, I'd be happy to dig into the pipenv source to be absolutely certain I'm on the right track - that it's really trying to get /simple.

And of course, as the AWS docs clearly state, the endpoint simply does not exist:

$ curl https://aws:[email protected]/pypi/xxxx/simple/
Not Found

All of this might seem more like a bug report for pipenv rather than cdktf, but I really don't care about pipenv. I'm loving cdktf so far and would rather spend my time ripping pipenv out of cdktf than filing a bug report against pipenv - there are plenty examples of issues on that repo going no where.

PS While I didn't show an example of normal pip installing from Code Artifact, that does in fact work - and as I previusly mentioned I think normal pip and a basic requirements.txt in the root of any cdktf stack is simple and sufficient. Combined with a recommendation of pyenv and virtualenv, I think the community will have less problems in the long term.

@skorfmann
Copy link
Contributor

Cool, thanks for clarifying this.

PS While I didn't show an example of normal pip installing from Code Artifact, that does in fact work - and as I previusly mentioned I think normal pip and a basic requirements.txt in the root of any cdktf stack is simple and sufficient. Combined with a recommendation of pyenv and virtualenv, I think the community will have less problems in the long term.

I think a good first step would be adding an additional Python template to the cdktf-cli which works without Pipenv, perhaps something like python-pip. What do you think?

@cmclaughlin
Copy link
Contributor Author

Sounds good! I'll work on that.

@cmclaughlin cmclaughlin changed the title Remove pipenv dependency New Python template for pip without pipenv Aug 22, 2020
@skorfmann
Copy link
Contributor

This was addressed by #327

@github-actions
Copy link
Contributor

github-actions bot commented Dec 7, 2022

I'm going to lock this issue because it has been closed for 30 days. This helps our maintainers find and focus on the active issues. If you've found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request language/python
Projects
None yet
Development

No branches or pull requests

4 participants