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 — Improve file URI ergonomics in `urllib.request` · Issue #125866 · python/cpython

Improve file URI ergonomics in urllib.request #125866

New issue
Copy link
New issue
Copy link
Closed
Closed
Improve file URI ergonomics in urllib.request#125866
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement

Description

@barneygale
barneygale
opened on Oct 23, 2024
Issue body actions

Feature or enhancement

I request that we make pathname2url and url2pathname easier to use:

  • pathname2url() is made to accept an optional include_scheme argument that sticks file: on the front when true
  • url2pathname() is made to strip any file: prefix from its argument.

I think this would go a long way towards making these functions usable, and allow us to remove the scary "This does not accept/produce a complete URL" warnings from the docs.

Linked PRs

  • GH-125866: Improve tests for pathname2url() and url2pathname() #125993
  • [3.13] GH-125866: Improve tests for pathname2url() and url2pathname() (GH-125993) #126144
  • [3.12] GH-125866: Improve tests for pathname2url() and url2pathname() (GH-125993) #126145
  • GH-125866: Preserve Windows drive letter case in file URIs #127138
  • GH-125866: Deprecate nturl2path module #131432
  • GH-125866: Support complete "file:" URLs in urllib #132378
Reacted by Tomas R.

Activity

Next
  1. barneygale
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on Oct 23, 2024
  2. barneygale
    added 4 commits that reference this issue on Oct 25, 2024

    pythonGH-125866: Improve tests for `pathname2url()` and `url2pathname()`

    593b23b

    Merge branch 'main' into pythongh-125866-move-tests

    75c2944

    Merge branch 'main' into pythongh-125866-move-tests

    f455c0d

    GH-125866: Improve tests for `pathname2url()` and `url2pathname()` (#…

    6742f14
  3. miss-islington
    added 2 commits that reference this issue on Oct 29, 2024

    pythonGH-125866: Improve tests for `pathname2url()` and `url2pathname…

    64c32bd

    pythonGH-125866: Improve tests for `pathname2url()` and `url2pathname…

    ea8fcb8
  4. barneygale
    added 3 commits that reference this issue on Oct 29, 2024

    [3.12] GH-125866: Improve tests for `pathname2url()` and `url2pathnam…

    b267b62

    [3.13] GH-125866: Improve tests for `pathname2url()` and `url2pathnam…

    35108c1

    pythonGH-125866: RFC8089 file URIs in `urllib.request`

    fb92f42
  5. picnixz
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Oct 30, 2024
  6. barneygale
    added a commit that references this issue on Oct 30, 2024

    Merge branch 'main' into pythongh-125866

    5c5a0b5
  7. barneygale
    added 3 commits that reference this issue on Nov 19, 2024

    Revise again with pythonGH-125866 in mind (sorry)

    27b1127

    pythonGH-125866: Preserve Windows drive letter case in file URIs

    770bb05

    GH-125866: Preserve Windows drive letter case in file URIs (#127138)

    cc813e1
  8. 7 remaining items

  9. barneygale commented on Nov 25, 2024

    @barneygale
    barneygale
    on Nov 25, 2024
    ContributorAuthor
    More actions

    @serhiy-storchaka I've revised the description as follows:

    I request that we make pathname2url and url2pathname easier to use:

    • pathname2url() is made to accept an optional include_scheme argument that sticks file: on the front when true
    • url2pathname() is made to strip any file: prefix from its argument.

    Does that seem like a good idea to you?

    If we go for these changes, and the user provides a URL with a non-file: scheme to url2pathname(), what should happen in your opinion? (I'm erring towards raising URLError.)

    Relatedly, what do you think should happen if the user provides a query or fragment in the URL? Currently it's returned as part of the file path. (This seems under-specified to me, but I'm leaning towards raising URLError here too.)

    Thank you

  10. serhiy-storchaka commented on Dec 2, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Dec 2, 2024
    Member
    More actions

    I wonder -- would not be better to add such functions in os.path? The implementation is clearly platform depending, and if we add support for platform with different path format (like old macpath), it will need a completely different implementation. In custom build for exotic platform it is easier to provide a separate os.path implementation than patch urllib.request.

  11. barneygale commented on Dec 3, 2024

    @barneygale
    barneygale
    on Dec 3, 2024
    ContributorAuthor
    More actions

    Good question! It's something that's come up before:

    • https://discuss.python.org/t/file-uris-in-python/15600
    • Add os.path.fileuri() function #88578

    The current Windows + POSIX implementations don't have much in common, but I think that will change when I address this issue and #123599. To solve them, I'm planning to use urlsplit() to parse the URL, replacing parts of the janky implementation in url2pathname(). Here's a rough draft of where I want to end up:

    def url2pathname(url):
        scheme, authority, path, query, fragment = urlsplit(url, scheme='file')
        if scheme != 'file':
            raise URLError(f'URL uses non-file scheme: {url!r}')
        if query:
            raise URLError(f'file URL has query: {url!r}')
        if fragment:
            raise URLError(f'file URL has fragment: {url!r}')
    
        if os.name == 'nt':
            # Windows-specific file URI quirks.
            if authority and authority != 'localhost':
                # e.g. file://server/share/file.txt
                path = '//' + authority + path
            elif path[:3] == '///':
                # e.g. file://///server/share/file.txt
                path = path[1:]
            else:
                if path[:1] == '/' and path[2:3] in ':|':
                    # Skip past extra slash before DOS drive in URL path.
                    path = path[1:]
                if path[1:2] == '|':
                    # Older URLs use a pipe after a drive letter
                    path = path.replace('|', ':', 1)
            path = path.replace('/', '\\')
        elif not _is_local_authority(authority):
            # POSIX only: reject URL if authority doesn't resolve to localhost.
            raise URLError(f'file URL has non-local authority: {url!r}')
    
        encoding = sys.getfilesystemencoding()
        errors = sys.getfilesystemencodeerrors()
        return unquote(path, encoding=encoding, errors=errors)
    
    
    def pathname2url(pathname, include_scheme=False):
        if os.name == 'nt':
            pathname = pathname.replace('\\', '/')
        encoding = sys.getfilesystemencoding()
        errors = sys.getfilesystemencodeerrors()
        prefix = 'file:' if include_scheme else ''
        drive, root, tail = os.path.splitroot(pathname)
    
        if drive:
            if drive[:4] == '//?/':
                drive = drive[4:]
                if drive[:4].upper() == 'UNC/':
                    drive = '//' + drive[4:]
            if drive[1:] == ':':
                prefix += '///'
            drive = quote(drive, encoding=encoding, errors=errors, safe='/:')
        elif root:
            prefix += '//'
    
        tail = quote(tail, encoding=encoding, errors=errors)
        return prefix + drive + root + tail

    There's clearly some OS-specific code in there, but there's also a fair amount of shared and URL-specific code which might feel out-of-place in os.path.

    Besides, if we added functions in os.path we'd need to either live with near-duplicate functionality in urllib, or deprecate the urllib functions (which isn't much fun for their users). I'm not ruling that out, but it seems unnecessarily if there's a reasonable path towards making pathname2url() and url2pathname() a bit more usable.

  12. barneygale commented on Dec 3, 2024

    @barneygale
    barneygale
    on Dec 3, 2024
    ContributorAuthor
    More actions

    FWIW, if we go with the above merger, then we can deprecate the oddball nturl2path module.

  13. picnixz
    added a commit that references this issue on Dec 8, 2024

    pythonGH-125866: Improve tests for `pathname2url()` and `url2pathname…

    d2f44de
  14. ebonnal
    added 2 commits that reference this issue on Jan 12, 2025

    pythonGH-125866: Improve tests for `pathname2url()` and `url2pathname…

    861925b

    pythonGH-125866: Preserve Windows drive letter case in file URIs (pyt…

    c83f8e9
  15. barneygale
    added 3 commits that reference this issue on Mar 18, 2025

    pythonGH-125866: Add tests for `nturl2path` module

    033baf5

    Merge branch 'main' into pythongh-125866-nturl2path-tests

    85a84fc

    GH-125866: Deprecate `nturl2path` module (#131432)

    8abfaba
  16. barneygale
    added 4 commits that reference this issue on Apr 10, 2025

    pythonGH-125866: Support complete "file:" URLs in urllib

    f70b2c1

    pythonGH-125866: Support complete "file:" URLs in urllib

    8c9fe62

    Merge branch 'main' into pythongh-125866-again

    db2876d

    GH-125866: Support complete "file:" URLs in urllib (#132378)

    ccad61e
  17. barneygale
    closed this as completedon Apr 14, 2025
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

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

    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.