Skip to content

Fix: Respect no_proxy in proxies dictionary and NO_PROXY env var - #7068

Open
cjac wants to merge 3 commits into
psf:mainfrom
LLC-Technologies-Collier:fix-no-proxy-2025-10-24
Open

cjac wants to merge 3 commits into
psf:mainfrom
LLC-Technologies-Collier:fix-no-proxy-2025-10-24

Conversation

@cjac

@cjac cjac commented Oct 24, 2025

Copy link
Copy Markdown

This PR addresses issue #5000 by ensuring that proxy bypass directives are respected, whether provided directly within the proxies dictionary passed to request functions or set via environment variables.

Previously, bypass rules in the proxies dictionary were not fully honored, and the NO_PROXY environment variable was not always checked when a proxies dictionary was provided.

This change includes:

  1. src/requests/sessions.py:

    • Modified Session.send to check both no_proxy and no keys in the proxies dictionary. If the request URL matches any pattern in the list, proxies are cleared for that request.
    • Updated merge_environment_settings to check both no_proxy and no keys when merging environment proxies.
    • Updated Session.request docstring to clarify no and no_proxy key support.
  2. src/requests/utils.py:

    • Updated select_proxy to evaluate bypass rules before selecting a proxy.
    • Refined select_proxy to respect standard precedence for environment variables (preferring lowercase no_proxy over NO_PROXY).
    • Updated resolve_proxies to check both no_proxy and no keys.
  3. src/requests/api.py:

    • Updated requests.request docstring to clarify no and no_proxy key support in the proxies dictionary.
  4. tests/test_requests.py:

    • Added new test cases (test_no_proxy_in_proxies_dict, test_no_proxy_star_in_proxies_dict, test_no_proxy_not_matching_in_proxies_dict) to verify that bypass rules within the proxies dictionary work as expected.
  5. tests/test_utils.py:

    • Added new test cases (test_select_proxy_with_no_proxy) to ensure proxy bypass rules and environment variables are correctly handled by select_proxy.

These changes ensure consistent behavior for proxy bypass logic, regardless of how the proxy settings are configured.

Closes #5000

@cjac
cjac force-pushed the fix-no-proxy-2025-10-24 branch from ed6f3a0 to a784de5 Compare October 24, 2025 20:58
@cjac
cjac marked this pull request as ready for review October 24, 2025 20:59

@hajo-m hajo-m left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Regarding #5000 (comment)

Comment thread src/requests/sessions.py Outdated
Comment thread src/requests/utils.py Outdated
@Mukller

Mukller commented Sep 18, 2026

Copy link
Copy Markdown

The
o_proxy handling in send() and select_proxy() looks correct. However, est_rewind_body_no_seek (line ~2004 in test_requests.py) has its body replaced with pass, which breaks the original test. This needs to be restored before merge.

Also, select_proxy now returns None when NO_PROXY matches — callers of select_proxy should be checked to ensure they handle None gracefully (currently merge_environment_settings and send both use the return value as a dict key or proxy URL).

Fix the broken test and this should be good.

@cjac

cjac commented Sep 19, 2026

Copy link
Copy Markdown
Author

Thank you for the review. I have addressed the issues raised:

  • Missing test_rewind_body_no_seek: This test has been restored to its original implementation with BadFileObj and the UnrewindableBodyError assertion. The new tests have been moved out of this function.

  • Handling of None from select_proxy: Callers in HTTPAdapter have been checked. They use truthiness evaluations (if proxy:) and treat None safely as bypassing the proxy setup, proceeding to standard connection Pool Manager invocation.

  • Dictionary Key and Environment Precedence: Addressed concerns regarding key naming ('no' vs 'no_proxy') by checking both in the proxies dictionary. Refined select_proxy to explicitly respect both no_proxy and NO_PROXY environment variables, prioritizing the lowercase version to maintain consistency with urllib and other standard HTTP clients.

@cjac
cjac requested a review from hajo-m September 19, 2026 18:11

@cjac cjac left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

now possible to accurately specify using environment variables which hosts should skip proxy and go direct

This commit addresses issue psf#5000 by ensuring that the `no_proxy` directive is respected, whether it's provided directly within the `proxies` dictionary passed to request functions or set as the `NO_PROXY` environment variable.

Previously, `no_proxy` in the `proxies` dictionary was not fully honored, and the `NO_PROXY` environment variable was not always checked when a `proxies` dictionary was provided.

This change includes:

1.  **`src/requests/sessions.py`**: Modified the `Session.send` method to check the `no_proxy` key within the `kwargs['proxies']` dictionary. If the request URL matches any pattern in the `no_proxy` list, the proxies are cleared for that request.
2.  **`src/requests/utils.py`**: Updated the `select_proxy` function to check the `NO_PROXY` environment variable using `should_bypass_proxies` before selecting a proxy from the provided `proxies` dictionary.
3.  **`tests/test_requests.py`**: Added new test cases (`test_no_proxy_in_proxies_dict`, `test_no_proxy_star_in_proxies_dict`, `test_no_proxy_not_matching_in_proxies_dict`) to verify that `no_proxy` within the `proxies` dictionary works as expected, using mocks to check if the proxy is bypassed.
4.  **`tests/test_utils.py`**: Added new test cases (`test_select_proxy_with_no_proxy`) to ensure the `NO_PROXY` environment variable is correctly handled by `select_proxy`.

These changes ensure consistent behavior for proxy bypass logic, regardless of how the proxy settings are configured.

Closes psf#5000
…x test arrangement

- Support both `no_proxy` and `no` keys in the `proxies` dictionary for bypass rules in `Session.send`, `merge_environment_settings`, and `resolve_proxies`, ensuring compatibility with `urllib` expectations.
- Update `select_proxy` to check bypass rules before selecting a proxy.
- Ensure `select_proxy` respects standard precedence for environment variables (preferring lowercase `no_proxy` over `NO_PROXY`).
- Clear proxies in `Session.send` if bypass rules are met for the requested URL.
- Restore `test_rewind_body_no_seek` to its original implementation with `BadFileObj` and `UnrewindableBodyError` assertion.
- Move new proxy bypass tests (`test_no_proxy_in_proxies_dict`, etc.) to be standalone tests rather than nested inside `test_rewind_body_no_seek`.
- Update docstrings for `requests.request` and `Session.request` to mention that the `proxies` dictionary can include a `'no'` or `'no_proxy'` key to specify URLs that should bypass proxy settings.
@cjac
cjac force-pushed the fix-no-proxy-2025-10-24 branch from 7524091 to 508449a Compare September 19, 2026 19:56
@cjac

cjac commented Sep 19, 2026

Copy link
Copy Markdown
Author

rebased onto orgin's main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

no_proxy setting ignores the proxies dictionary

3 participants