GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — pathlib.Path objects can be used as context managers · Issue #83863 · python/cpython

pathlib.Path objects can be used as context managers #83863

New issue
Copy link
New issue
Copy link
Closed
Closed
pathlib.Path objects can be used as context managers#83863
Copy link
Labels
3.9 (EOL)end of lifeend of lifestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

barneygale
mannequin
opened on Feb 19, 2020
Issue body actions
BPO 39682
Nosy @brettcannon, @pitrou, @barneygale
PRs
  • bpo-39682: make pathlib.Path immutable by removing (undocumented) support for "closing" a path by using it as a context manager #18846
  • bpo-46556: emit DeprecationWarning from pathlib.Path.__enter__() #30971
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2020-04-01.14:11:09.381>
    created_at = <Date 2020-02-19.02:10:35.842>
    labels = ['type-bug', 'library', '3.9']
    title = 'pathlib.Path objects can be used as context managers'
    updated_at = <Date 2022-01-27.23:22:28.820>
    user = 'https://github.com/barneygale'

    bugs.python.org fields:

    activity = <Date 2022-01-27.23:22:28.820>
    actor = 'barneygale'
    assignee = 'none'
    closed = True
    closed_date = <Date 2020-04-01.14:11:09.381>
    closer = 'pitrou'
    components = ['Library (Lib)']
    creation = <Date 2020-02-19.02:10:35.842>
    creator = 'barneygale'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 39682
    keywords = ['patch']
    message_count = 14.0
    messages = ['362244', '362840', '362934', '363206', '363209', '363218', '363260', '363261', '363285', '363298', '363383', '363468', '363469', '365473']
    nosy_count = 4.0
    nosy_names = ['brett.cannon', 'pitrou', 'Isaac Muse', 'barneygale']
    pr_nums = ['18846', '30971']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue39682'
    versions = ['Python 3.9']

    Linked PRs

    • GH-83863: Drop support for using pathlib.Path objects as context managers #104807

    Activity

    Next
    1. barneygale commented on Feb 19, 2020

      @barneygale
      barneygalemannequin
      on Feb 19, 2020
      MannequinAuthor
      More actions

      pathlib.Path objects can be used as context managers, but this functionality is undocumented and makes little sense. Example:

      >>> import pathlib
      >>> root = pathlib.Path("/")
      >>> with root:
      ...     print(1)
      ... 
      1
      >>> with root:
      ...     print(2)
      ... 
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/home/barney/.pyenv/versions/3.7.3/lib/python3.7/pathlib.py", line 1028, in __enter__
          self._raise_closed()
        File "/home/barney/.pyenv/versions/3.7.3/lib/python3.7/pathlib.py", line 1035, in _raise_closed
          raise ValueError("I/O operation on closed path")
      ValueError: I/O operation on closed path

      Path objects don't acquire any resources on new/init/enter, nor do they release any resources on exit. The whole notion of the path being _closed seems to exist purely to make impure Path methods unusable after exiting from the context manager. I can't personally think of a compelling use case for this, and suggest that it be removed.

    2. barneygale
      added
      3.8 (EOL)end of lifeend of life
      stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
      on Feb 19, 2020
    3. brettcannon commented on Feb 27, 2020

      @brettcannon
      brettcannon
      on Feb 27, 2020
      Member
      More actions

      A use-case of "closing" a path is to cheaply flag that a path object is no longer valid, e.g. you deleted the underlying file and so you don't want others using the object anymore without paying the penalty of having to do the I/O to trigger the failure due to the path no longer existing.

      Now whether anyone is using this functionality I don't know, but removing it will inevitably break code for someone, so someone will need to make at least some form of an attempt to see if there's any use in the wild to justify simplifying the code by removing the functionality.

    4. anntzer commented on Feb 28, 2020

      @anntzer
      anntzermannequin
      on Feb 28, 2020
      Mannequin
      More actions

      A problem of having this bit of state in paths is that it violates assumptions based on immutability/hashability, e.g. with

          from pathlib import Path
      
          p = Path("foo")
          q = Path("foo")
      
          with p: pass
      
          unique_paths = {p, q}
      
          print(len(unique_paths))  # == 1, as p == q
          for path in unique_paths:
              print(path.resolve())  # Fails if the path is closed.

      The last line fails with unique_paths = {p, q} as p has been closed (and apparently sets keep the first element when multiple "equal" elements are passed in), but not with unique_paths = {q, p}.

      It would also prevent optimizations based on immutability as proposed in https://bugs.python.org/issue39783.

    5. brettcannon commented on Mar 2, 2020

      @brettcannon
      brettcannon
      on Mar 2, 2020
      Member
      More actions

      I guess a question is whether we want immutability guarantees (I for one didn't even know you could hash Path objects until now).

      I'm personally fine with that idea as it mentally makes sense to not need paths to be mutable. But as I said, someone needs to take at least some stab at seeing if any preexisting code out there will break if the _closed flag is removed before we can continue this discussion.

    6. anntzer commented on Mar 2, 2020

      @anntzer
      anntzermannequin
      on Mar 2, 2020
      Mannequin
      More actions

      Immutability and hashability are listed first among "general properties" of paths (https://docs.python.org/3/library/pathlib.html#general-properties), and in the PEP proposing pathlib (https://www.python.org/dev/peps/pep-0428/#immutability). Looking at it again I *guess* the docs version could be read as only guaranteeing this for PurePaths (because that's in the PurePath section) rather than Path, but the PEP version clearly implies that this is true for both PurePaths and concrete Paths.

      It may be tricky to check usage in third-party packages, given that one would need to look for with <path-object>: ... rather than, say, a method name which can be grepped. Do you have any suggestions here?

    7. pitrou commented on Mar 2, 2020

      @pitrou
      pitrou
      on Mar 2, 2020
      Member
      More actions

      As with the Accessor abstraction, the original idea was to support Path objects backed by a directory file descriptor (for use with openat() and friends). That idea was abandoned but it looks like the context manager stayed. It's certainly not useful currently.

    8. barneygale commented on Mar 3, 2020

      @barneygale
      barneygalemannequin
      on Mar 3, 2020
      MannequinAuthor
      More actions

      Can I ask what sort of backwards-compatibility guarantees Python provides for these cases? In the case of using a Path object as a context manager, I think we can say:

      • It's easy to do - there's no need to call any underscore-prefixed methods for example
      • It's undocumented
      • It's pretty hard to determine existing usage statically - grepping for `with p:` is years of work.
    9. barneygale commented on Mar 3, 2020

      @barneygale
      barneygalemannequin
      on Mar 3, 2020
      MannequinAuthor
      More actions

      Also, thank you Antoine for your explanation :-)

    10. brettcannon commented on Mar 3, 2020

      @brettcannon
      brettcannon
      on Mar 3, 2020
      Member
      More actions

      Can I ask what sort of backwards-compatibility guarantees Python provides for these cases?

      A deprecation warning for two releases (i.e. two years). Then it can be removed. So if people want to move forward with removing this then a DeprecationWarning would need to be raised in all places where _closed is set with a message stating the functionality is deprecated in 3.9 and slated for removal in 3.11 (along with appropriate doc updates, both for the module and What's New).

    11. pitrou commented on Mar 3, 2020

      @pitrou
      pitrou
      on Mar 3, 2020
      Member
      More actions

      Note you could simply remove the "closed" flag and the context manager live. That way, you don't have to deprecate anything.

    12. brettcannon commented on Mar 4, 2020

      @brettcannon
      brettcannon
      on Mar 4, 2020
      Member
      More actions

      @antoine I just quite follow what you mean. Are you saying ditch _closed and just leave the context manager to be a no-op?

    13. 6 remaining items

    14. pitrou
      added
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      3.9 (EOL)end of lifeend of life
      and removed
      3.8 (EOL)end of lifeend of life
      on Apr 1, 2020
    15. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    16. skshetry
      added 2 commits that reference this issue on Oct 15, 2022

      remove pathlib.Path use as a contextmanager

      3f0b2a9

      remove pathlib.Path use as a contextmanager

      d4450c7
    17. pixelb
      added a commit that references this issue on Oct 17, 2022

      remove pathlib.Path use as a contextmanager

      5300a86
    18. barneygale
      added 2 commits that reference this issue on May 23, 2023

      pythonGH-83863: Drop support for using `pathlib.Path` objects as cont…

      04d568a

      GH-83863: Drop support for using `pathlib.Path` objects as context ma…

      6b1510c
    19. andrewshadura commented on Oct 12, 2023

      @andrewshadura
      andrewshadura
      on Oct 12, 2023
      More actions

      Oh well. I was actually using this functionality.
      It was super convenient to do something like:

      with Path('debian') / 'fill.copyright.blanks.yml' as debian_copyright_overrides:
          if debian_copyright_overrides.is_file():
              ...
          else:
              ...

      Basically it was a very visual way to structure code that worked with different subpaths. So no matter that it didn’t "close" path, it allowed to temporarily assign a shortcut to that path, do some work, and then forget about it.

      Reacted by rosscdh-tpg
    20. barneygale commented on Oct 13, 2023

      @barneygale
      barneygale
      on Oct 13, 2023
      ContributorAuthor
      More actions

      Perhaps contextlib.nullcontext() would help?

      But context managers are all about acquiring and releasing resources. It could be considered misleading to use a context manager only for code formating purposes. I would write:

      debian_copyright_overrides = Path('debian') / 'fill.copyright.blanks.yml'
      if debian_copyright_overrides.is_file():
          ...
      else:
          ...
      Reacted by CCP Murgatroyd and Feuermurmel
    21. agx
      added a commit that references this issue on Jan 9, 2025

      repo-setup: Drop context manager for posix path

      ae6f841
    22. mhy-pexip
      added a commit that references this issue on Apr 28, 2025

      Import Debian version 0.9.38

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

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.9 (EOL)end of lifeend of lifestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        You are visitor 01402503 — GeezerVison does not store the pages you look up.
        Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.