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

Fix/5147 #5170

Closed
wants to merge 8 commits into from
Closed

Fix/5147 #5170

wants to merge 8 commits into from

Conversation

venthur
Copy link
Contributor

@venthur venthur commented Apr 5, 2018

Suppress the output of the stack trace when pip install is called with an invalid requirement.

@pradyunsg pradyunsg added the type: enhancement Improvements to functionality label Apr 5, 2018
@pradyunsg pradyunsg modified the milestones: 10.0, 10.1 Apr 5, 2018
@pradyunsg
Copy link
Member

Hey @venthur! Thanks for this PR!

We're currently in the beta period for pip 10.0, which means we won't be merging any new features or enhancements until pip 10.0.0 is released.

Sorry to keep you waiting but I hope you'd understand. :)

@@ -257,7 +257,7 @@ def from_line(
elif '=' in req and not any(op in req for op in operators):
add_msg = "= is not a valid operator. Did you mean == ?"
else:
add_msg = traceback.format_exc()
add_msg = ''
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned in #5147 (comment), it's probably not right to print the traceback or nothing here.

Could you look into extracting any useful info from the exception raised?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @pradyunsg thanks for the review!

Well, we have

pip._vendor.pyparsing.ParseException: Expected W:(abcd...) (at char 0), (line:1, col:1)

at the end of the first stack trace and

pip._vendor.packaging.requirements.InvalidRequirement: Invalid requirement, parse error at "'-'"

at the end of the second one.

And of course the error message

Invalid requirement: '-'

I think for a user facing error message the Invalid requirement: '-' should be explanation enough for a user to fix the problem. The extra info about the actual problem -- the parser error -- does not really add value don't you think?

Looking at the issue it seems that @gvanrossum and @pfmoore had a similar fix in mind.

Copy link
Contributor Author

@venthur venthur Apr 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick clarification: the Error message Invalid requirement: '$FOO' message will still be shown with this patch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @pradyunsg. I think it would be better to display something about why / what caused the requirement to be invalid as opposed to swallowing the details completely and just saying it's "invalid." For now this could be done simply by displaying the exception type and message for what caused it. For the case that was originally provided, this could look something like--

Invalid requirement: '-'
Details: ParseException: Expected W:(abcd...) (at char 0), (line:1, col:1)

Over time, these inner causes could be made more user-friendly as they come up. For example, in this case it might be something like, "First character must be one of ...." (or whatever the condition is).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very well, I've updated the PR and it prints out now:

$ pip install "toto 42"
Invalid requirement: 'toto 42'
Expected stringEnd (at char 5), (line:1, col:6)

and

$ pip install -
Invalid requirement: '-'
Expected W:(abcd...) (at char 0), (line:1, col:1)

I'm not sure if value of the extra info justifies the fragility of the implementation to get it: Python2 doesn't support the __context__ attribute yet and peeling out the message from the middle of a chained stack trace then seems not easy. So on Python2 it will simply print the Invalid requirement message without the additional hint.

$ pip install -
Invalid requirement: '-'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that you need to reach into the __context__ makes it seem like something else is wrong. The info should already be contained in the message for the InvalidRequirement exception that you are handling. If it's not, then it seems like that message should be adjusted. This would also address the issue for Python 2 because then you'll no longer need to access __context__ which isn't available. It will be available at the immediate exception being handled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cjerdonek Ok, that'll make things a lot easier, I wasn't sure if I'm allowed to modify stuff in src/pip/_vendor/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just investigated, too. It looks like an issue would need to be filed with the packaging project to make that error message more informative. It's packaging that would need to provide a more detailed explanation since it's currently not providing that info:

raise InvalidRequirement(

So I guess @pradyunsg's option (2) is probably best here (combined with filing an issue with packaging).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS - just to be clear, you're probably not allowed to modify what's in the _vendor directory (which is why it would need to be improved in the project itself). Stuff in the vendor directory is most likely copied as is from wherever it came from.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, how about the current compromise:

$ pip install -
Invalid requirement: '-'
parse error at "'-'"

and

$ pip install 'toto 42'
Invalid requirement: 'toto 42'
parse error at "'42'"

The patch is very digestible and runs on all current Python's.

if os.path.sep in req:
add_msg = "It looks like a path."
add_msg += deduce_helpful_msg(req)
elif '=' in req and not any(op in req for op in operators):
add_msg = "= is not a valid operator. Did you mean == ?"
else:
add_msg = traceback.format_exc()
msg = str(e)
msg = msg.replace('Invalid requirement, ', '')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This replace() seems brittle and hacky to me, but I'll let others weigh in. The packaging project probably shouldn't be including this string to begin with since it's redundant with the exception class being InvalidRequirement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed I've created a PR against packaging fixing that: pypa/packaging#129

@venthur
Copy link
Contributor Author

venthur commented Jun 7, 2018

Refreshed the patch.

@pradyunsg
Copy link
Member

Let's improve the error message in packaging and then we'll modify this to just print whatever that's printing.

@pradyunsg pradyunsg added the state: blocked Can not be done until something else is done label Jun 7, 2018
@venthur
Copy link
Contributor Author

venthur commented Jun 7, 2018

@pradyunsg
Copy link
Member

@venthur Yep. I posted a comment there. :)

@pradyunsg pradyunsg modified the milestones: 18.0, 18.1 Jul 6, 2018
@pradyunsg
Copy link
Member

Pushing this down the road to the next release since I don't think this'd happen in time for 18.0.

@BrownTruck
Copy link
Contributor

Hello!

I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the master branch into this pull request or rebase this pull request against master then it will eligible for code review and hopefully merging!

@BrownTruck BrownTruck added the needs rebase or merge PR has conflicts with current master label Aug 21, 2018
@pradyunsg
Copy link
Member

Dropping this from 18.1 since I don't think this'll be ready in time (by 30th this month).

@pradyunsg pradyunsg removed this from the 18.1 milestone Sep 20, 2018
@lock
Copy link

lock bot commented May 31, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot added the auto-locked Outdated issues that have been locked by automation label May 31, 2019
@lock lock bot locked as resolved and limited conversation to collaborators May 31, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation needs rebase or merge PR has conflicts with current master state: blocked Can not be done until something else is done type: enhancement Improvements to functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants