Skip to content

5677: Respect variable precedence in session#5735

Closed
mateusduboli wants to merge 2 commits into
psf:v2.27.xfrom
mateusduboli:5677
Closed

5677: Respect variable precedence in session#5735
mateusduboli wants to merge 2 commits into
psf:v2.27.xfrom
mateusduboli:5677

Conversation

@mateusduboli
Copy link
Copy Markdown
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.

Comment thread requests/sessions.py

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

@mateusduboli mateusduboli Jan 28, 2021

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
Copy Markdown

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
Copy Markdown
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
Copy Markdown

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

@CrazyBoyFeng
Copy link
Copy Markdown

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
Copy Markdown

@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?

Comment thread requests/sessions.py Outdated
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
Copy Markdown
Contributor Author

@mateusduboli mateusduboli Mar 8, 2021

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
Copy Markdown
Contributor Author

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

@CrazyBoyFeng
Copy link
Copy Markdown

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
Copy Markdown
Contributor Author

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

@tscheburaschka
Copy link
Copy Markdown

@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
Copy Markdown

@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
Copy Markdown

@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
Copy Markdown
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
Copy Markdown

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
Copy Markdown
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
Copy Markdown
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
@nateprewitt nateprewitt deleted the branch psf:v2.27.x March 30, 2026 04:18
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.

6 participants