Skip to content

3.15.0b2 test_shutil failure on FreeBSD in a "poudriere jail" mounted atop ZFS file system #150984

Open

Description

@mandree

Bug report

Bug description:

Greetings,

building Python 3.15.0b2 (beta 2) on FreeBSD in a poudriere jail mounted atop a ZFS file system, where poudriere is the tool that FreeBSD uses for package building, and a jail is a stricter companion of a chroot, we get this make test failure in test_shutil. Note that the OSError 45 (aka EOPNOTSUPP) relates to the test_tempfile failure reported in gh-150982, #150982.

It is not clear to me why a jail or how poudriere mounts the underlying filesystem would NOT support UF_OPAQUE because outside poudriere (albeit on a different minor version of the operating system), I don't get OSError [Errno 45] exceptions on the same test.

As suggested in #150982, I am wondering whether it would be useful to map this particular errno (EOPNOTSUPP) to a NotImplementedError exception and handle that.

This is the test with offending lines marked with python comments in three (3) places,
followed by the unittest output.

    def test_move_dir_permission_denied(self):
        # bpo-42782: shutil.move should not create destination directories
        # if the source directory cannot be removed.
        try:
            os.mkdir(TESTFN_SRC)
            os.lchflags(TESTFN_SRC, stat.SF_IMMUTABLE)

            # Testing on an empty immutable directory
            # TESTFN_DST should not exist if shutil.move failed
            self.assertRaises(PermissionError, shutil.move, TESTFN_SRC, TESTFN_DST)
            self.assertFalse(TESTFN_DST in os.listdir())

            # Create a file and keep the directory immutable
            os.lchflags(TESTFN_SRC, stat.UF_OPAQUE)   # <-- offender #1
            os_helper.create_empty_file(os.path.join(TESTFN_SRC, 'child'))
            os.lchflags(TESTFN_SRC, stat.SF_IMMUTABLE)

            # Testing on a non-empty immutable directory
            # TESTFN_DST should not exist if shutil.move failed
            self.assertRaises(PermissionError, shutil.move, TESTFN_SRC, TESTFN_DST)
            self.assertFalse(TESTFN_DST in os.listdir())
        finally:
            if os.path.exists(TESTFN_SRC):
                os.lchflags(TESTFN_SRC, stat.UF_OPAQUE)   # <-- offender #2
                os_helper.rmtree(TESTFN_SRC)
            if os.path.exists(TESTFN_DST):
                os.lchflags(TESTFN_DST, stat.UF_OPAQUE)   # <-- not reached, but would be offender #3.
                os_helper.rmtree(TESTFN_DST)
ERROR: test_move_dir_permission_denied (test.test_shutil.TestMove.test_move_dir_permission_denied)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/wrkdirs/usr/ports/lang/python315/work/Python-3.15.0b2/Lib/test/test_shutil.py", line 3051, in test_move_dir_permission_denied
    os.lchflags(TESTFN_SRC, stat.UF_OPAQUE)
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 45] Operation not supported: '@test_22085_tmpæ_SRC'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/wrkdirs/usr/ports/lang/python315/work/Python-3.15.0b2/Lib/test/test_shutil.py", line 3061, in test_move_dir_permission_denied
    os.lchflags(TESTFN_SRC, stat.UF_OPAQUE)
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 45] Operation not supported: '@test_22085_tmpæ_SRC'

----------------------------------------------------------------------
Ran 225 tests in 1.029s

FAILED (errors=1, skipped=69)
Warning -- files was modified by test_shutil
Warning --   Before: []
Warning --   After:  ['@test_22085_tmpæ_SRC/'] 

CPython versions tested on:

3.15

Operating systems tested on:

Other

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Jun 5, 2026
  2. changed the title [-]3.15.0b2 test failure on FreeBSD in a "poudriere jail" mounted atop ZFS file system[/-] [+]3.15.0b2 test_shutil failure on FreeBSD in a "poudriere jail" mounted atop ZFS file system[/+] on Jun 5, 2026
  3. vstinner commented on Jun 8, 2026

    @vstinner
    Member

    What is the result if you run the following script?

    import os, stat
    
    filename = '/tmp/test.python'
    os.mkdir(filename)
    try:
        os.lchflags(filename, stat.SF_IMMUTABLE)
        os.lchflags(filename, stat.UF_OPAQUE)
    finally:
        os.rmdir(filename)

    On my FreeBSD machine, I have to run the script as root. Otherwise, lchflags(SF_IMMUTABLE) fails with PermissionError.

    ./python -m test test_shutil -m test_move_dir_permission_denied -v is skipped with 'requires CAP_DAC_OVERRIDE'. It pass if I run the test as root.

  4. mandree commented on Jun 8, 2026

    @mandree
    Author

    Unprivileged, on ZFS:

    $ freebsd-version -kru ; uname -m   # [installed] kernel, running [kernel], userspace; machine
    15.1-RC3
    15.1-RC3
    15.1-RC3
    amd64
    
    $ df -T /tmp
    Filesystem  Type 1K-blocks Used     Avail Capacity  Mounted on
    zroot/tmp   zfs  203347617   41 203347576     0%    /tmp
    
    $ python3.15 script.py
    Traceback (most recent call last):
      File "/usr/home/mandree/script.py", line 6, in <module>
        os.lchflags(filename, stat.SF_IMMUTABLE)
        ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    PermissionError: [Errno 1] Operation not permitted: '/tmp/test.python'
    

    Privileged, on ZFS:

    $ sudo python3.15 script.py
    Traceback (most recent call last):
      File "/usr/home/mandree/script.py", line 7, in <module>
        os.lchflags(filename, stat.UF_OPAQUE)
        ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
    OSError: [Errno 45] Operation not supported: '/tmp/test.python'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/home/mandree/script.py", line 9, in <module>
        os.rmdir(filename)
        ~~~~~~~~^^^^^^^^^^
    PermissionError: [Errno 1] Operation not permitted: '/tmp/test.python'
    
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

    OS-freebsdtestsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions