Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move the check bs if not None #26887

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions Lib/urllib/parse.py
Expand Up @@ -893,10 +893,12 @@ def quote_from_bytes(bs, safe='/'):
not perform string-to-bytes encoding. It always returns an ASCII string.
quote_from_bytes(b'abc def\x3f') -> 'abc%20def%3f'
"""
if not isinstance(bs, (bytes, bytearray)):
raise TypeError("quote_from_bytes() expected bytes")
if not bs:
return ''

if not isinstance(bs, (bytes, bytearray)):
raise TypeError("quote_from_bytes() expected bytes")

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for your contribution.

This changes behavior, and if it didn't break any of the unit tests it means this case is not covered by tests and you need to fix that in this PR.

You also need to create an issue on bugs.python.org to describe this change and confirm that this is a bug and not a feature.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, it's not redundant:

isinstance(None, (bytes, bytearray))
False

so before the change None gave TypeError and after the change it returns ''.

Copy link
Member

Choose a reason for hiding this comment

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

I think thats what the logic should be, None == not bs hence '', Type Error is meant for the instance check, no? I will leave to you.

Copy link
Member

Choose a reason for hiding this comment

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

I don't follow. The change is this:

def old():
    bs = None
    if not isinstance(bs, (bytes, bytearray)):
        raise TypeError("quote_from_bytes() expected bytes")
    if not bs:
        return ''

def new():
    bs = None
    if not bs:
        return ''
    if not isinstance(bs, (bytes, bytearray)):
        raise TypeError("quote_from_bytes() expected bytes")

print('--------- new:')
print(new() == '')
print('--------- old:')
print(old() == '')

output:

--------- new:
True
--------- old:
Traceback (most recent call last):
  File "C:\Users\User\src\cpython-current\tmp.py", line 20, in <module>
    print(old() == '')
  File "C:\Users\User\src\cpython-current\tmp.py", line 6, in old
    raise TypeError("quote_from_bytes() expected bytes")
TypeError: quote_from_bytes() expected bytes

Copy link
Member

Choose a reason for hiding this comment

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

hmm, I would see how returning TypeError for None would have been a feature and intentional hence this PR maybe actually wrong in that case.

if isinstance(safe, str):
# Normalize 'safe' by converting to bytes and removing non-ASCII chars
safe = safe.encode('ascii', 'ignore')
Expand Down