-
Notifications
You must be signed in to change notification settings - Fork 308
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
Allow defining empty username and password in .pypirc #426
Conversation
In the case of a private repository (Nexus in my case) without any authentication, I haven't found a way not to have a prompt asking for username and password. This PR allows to have the following configuration: ```ini username: password: ``` Note that I haven't tested for side effects.
Codecov Report
@@ Coverage Diff @@
## master #426 +/- ##
=======================================
Coverage 78.29% 78.29%
=======================================
Files 14 14
Lines 751 751
Branches 108 108
=======================================
Hits 588 588
Misses 130 130
Partials 33 33
Continue to review full report at Codecov.
|
This change breaks twine for me. I have no
|
Before this change, twine would resolve my username from the TWINE_USERNAME environment variable. Now I suspect it's being loaded as |
Should I open a new ticket on this issue? |
Yes, please. It's disappointing that our CI didn't catch this |
@marob Thinking about the code prior to this change, if you had put |
I'm not for using a special value to indicate an absence of value. I don't understand how the changes introduced in this PR can have the side effect of not taking env vars into account. On my understanding, the ArgumentParser parses arguments on the command line and defaults to env var if the argument is not present. |
@@ -57,7 +57,7 @@ | |||
def get_config(path="~/.pypirc"): | |||
# even if the config file does not exist, set up the parser | |||
# variable to reduce the number of if/else statements | |||
parser = configparser.RawConfigParser() | |||
parser = configparser.RawConfigParser(allow_no_value=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.
Today I learned that allow_no_value=True
allows for:
[pypi]
username
password
But with allow_no_value=False
, username=
and password=
are still valid and still result in empty strings.
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.
With allow_no_value=False
, if the config file is of the form:
[pypi]
username
password
the username
and password
key won't be available in the parsed config.
Or am I mistaking?
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 that case, the parser will raise an Exception, but naked username
or password
was not the prescribed syntax; rather username:
(which I assume is equivalent to username=
) was.
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.
Well, now I remember why I had to add allow_no_value=True
in order to allow empty value.
What's the difference between adding :
(or =
), and using naked keys?
Is it parsed differently?
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.
Yes. Adding the separator causes the value to be parsed as the empty string. Not including the separator creates a ParseException unless allow_no_value=True
in which case the value is 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.
OK. The intent of my PR was to be able to provide a None
value in the configuration file in order to be anonymous.
Without this PR, you wouldn't be able to provide such value, so the CLI would systematically ask for a login/password (which I didn't want).
You're right, and I've learned more in #450. |
@@ -195,7 +195,7 @@ def get_userpass_value(cli_value, config, key, prompt_strategy=None): | |||
""" | |||
if cli_value is not None: | |||
return cli_value | |||
elif config.get(key): | |||
elif key in config: |
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.
Given that config always defaults with {'username': None, 'password': None}
, I now believe this change unconditionally disables prompts.
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 don't add username
nor password
keys in your configuration file, the keys won't be available in the parsed config object, so it should continue to the prompt_strategy part.
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.
That's where you're mistaken. Keys are set unconditionally to default to 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.
What if I don't have a server-login
section (which is my case):
[distutils]
index-servers =
internal
[internal]
repository: ******
username
password
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.
The defaults still get copied into every repository.
I'll take that as a yes. And I agree, using |
…allowed, as added in #426. Note that the tests pass even without 'allow_no_value'.
It was a no. |
Does that mean your private PyPI server is rejecting |
I don't know if it accepts The goal is to provide no username nor password (no authentication) at all. |
…e config should bypass the prompt. Ref #426.
I would not expect you to have to create a special user. My suspicion was that your server was not requiring authentication at all, so was ignoring the empty authentication that was being passed. In 3c0ad12, I've added another test, a test capturing the intention that you're intending to express in this PR, prior to the PR, which should fail first and pass after merging with this commit. |
I've confirmed that requests does not suppress double-blanks for auth:
|
The use case is not to provide empty string values for the username and password (which will indeed generate a |
@marob: Can you confirm then that with Regardless of that outcome, I tend to agree - one shouldn't have to supply special values, even empty ones, to avoid prompts. Unfortunately, due to the current behavior and expectations, the |
* Add test capturing expectation that an empty username or password is allowed, as added in #426. Note that the tests pass even without 'allow_no_value'. * Add test capturing expectation that the password prompt occurs if no password was indicated. Ref #426 #450. * Add test capturing new expectation that an empty password found in the config should bypass the prompt. Ref #426. * Remove 'allow_no_value' on config parser. It was unneeded and adds ambiguity. Ref #426. * Allow empty strings in config to satisfy username and password values, suppressing prompts and keyring resolution. Ref #426. Fixes #450.
It does work with 95ecde2 and the following configuration:
|
That's great news. We'll acknowledge that it's a hack - that a better design might be had, but at least there's a suitable workaround in the meantime. Thanks @marob for the extra effort in making this product better. |
In the case of a private repository (Nexus in my case) without any authentication, I haven't found a way not to have a prompt asking for username and password.
This PR allows to have the following configuration:
Note that I haven't tested for side effects.