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

5677: Respect variable precedence in session #5735

Open
wants to merge 2 commits into
base: v2.27.x
Choose a base branch
from

Conversation

mateusduboli
Copy link
Contributor

  • Move Session#merge_environment_variables from Session#request to Session#send to make it consistent
  • On Session#send change variable precedence to (higher precedence first) kwargs -> session args -> environment.

hooks = request.hooks

# Merge with environment variables
settings = self.merge_environment_settings(request.url, proxies, stream, cert)
kwargs.update(settings)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Personally I don't like to reuse kwargs too much, but it reduce the amount of changes

@mateusduboli mateusduboli changed the title #5677: Respect variable precedence in session 5677: Respect variable precedence in session Jan 28, 2021
@junqfisica
Copy link

I propose the following change at line:

proxies = proxies or {}

Replace it by:

proxies = proxies or self.proxies

This change will make this hierarchy kwargs -> session args -> environment to be respected with no need to change anywhere else. Solving problems also with pip as discussed here

@mateusduboli
Copy link
Contributor Author

mateusduboli commented Mar 8, 2021

I've added a test case, and changed the strategy.

Now we are merging the session and request settings before we ever look into the environment, that way the precedence becomes more explicit.

Can you test this patch with pypa/pip#9691 @junqfisica ?

@junqfisica
Copy link

@mateusduboli Yes, your commit 57ddecd, also fixes the problem with pypa/pip#9691. :)

@CrazyBoyFeng
Copy link

CrazyBoyFeng commented Mar 8, 2021

proxies = proxies or self.proxies

in fact, the solutions of you two are similar: merging func args with session.self first, then with env.
and mateusduboli does more work: move all merging (not only proxies) to merge_environment_settings(), adjust the code sequence after merging so that kwargs will not be overwritten.

Copy link

@CrazyBoyFeng CrazyBoyFeng left a comment

Choose a reason for hiding this comment

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

Sorry, my test result is that no_proxy is still valid. There is no problem with your modification.

So why rebuild_proxies() is here before?

kwargs.setdefault('stream', self.stream)
kwargs.setdefault('verify', self.verify)
kwargs.setdefault('cert', self.cert)
kwargs.setdefault('proxies', self.rebuild_proxies(request, self.proxies))

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before #5681, the send method was not using the environment variables at all, this was here to ensure that those would be read at some point.

However, this MR also moves the call for merge_environment_settings to send, thus rebuilding proxies is not necessary. Before, it was only issued in the request method.

@mateusduboli
Copy link
Contributor Author

@CrazyBoyFeng Do we need any additional review on this, so it can be merged?

@CrazyBoyFeng
Copy link

Do we need any additional review on this, so it can be merged?

I used this fix with pip, and it works fine with the --proxy parameter.
I think it can be merged.

@mateusduboli
Copy link
Contributor Author

@sigmavirus24, can you take a look at these changes?

@tscheburaschka
Copy link

@nateprewitt, can you maybe take a look at this PR before the next release? We would really appreciate this bugfix included in the next available version of requests. Thank you.

Copy link

@NullPointerMaker NullPointerMaker left a comment

Choose a reason for hiding this comment

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

Hope this fix can be confirmed as soon as possible. It makes a lot of software does not work with custom proxy while the system proxy is set, including pip.

In addition, it is recommended that type "fix #5677" in the PR description to associate this PR with the issue.

Copy link

@junqfisica junqfisica left a comment

Choose a reason for hiding this comment

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

These changes will make the hierarchy request kwargs -> Session args -> environment to be respected. This also solves problems with pip as discussed here

@mateusduboli
Copy link
Contributor Author

@nateprewitt thanks for taking a look at this!

I'm wondering why this is a tagged as a Breaking API Change, I can understand that it should not go through a patch revision, but it does keeps the API as intended on the docs.

I'm guessing if we not consider it as such it would be less hassle to merge it, could you clarify it better?

@CrazyBoyFeng
Copy link

This should be considered as a bug, I think.
When there are both environment variables and argument of requests.session about the proxy, requests eventually takes the system environment variable. This is not the usual practice.
If this is not considered as a bug, then it needs to be answered: how to use session with a custom proxy argument when the environment variable http_proxy or https_proxy exists?

@nateprewitt
Copy link
Member

nateprewitt commented Oct 9, 2021

Hi @mateusduboli, the reason we have this marked as a breaking change is we're doing a pretty fundamental change to the Session API here. The last PR (#5888) that was introduced for this had some non-trivial impact that's made Requests 2.26.0 unusable for a number of our dependents. It arguably shouldn't have been merged to begin with.

I know we've discussed the session precedence issue more than once previously, but I wasn't able to find actual issue numbers. send and request are not intended to function identically and trying to accomplish that breaks a few different workflows. send is intended to do almost nothing to the request and send the PreparedRequest exactly as it was created. This has drifted over the years, so it's no longer entirely true, but this change will make the situation worse.

I think we need to reevaluate how these interfaces actually operate going into a new major version. Until then though, this has been the behavior of send for 7+ years, and there's a lot of infrastructure that will stop behaving correctly because of this.

@nateprewitt
Copy link
Member

nateprewitt commented Oct 9, 2021

If this is not considered as a bug, then it needs to be answered: how to use session with a custom proxy argument when the environment variable http_proxy or https_proxy exists?

@CrazyBoyFeng I'm reading over the pip issue more and while I agree this far from optimal, as I've stated above, it's kind of where we are. We would like to fix this but can't currently.

For the interim, I'm failing to see why pip cannot handle this the same way they do timeout. Requests 2.x was specifically designed to ignore Session.timeout because the maintainers at the time didn't agree with it being a session level property. To get around this, Pip created its own timeout attribute and sets it on each request before calling into Requests. The same thing can be done with proxies. This doesn't require a patch or change to the vendored code, and produces the desired outcome.

e.g.

https://github.com/pypa/pip/blob/3ab760aaa17fdc7f00c468a529241164b070b353/src/pip/_internal/network/session.py#L443-L449

Would become:

def request(self, method, url, *args, **kwargs):
    # type: (str, str, *Any, **Any) -> Response
    # Allow setting a default timeout on a session
    kwargs.setdefault("timeout", self.timeout)
+   if self.proxies:
+       kwargs.setdefault("proxies", self.proxies)

    # Dispatch the actual request
    return super().request(method, url, *args, **kwargs)

junqfisica added a commit to junqfisica/requests that referenced this pull request Nov 23, 2021
This change will make the hierarchy request **kwargs -> Session args -> environment to be respected. This also solves problems with pip as discussed [here](pypa/pip#9691 (comment))  and  psf#5735
@junqfisica junqfisica mentioned this pull request Nov 23, 2021
junqfisica added a commit to junqfisica/pip that referenced this pull request Nov 24, 2021
After waiting a long time for a fix on the side of the request that could fix pip install issues with proxy as already discussed in pypa#9691. It seems that such changes as mentioned in psf/requests#5735 will take a while to happen, probably only on version 3 of the request. 

Therefore, I'm suggesting a change on the pip side as already proposed in [issuecomment-79051687]pypa#9568 (comment) and [issuecomment-939373868]psf/requests#5735 (comment) 

I think it's important that pip address this issue asap since the newer versions of pip are not working properly behind a proxy.
@nateprewitt nateprewitt changed the base branch from master to v2.27.x January 3, 2022 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants