Skip to content

urllib.parse.urlunsplit makes relative path to absolute (http:g -> http:///g) #85110

Closed

Description

@openandclose
BPO 40938
Nosy @orsenthil, @openandclose, @jaswdr

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 = None
created_at = <Date 2020-06-10.11:18:48.328>
labels = ['3.7', '3.8', 'type-bug', 'library', '3.9']
title = 'urllib.parse.urlunsplit makes relative path to absolute (http:g -> http:///g)'
updated_at = <Date 2021-05-13.14:11:56.189>
user = 'https://github.com/openandclose'

bugs.python.org fields:

activity = <Date 2021-05-13.14:11:56.189>
actor = 'op368'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2020-06-10.11:18:48.328>
creator = 'op368'
dependencies = []
files = []
hgrepos = []
issue_num = 40938
keywords = []
message_count = 7.0
messages = ['371179', '393544', '393574', '393576', '393577', '393578', '393583']
nosy_count = 3.0
nosy_names = ['orsenthil', 'op368', 'jaswdr']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue40938'
versions = ['Python 3.7', 'Python 3.8', 'Python 3.9']

Linked PRs

Activity

  1. openandclose commented on Jun 10, 2020

    openandclosemannequin
    MannequinAuthor

    path 'g' in 'http:g' becomes '/g'.

        >>> urlsplit('http:g')
        SplitResult(scheme='http', netloc='', path='g', query='', fragment='')
        >>> urlunsplit(urlsplit('http:g'))
        'http:///g'
        >>> urlsplit('http:///g')
        SplitResult(scheme='http', netloc='', path='/g', query='', fragment='')
    
        >>> urljoin('http://a/b/c/d', 'http:g')
        'http://a/b/c/g'
        >>> urljoin('http://a/b/c/d', 'http:///g')
        'http://a/g'

    The problematic part of the code is:

        def urlunsplit(components):
            [...]
            if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'):
    --->        if url and url[:1] != '/': url = '/' + url
                url = '//' + (netloc or '') + url

    Note also that urllib has decided on the interpretation of 'http:g' (in test).

        def test_RFC3986(self):
            [...]
            #self.checkJoin(RFC3986_BASE, 'http:g','http:g') # strict parser
            self.checkJoin(RFC3986_BASE, 'http:g','http://a/b/c/g') #relaxed parser
  2. added
    type-bugAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directory
    on Jun 10, 2020
  3. jaswdr commented on May 12, 2021

    jaswdrmannequin
    Mannequin

    @op368 I don't think that this is a bug, [1] literally uses this exact example and shows the expected behaviour.

    [1] https://datatracker.ietf.org/doc/html/rfc3986#section-5.4.2

  4. openandclose commented on May 13, 2021

    openandclosemannequin
    MannequinAuthor

    hello, @jaswdr, but I can't understand what's wrong with my point.
    What is 'the expected behaviour'?

  5. jaswdr commented on May 13, 2021

    jaswdrmannequin
    Mannequin

    @op368 as far as I can see, regarding of any miss interpretation, yes, the RFC has this section:

      "http:g"        =  "http:g"         ; for strict parsers
                      /  "http://a/b/c/g" ; for backward compatibility
    

    What I can understand is that for "http:g" it will be translated to "http:///g" because of backward compatibility, this seems to be an edge case for the parser, since the RFC text also mention that this should be avoided.

  6. openandclose commented on May 13, 2021

    openandclosemannequin
    MannequinAuthor

    'http:///g' has absolute path '/g',
    and as urljoin shows:

        >>> urljoin('http://a/b/c/d', 'http:///g')
        'http://a/g'  # 'a' is netloc

    So you are proposing third interpretation.

      "http:g"        =  "http:g"         ; for strict parsers
                      /  "http://a/b/c/g" ; for backward compatibility
                      /  "http://a/g"     ; (yours)
    
  7. 15 remaining items

  8. added a commit that references this issue on Feb 11, 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

    3.7 (EOL)end of life3.8 (EOL)end of life3.9 (EOL)end of lifestdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions