Skip to content

Use NETRC environment variable #135788

Open
Open

Description

@berthin

Feature or enhancement

Proposal:

Hi,

I'd like to add support to the NETRC environment variable as documented in GNU inetuils v2.6 (https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html). Other tools and libraries are already supporting that envvar and I think it would be nice to aligned as well in that regard.

Supporting the envvar should be as simple as changing:

file = os.path.join(os.path.expanduser("~"), ".netrc")

with

file = os.environ.get("NETRC", None) or os.path.join(os.path.expanduser("~"), ".netrc")

Best regards,
Berthin

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Jun 21, 2025
  2. picnixz commented on Jun 21, 2025

    @picnixz
    Member

    FTR, it's supported in (pip) pypa/pip#11023 and requests (psf/requests#5643) as well as httpx (https://www.python-httpx.org/advanced/authentication/#netrc-authentication).

    I think it's a legitimate addition, though any PR doing it needs tests & docs.

  3. berthin commented on Jun 21, 2025

    @berthin
    Author

    FTR, it's supported in (pip) pypa/pip#11023 and requests (psf/requests#5643) as well as httpx (https://www.python-httpx.org/advanced/authentication/#netrc-authentication).

    I think it's a legitimate addition, though any PR doing it needs tests & docs.

    Cool, I can work on this.

  4. picnixz commented on Jun 21, 2025

    @picnixz
    Member

    Sure! but please read https://devguide.python.org/getting-started/pull-request-lifecycle/ first so to avoid surprises! TiA

  5. cmaloney commented on Jun 22, 2025

    @cmaloney
    Contributor

    I don't think getting the path from an environment variable by default in CPython netrc is good from a security perspective as netrc underlies multiple http libraries which explicitly implement a trust_env[0] option to disable getting configuration from environment variables. They generally do this in their code, then pass a path to netrc from my reading, and CPython changing under the hood to read an env var potentially could bypass that protection. An opt-in implementation I think would allow their security design and be good to add to CPython.

    I do think it's useful to have environment variable support, and it would be nice to reduce the boiler plate that seems to be getting added to the multiple http client libraries, but doing so I think needs to be opt-in (ex. allow_env=True parameter, a new entrypoint, or some other bike shed).

    [0] Ones I looked at:

  6. picnixz commented on Jun 22, 2025

    @picnixz
    Member

    I don't think getting the path from an environment variable by default in CPython netrc is good from a security perspective as netrc underlies multiple http libraries which explicitly implement a trust_env

    Hum, in this case I think we shouldn't do it by default as well on our side. I'm ok with with using a boolean or an alternative constructor.

  7. berthin commented on Jun 23, 2025

    @berthin
    Author

    I don't think getting the path from an environment variable by default in CPython netrc is good from a security perspective as netrc underlies multiple http libraries which explicitly implement a trust_env

    Hum, in this case I think we shouldn't do it by default as well on our side. I'm ok with with using a boolean or an alternative constructor.

    Interesting point. I don't mind adding that. But before, what do you think about the following:

    a) The documentation must clearly state what the scope oftrust_env will be. It might be a bit confusing for instance to set trust_env=False and then expect os.expanduser to work, because that can rely in the HOME envvar (https://github.com/python/cpython/blob/main/Lib/posixpath.py#L244).
    b) The difference between netrc.trust_env=... and netrc.netrc(trust_env=...) is the scope. The former is module level, while the later is function level. I personally think that function level is safer between the two.

  8. cmaloney commented on Jun 24, 2025

    @cmaloney
    Contributor

    a) Definitely needs clear/concise documentation (want to avoid security FUD); overall the feature (NETRC env var support in CPython netrc) should make it easier for more community/libraries to add support. I have a slight preference for a new name / flag as trust_env is already defined by multiple different Python libraries with different defaults and meanings, not sure CPython adding another would make things easier to understand.
    b) I like function level for clearer config/control flow. I'm generally a fan of reducing non-constant global state.

  9. berthin commented on Jun 25, 2025

    @berthin
    Author

    a) Definitely needs clear/concise documentation (want to avoid security FUD); overall the feature (NETRC env var support in CPython netrc) should make it easier for more community/libraries to add support. I have a slight preference for a new name / flag as trust_env is already defined by multiple different Python libraries with different defaults and meanings, not sure CPython adding another would make things easier to understand. b) I like function level for clearer config/control flow. I'm generally a fan of reducing non-constant global state.

    An alternative could be to name the option as trust_netrc_env so it leaves no room for misunderstandings. However, maybe this is a bigger discussion for the library maintainers?

  10. cmaloney commented on Jun 25, 2025

    @cmaloney
    Contributor

    To me at least (not a CPython core dev), your choice if you want to do larger library maintainer reach out/coordination. Would likely mean get much more precisely what libraries want/will use but also requires a lot more time/effort. This is a new feature so I think currently heading towards Python 3.15 which means do have a bit of time to get things done (feature freeze for 3.15 is with beta1 on 2026-05-05 per PEP-790).

  11. berthin commented on Jul 4, 2025

    @berthin
    Author

    @picnixz do you think you can make a judgement call and decide if #135788 (comment) is acceptable? or would you like (me) to open(start) the discussion with other library maintainers to decide if there could be a convention to enable/disable the use of envvars.

  12. picnixz commented on Jul 4, 2025

    @picnixz
    Member

    I am travelling and will make a judgement call next week (soonest would be Friday). I'd like to be on my laptop for that. TiA

  13. berthin commented on Jul 5, 2025

    @berthin
    Author

    I am travelling and will make a judgement call next week (soonest would be Friday). I'd like to be on my laptop for that. TiA

    Sure thanks! Safe travels!

  14. berthin commented on Aug 16, 2025

    @berthin
    Author

    @picnixz, do you have time to review the discussions and give your opinion??

  15. picnixz commented on Aug 16, 2025

    @picnixz
    Member

    Hum I forgot and I am not available before next week. Let me assign myself this issue

  16. self-assigned this
    on Aug 16, 2025
  17. picnixz commented on Aug 20, 2025

    @picnixz
    Member

    My 2c (with me being sick so this is still a draft of my opinion):

    a) when using the NETRC env. var, we should just take the path that is given as is, namely pass it as is to open(). That's what already happens when we specify file=.... I think using NETRC should be equivalent to explicitly pass file=....

    b) let's avoid module's level configuration, it's usually a pain to maintain, changes when reloading, etc. netrc.netrc(..., trust_env=True) would be cleaner and sufficient.

    I can suggest two approaches:

    • classmethod-based named load which does the expansion. Later, we can add more options from where a netrc file could be loaded for instance (e.g., netrc.load(paths=[...]) or netrc.load(ignore=...) to prevent loading from some files.
    • I would have used trust_env because I don't think it conflicts with something else. requests uses trust_env to indicate that we can/cannot use netrc, but the others use trust_env to indicate whether environment variables are to be trusted in the given context. I'm ok with keeping trust_env because trust_netrc_env seems too verbose.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions