Skip to content

Pathlib relative_to issue on python 3.13+ #1279

@dlegaultbbry

Description

@dlegaultbbry

Describe the bug
pathlib relative_to fails with pyfakefs in testing. This only happens on python 3.13 and 3.14. 3.12 works fine with the test.

This code runs fine in production.

Note that the bug doesn't manifest itself if you do not have the dataclass and the sub-function called. This was the simplest reproducer I could come up with to showcase the error.

The bug still happens with pyfakefs 6.1.0

How To Reproduce

from dataclasses import dataclass
from pyfakefs.fake_filesystem import FakeFilesystem
from pathlib import Path

@dataclass
class Options:
    rootdir: Path

FAKE_OPTIONS = Options(
    rootdir=Path('/root'),
)

def something(utpath: Path, options: Options) -> None:
    print(utpath)
    print(options.rootdir)
    rel_path = utpath.relative_to(options.rootdir)


def test_pyfakefs_bug(fs: FakeFilesystem):

    utpath = Path('/root/src/unittests')
    fs.create_dir(utpath)

    something(utpath, FAKE_OPTIONS)
fs = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x75afad170c20>

    def test_pyfakefs_bug(fs: FakeFilesystem):
    
        utpath = Path('/root/src/unittests')
        fs.create_dir(utpath)
    
>       something(utpath, FAKE_OPTIONS)

/code/tests/pyfakefs_bug_test.py:25: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/code/tests/pyfakefs_bug_test.py:17: in something
    rel_path = utpath.relative_to(options.rootdir)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = PosixPath('/root/src/unittests'), other = PosixPath('/root')

    def relative_to(self, other, *, walk_up=False):
        """Return the relative path to another path identified by the passed
        arguments.  If the operation is not possible (because this is not
        related to the other path), raise ValueError.
    
        The *walk_up* parameter controls whether `..` may be used to resolve
        the path.
        """
        if not hasattr(other, 'with_segments'):
            other = self.with_segments(other)
        for step, path in enumerate(chain([other], other.parents)):
            if path == self or path in self.parents:
                break
            elif not walk_up:
>               raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}")
E               ValueError: '/root/src/unittests' is not in the subpath of '/root'

Your environment

Linux-6.8.0-87-generic-x86_64-with-glibc2.39
Python 3.14.2 (main, Dec  9 2025, 19:03:28) [Clang 21.1.4 ]
pyfakefs 6.0.0
pytest 9.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions