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

'WindowsPath' object has no attribute 'startswith' when setting cwd #1108

Closed
wavesinaroom opened this issue Jan 7, 2025 · 7 comments · Fixed by #1109
Closed

'WindowsPath' object has no attribute 'startswith' when setting cwd #1108

wavesinaroom opened this issue Jan 7, 2025 · 7 comments · Fixed by #1109

Comments

@wavesinaroom
Copy link

wavesinaroom commented Jan 7, 2025

I'm working on a project that uses pyfakefs to mock my filesystem to test folder creation and missing folders in a previously defined tree structure. I'm using Python 3.13 on Windows and get this output from the terminal after running my test:

Terminal output:

E
======================================================================
ERROR: test_top_folders_exist (file_checker.tests.file_checker_tests.TestFolderCheck.test_top_folders_exist)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\juank\dev\projects\python\gamedev_eco\file_checker\tests\file_checker_tests.py", line 20, in test_top_folders_exist
    self.fs.create_dir(Path.cwd() / "gdd")
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\juank\AppData\Local\Programs\Python\Python313\Lib\site-packages\pyfakefs\fake_filesystem.py", line 2191, in create_dir
    dir_path = self.absnormpath(dir_path)
  File "C:\Users\juank\AppData\Local\Programs\Python\Python313\Lib\site-packages\pyfakefs\fake_filesystem.py", line 1133, in absnormpath
    path = self.replace_windows_root(path)
  File "C:\Users\juank\AppData\Local\Programs\Python\Python313\Lib\site-packages\pyfakefs\fake_filesystem.py", line 1418, in replace_windows_root
    if path and self.is_windows_fs and self.root_dir:
                                       ^^^^^^^^^^^^^
  File "C:\Users\juank\AppData\Local\Programs\Python\Python313\Lib\site-packages\pyfakefs\fake_filesystem.py", line 357, in root_dir
    return self._mount_point_dir_for_cwd()
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "C:\Users\juank\AppData\Local\Programs\Python\Python313\Lib\site-packages\pyfakefs\fake_filesystem.py", line 631, in _mount_point_dir_for_cwd
    if path.startswith(str_root_path) and len(str_root_path) > len(mount_path):
       ^^^^^^^^^^^^^^^
AttributeError: 'WindowsPath' object has no attribute 'startswith'

----------------------------------------------------------------------
Ran 1 test in 0.011s

FAILED (errors=1)

Test:

from pyfakefs.fake_filesystem_unittest import TestCase

class TestFolderCheck(TestCase):
    """Test top folders = gdd marketing business"""

    @classmethod
    def setUp(cls):
        cls.setUpClassPyfakefs()
        cls.fake_fs().create_dir(Path.cwd() / "gamedev_eco")
        cls.fake_fs().cwd = Path.cwd() / "gamedev_eco"  # Needs to be cast with str() to work

    def test_top_folders_exist(self):
        self.fs.create_dir(Path.cwd() / "gdd")

I found out after troubleshooting with another programmer that cls.fake_fs().cwd had to be cast as a string to be legally set like this: str(cls.fake_fs().cwd). That is not so bad on tests but it is in my source code, otherwise tests won't pass.

import os
from pathlib import Path


class InvalidNameFormat(Exception):
    pass


class MissingFileFolder(Exception):
    pass


def check_folders():
    paths = [
        str(Path.cwd() / "gdd"),  # Works
        Path.cwd() / "marketing",  # Does not work
        Path.cwd() / "business",
        Path.cwd() / "gdd" / "components",
        Path.cwd() / "gdd" / "milestones",
        Path.cwd() / "gdd" / "components" / "characters",
        Path.cwd() / "gdd" / "components" / "environments",
        Path.cwd() / "gdd" / "components" / "ui",
        Path.cwd() / "gdd" / "components" / "cinematics",
    ]

    for root, dirs, files in os.walk(Path.cwd()):
        try:
            for d in dirs:
                paths.index(os.path.join(root, d))
        except ValueError:
            for p in paths:
                if not os.path.exists(p):
                    os.mkdir(p)
            raise MissingFileFolder(
                "Missing folders have been created for you, please use them store you markdown files"
            )

        for d in dirs:
            if d.isupper() and not d.isalpha():
                raise InvalidNameFormat(
                    f"{d} folder name must be lowercase and has no digits"
                )

I couldn't find anything that could give me a specific way to set cwd rather than just any string but I wonder if this is a platform or python version related issue. Maybe there's something different in Python 3.13 that causes this problem since a StackOverFlow community member confirmed me in this question he didn't get any trouble running the code on Linux and Python 3.11.

Please let me know if you need more details from my side I'd be glad to contribute to your project by helping out troubleshooting.

@mrbean-bremen
Copy link
Member

Thanks for the report! I can reproduce this with different Python versions, so this is not a Python 3.13-specific problem. It looks like a path object is passed somewhere where a string is expected.

@wavesinaroom
Copy link
Author

wavesinaroom commented Jan 7, 2025

Sure! Not a problem.

@wavesinaroom
Copy link
Author

wavesinaroom commented Jan 7, 2025

I just double-checked that this is related with the way I set cwd in my setUp method. I looked for a method in the documentation that would help me do that but apparently direct assignment seems the only choice. Do you have a specific method to set this variable e.g cls.fake_fs().setCwd() that my LSP (lsp-python) misses or I'm ignoring?

image

mrbean-bremen added a commit to mrbean-bremen/pyfakefs that referenced this issue Jan 7, 2025
@wavesinaroom wavesinaroom changed the title 'WindowsPath' object has no attribute 'startswith' 'WindowsPath' object has no attribute 'startswith' when setting cwd Jan 7, 2025
@mrbean-bremen
Copy link
Member

I made a PR that should fix this, will probably merge tomorrow in case nobody objects.
There is still another more complicated issue I wanted to handle before a patch release, but if I don't get that fixed in the near future, I'll probably make a release anyway.

@wavesinaroom
Copy link
Author

Awesome @mrbean-bremen! Many thanks for fixing this so quickly.

Have a good one \m/

@mrbean-bremen
Copy link
Member

FYI: the patch release is out now.

@wavesinaroom
Copy link
Author

Thanks a lot! Having it working has been awesome for the project I'm working on.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants