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 — Should shutil functions support bytes paths? · Issue #90883 · python/cpython

Should shutil functions support bytes paths? #90883

New issue
Copy link
New issue
Copy link
Open
Open
Should shutil functions support bytes paths?#90883
Copy link
Labels
stdlibStandard 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

@JelleZijlstra
JelleZijlstra
opened on Feb 12, 2022
Issue body actions
BPO 46727
Nosy @serhiy-storchaka, @JelleZijlstra, @AlexWaygood

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 2022-02-12.01:43:24.033>
labels = ['type-bug', 'library', '3.11']
title = 'Should shutil functions support bytes paths?'
updated_at = <Date 2022-02-12.01:43:24.033>
user = 'https://github.com/JelleZijlstra'

bugs.python.org fields:

activity = <Date 2022-02-12.01:43:24.033>
actor = 'JelleZijlstra'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2022-02-12.01:43:24.033>
creator = 'JelleZijlstra'
dependencies = []
files = []
hgrepos = []
issue_num = 46727
keywords = []
message_count = 1.0
messages = ['413113']
nosy_count = 3.0
nosy_names = ['serhiy.storchaka', 'JelleZijlstra', 'AlexWaygood']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue46727'
versions = ['Python 3.11']

Activity

  1. JelleZijlstra commented on Feb 12, 2022

    @JelleZijlstra
    JelleZijlstra
    on Feb 12, 2022
    MemberAuthor
    More actions

    The shutil documentation doesn't say anything about bytes paths, and the CPython unit tests don't test them. But some functions do work with bytes paths in practice, and on typeshed we've received some requests to add support for them in the type stubs.

    Links:

    • Fix shutil.unpack_archive stub typeshed#6869 (shutil.unpack_archive works with bytes paths, but only sometimes)
    • Fix shutil.make_archive stub typeshed#6868 (shutil.make_archive)
    • Adjust shutil.move stubs to allow bytes/Pathlike[bytes] args typeshed#6832 (shutil.move accepts bytes paths, except when moving into an existing directory)

    My overall impression is that bytes paths sometimes work by accident because they happen to not hit any code paths where we do os.path.join or string concatenation, but relying on them is risky because minor changes in the call site or in the file system can cause the call to break.

    Here's three possible proposals:

    (1) We document in the shutil docs that only str paths are officially supported. Bytes paths may sometimes work, but do it at your own risk.

    (2) We add this documentation, but also make code changes to deprecate or even remove any support for bytes paths.

    (3) We decide that bytes paths are officially supported, and we add tests for them and fix any cases where they don't work.

    My preference is for (1). (2) feels like gratuitously breaking backward compatibility, and (3) is more work and there is little indication that bytes path support is a desired feature.

  2. JelleZijlstra
    added
    3.11only security fixesonly security fixes
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Feb 12, 2022
  3. ezio-melotti
    transferred this issue fromon Apr 10, 2022
  4. johnslavik commented on Oct 11, 2025

    @johnslavik
    johnslavik
    on Oct 11, 2025
    Member
    More actions

    I'm also against 2 and in favor of extending the documentation/improving coverage.

    As some extra info here:

    shutil.which supports byte paths since #11818 (2019), motivated by #62483. The most relevant piece of discussion took place in 2013, notably in #62483 (comment), when @vstinner said:

    Bytes is the native type for path on all platforms... except Windows. So I fixed many functions of the os module to support bytes parameters. For example, functions of os.path support str and bytes types, but not bytearray. I also prefer to reject byte-like objects, to keep it simple.

    The bytes type should be accepted for any kind of os function parameter: path, environment variable, command line argument, etc. It's not a question of being compatible with Python 2, an application can make the choice of only used bytes because bytes is the native type for OS data on UNIX.

    Python 3 supports also "bytes stored in Unicode" thanks to the PEP-393, but it's not exactly the same: a path stored as str depends on the filesystem locale, whereas a bytes string is well defined (it's just an array of 8-bit unsigned numbers) and doesn't depend on any configuration variable.

    [...]

    Almost all functions of the shutil module support bytes filenames. I tested shutil.copyfile(), shutil.ignore_patterns(), shutil.copytree(), shutil.rmtree() and shutil.move().

    My interpretation is that it was explicitly intended that byte paths were supported in all these functions.
    However, in our current test suite, we're only testing that shutil.rmtree and shutil.which work with byte paths:

    cpython/Lib/test/test_shutil.py

    Line 186 in 35e9d41

    def test_rmtree_works_on_bytes(self):

    cpython/Lib/test/test_shutil.py

    Line 2697 in 35e9d41

    class TestWhichBytes(TestWhich):

    I only found one function which only support Unicode filenames: shutil.make_archive().

    That would be true for shutil.unpack_archive as well.

    Adding support for byte paths to shutil.make_archive and shutil.unpack_archive would be tedious because there's a lot of concatenation by coexisting _make_tarball & _make_zipfile and helper functions such as shutil.register_unpack_format, shutil.unregister_unpack_format etc.

    Replying to OP:

    there is little indication that bytes path support is a desired feature.

    Seems like this holds true after 3+ more years.

    I'll try to add bytes paths tests to shutil.copyfile, shutil.ignore_patterns, shutil.copytree, shutil.copystat and see if it can hit a code path that breaks. If it does, let's decide about support for bytes path for every function case by case, in separate issues, otherwise merge in new tests.

    WDYT?

  5. picnixz
    removed
    3.11only security fixesonly security fixes
    on Oct 12, 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-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.