Skip to content

Exception thrown by shlex.quote changed in 3.14 and is not documented #138804

Description

@cybit

Bug report

Bug description:

It seems to me that #132036 not only made the import time faster but did also change the exception thrown if the arguments in shlex.quote are not of type str.

It used to be "TypeError", now it is "AttributeError" .

I am not able to find this change in the release notes or the PR.

Test code:

import shlex

shlex.quote(123)

Test run on the shell:

➜ for i in 10 11 12 13 14 ; do echo "3.$i" ; uv run --python 3.$i test.py 2>&1 | tail -n 1 ; done
3.10
TypeError: expected string or bytes-like object
3.11
TypeError: expected string or bytes-like object, got 'int'
3.12
TypeError: expected string or bytes-like object, got 'int'
3.13
TypeError: expected string or bytes-like object, got 'int'
3.14
AttributeError: 'int' object has no attribute 'isascii'

CPython versions tested on:

3.10, 3.11, 3.12, 3.13, 3.14

Operating systems tested on:

macOS

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Sep 11, 2025
  2. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Sep 11, 2025
  3. StanFromIreland commented on Sep 11, 2025

    @StanFromIreland
    Member

    For reference, on 3.13:

    >>> import shlex
    ... 
    ... shlex.quote(123)
    ... 
    Traceback (most recent call last):
      File "<python-input-0>", line 3, in <module>
        shlex.quote(123)
        ~~~~~~~~~~~^^^^^
      File "/usr/lib64/python3.13/shlex.py", line 327, in quote
        if _find_unsafe(s) is None:
           ~~~~~~~~~~~~^^^
    TypeError: expected string or bytes-like object, got 'int'
    

    cc @AA-Turner

  4. added
    3.14bugs and security fixes
    3.15bugs and security fixes
    on Sep 11, 2025
  5. picnixz commented on Sep 11, 2025

    @picnixz
    Member

    A check of the form if isinstance(s, str | bytes): or if isinstance(s, (str, bytes)): (don't know which one is the preferred way in this module). shouldn't be too costly here so let's add it. Before, it was implicitly done in _find_unsafe as it relied on re.Pattern.search.

  6. added 2 commits that reference this issue on Sep 11, 2025
  7. wiomoc commented on Sep 11, 2025

    @wiomoc
    Contributor

    A check of the form if isinstance(s, str | bytes): or if isinstance(s, (str, bytes)): (don't know which one is the preferred way in this module). shouldn't be too costly here so let's add it. Before, it was implicitly done in _find_unsafe as it relied on re.Pattern.search.

    As encode() is called on the argument, passing a bytes object should raise a TypeError too.

  8. cybit commented on Sep 12, 2025

    @cybit
    Author

    As encode() is called on the argument, passing a bytes object should raise a TypeError too.

    Might that be the reason for #69753 ?

  9. added a commit that references this issue on Sep 12, 2025
  10. added a commit that references this issue on Sep 12, 2025
  11. added a commit that references this issue on Sep 13, 2025
  12. hugovk commented on Sep 13, 2025

    @hugovk
    Member

    Thanks for the report and fix!

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.14bugs and security fixes3.15bugs and security fixeseasystdlibStandard 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