-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Add --extra-index-url
from all extra indexes
#1980
Conversation
4714b50
to
53fafef
Compare
205edcf
to
7cc1d08
Compare
b3512ed
to
2315eab
Compare
@uranusjr @jtratner @ncoghlan @frostming would appreciate if at least one of you can look this over before it gets merged so I can go ahead and cut a bugfix release |
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
- Handle extra-index-urls when resolving - Handle extra-index-url when using `--skip-lock` - Parse index arguments when installing individual packages - Translate index aliases to urls - Always include extra indexes when installing a packages - `get_source()` falls back to `parsed_pipfile['source']` for sources when not present in the lockfile (#1994) - Include index and extra-index-url arguments in `pipenv lock -r` output - Fixes #1973, #1974, #1852, #1977, #1994 Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
2e403e3
to
81a2367
Compare
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.
Made some comments. The most problematic to me is test_install_named_index_alias
. My other comments are mostly petty.
pipenv/project.py
Outdated
elif url: | ||
if source.get('url') in url: | ||
return source | ||
source = [s for s in sources if s.get('url') in url] |
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 know this was the case before, but is it a good idea to use in
here, or should we use startswith
instead?
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.
probably, it seemed odd when I was reimplementing it but I kind of copied what was there... I can't really imagine why we'd use in
vs startswith
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.
git blame
shows @kennethreitz and it dates all the way back to the original implementation (v2.8.7!). Maybe no particular reason, just to hammer out something working first.
pipenv/project.py
Outdated
return source | ||
source = [s for s in sources if s.get('url') in url] | ||
if source: | ||
return source[0] |
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.
Isn’t this essentially what first
does? I don’t dislike this (I never liked the first
library, in fact), but maybe we should be consistent here.
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.
if it's imported I'll swap it over, in the spirit of speeding up startup time (which primarily was coming from indirect loading of the project module) I was trying to avoid extra imports
""".format(os.environ.get('PIPENV_TEST_INDEX')).strip() | ||
f.write(contents) | ||
c = p.pipenv('install pytz --index pypi') | ||
assert c.return_code == 0 |
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.
A few problems:
- Comment seems wrong. A lot of tests below have the wrong comment, it seems? None of them are using a Git repo afaict.
- This is not future-proof. If we add pytz to the mock PyPI (we might) this cannot detect an incorrect
--index
implementation. - Probably don’t want to use
dict.get
. IfPIPENV_TEST_INDEX
is not set this needs to fail loudly.
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.
oh yeah I think I've been copy pasting a bunch, I can do some comment cleanup
- I agree about the package, we can use something that's only available on the test index like the one I am using in the other test
Forgot to mention in the review— |
Signed-off-by: Dan Ryan <dan@danryan.co>
@@ -1367,6 +1367,7 @@ def pip_install( | |||
pre=False, | |||
selective_upgrade=False, | |||
requirements_dir=None, | |||
extra_indexes=None, |
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.
wdyt about, rather than making this type polymorphic, enforcing that extra_indexes
must always be a list and when calling this function on line 841, ensuring that it's always a list (or having split_extra_index always return a list of elements)
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 that makes sense but I want to stay out of the weeds on that logic until I get this bugfix released, so lets plan for 11.11.0
extra_indexes = [extra_indexes,] | ||
for idx in extra_indexes: | ||
try: | ||
extra_src = project.find_source(idx).get('url') |
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.
what exactly is going on here? how would you hit this case?
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.
If you have multiple indexes in your pipfile but you don't specify anything special when you run pipenv install
, this makes sure we use all of the indexes you specify as extra index urls
tests/integration/test_project.py
Outdated
source = [s for s in project.pipfile_sources if s.get('name') == name] | ||
assert source[0]['name'] == name | ||
assert source[0]['url'] == url | ||
source = project.get_source(name=name) |
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.
why can't you just do one big equality check here?
source = [s for s in project.pipfile_sources if s.get('name') == name]
assert source
source = source[0]
assert source['name'] == name
assert source['url'] == url
assert source == project.get_source(name=name)
assert source == project.get_source(url=url)
assert source == project.find_source(name)
assert source == project.find_source(url)
additionally where are there get and find methods that do the same thing?
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.
so the pipfile_sources
property hits the pipfile directly, exclusively. The get_source
method (which I didn't write and wasn't sure about) appears to consult the lockfile, and when I happened upon it it only consulted the lockfile. find_source
is a helper method to deal with #1852 so it simply saves reimplementing the same calls/checks a bunch in order to figure out if we have a named source
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.
However yes this can probably be done the way you described
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.
turns out equality checks don't work but I did fix this
tests/integration/test_project.py
Outdated
|
||
@pytest.mark.project | ||
@pytest.mark.sources | ||
def test_get_cached_source(PipenvInstance, pypi): |
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.
what do you think about combining these two tests) which look nearly the same except for lock step into one test that looks like:
@pytest.mark.parameterized('lock_first', [True, False])
def test_get_source(PipenvInstnace, pypi, lock_first):
with PipenvInstance(...)
with open(p.pi...):
...
if lock_first:
# force source to be cached
c = p.pipenv('lock')
assert c.return_code == 0
that way it's clearer how these two checks differ
tests/integration/test_lock.py
Outdated
# dependency anyway. | ||
with PipenvInstance() as p: | ||
with open(p.pipfile_path, 'w') as f: | ||
contents = """ |
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.
since these two are the same, how do you feel about using a constant and/or a fixture:
@pytest.mark.install # private indexes need to be uncached for resolution
@pytest.fixture
def PrivateIndexPipenvInstance(PipenvInstance):
# This uses the real PyPI since we need Internet to access the Git
# dependency anyway.
with PipenvInstance() as p:
with open(p.pipfile_path, 'w') as f:
f.write(contents)
yield p
that way you don't have to repeat the @pytest.mark.install
as much and you can slim down the test to make it easier to read.
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.
def test_private_index_skip_lock(PrivateIndexPipenvInstance):
p = PrivateIndexPipenvInstance
c = p.pipenv('install --skip-lock')
assert p.pipenv('install --skip-lock')
or if you want to keep the convention that you call PipenvInstances in a with statement, can do:
def PrivatePipenvIndexInstance(PipenvInstance):
@contextlib.contextmanager
def inner():
with PipenvInstance() as p:
# write stuff
yield p
return inner
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 that great with pytest so I don't want to hold the release up while I tinker with this but I hear the comments and agree broadly speaking that we can afford to clean this up some more
f747090
to
fe3a3fe
Compare
- Interpolate environment vars into pipfile sources - Use first to more efficiently handle list comprehensions Signed-off-by: Dan Ryan <dan@danryan.co>
fe3a3fe
to
c2462e3
Compare
Signed-off-by: Dan Ryan <dan@danryan.co>
bb612ab
to
45d6355
Compare
Ok mostly changed stuff, didn't rewrite all of the testing w/ the fixtures and refactor points per @jtratner but did refactor them a bit to be more concise & got them passing again |
Signed-off-by: Dan Ryan <dan@danryan.co>
45d6355
to
31a4a75
Compare
Signed-off-by: Dan Ryan <dan@danryan.co>
Handle indexes, extra indexes, uncached sources
--skip-lock
get_source()
falls back toparsed_pipfile['source']
for sources whennot present in the lockfile (SourceNotFound for internal source on 11.10.0 #1994)
pipenv lock -r
outputpipenv install --index myindex mypackage
#1852, pipenv sync unexpected behavior when Pipfile missing #1977, SourceNotFound for internal source on 11.10.0 #1994Signed-off-by: Dan Ryan dan@danryan.co