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

Support pathlib.Path parameter in create_dir() #409

Closed
shuttle1987 opened this issue May 31, 2018 · 6 comments · Fixed by #410
Closed

Support pathlib.Path parameter in create_dir() #409

shuttle1987 opened this issue May 31, 2018 · 6 comments · Fixed by #410
Assignees

Comments

@shuttle1987
Copy link

shuttle1987 commented May 31, 2018

I created a repository here to show the bug I am getting:
https://github.com/shuttle1987/pyfakefs-pathlib-fail

Essentially when this test is run:

def test_pathlib(fs): #fs is the fake filesystem fixture
    """Attempt to use a pathlib path"""

    import pathlib
    base_dir = pathlib.Path('/tmp/corpus_data')
    fs.create_dir(base_dir)

    from example_lib.searcher import determine_labels

The failure is as follows:

$ python -m pytest
================================================ test session starts ================================================
platform linux -- Python 3.5.2, pytest-3.6.0, py-1.5.3, pluggy-0.6.0
rootdir: /home/janis/pyfakefs-pathlib-fail, inifile:
plugins: cov-2.5.1, pyfakefs-3.4.1
collected 1 item                                                                                                    

tests/test_example.py F                                                                                       [100%]

===================================================== FAILURES ======================================================
___________________________________________________ test_pathlib ____________________________________________________

fs = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x7f03fc2b9a90>

>   ???

home/janis/pyfakefs-pathlib-fail/tests/test_example.py:6: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
home/janis/pyfakefs-pathlib-fail/venv/lib/python3.5/site-packages/pyfakefs/fake_filesystem.py:2137: in create_dir
    ???
home/janis/pyfakefs-pathlib-fail/venv/lib/python3.5/site-packages/pyfakefs/fake_filesystem.py:1362: in absnormpath
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x7f03fc2b9a90>, file_path = PosixPath('/tmp/corpus_data')

>   ???
E   AttributeError: 'PosixPath' object has no attribute 'startswith'

home/janis/pyfakefs-pathlib-fail/venv/lib/python3.5/site-packages/pyfakefs/fake_filesystem.py:1578: AttributeError
============================================= 1 failed in 0.12 seconds ==============================================

As far as I can tell from reading the documentation this library is supposed to patch pathlib.Path.

@mrbean-bremen
Copy link
Member

Thanks for the report! Currently, create_dir is not designed to take a Path parameter, so you have to convert it to a string first, e.g. fs.create_dir (str (base_dir)).
But I agree that it would make sense to support this - I will adapt it accordingly.

@mrbean-bremen mrbean-bremen changed the title creatre_dir fails with pathlib.Path parameter in pytest Support pathlib.Path parameter in create_dir() May 31, 2018
@mrbean-bremen mrbean-bremen self-assigned this May 31, 2018
@shuttle1987
Copy link
Author

shuttle1987 commented Jun 1, 2018

I have converted to a str as requested but there's still an issue with the paths, consider this test case:

def test_determine_labels(fs): #fs is the fake filesystem fixture
    """test the function that determines what labels exist in a directory"""
    from pyfakefs.fake_filesystem_unittest import Patcher

    with Patcher(use_dynamic_patch=True) as patcher:
        import pathlib
    base_dir = pathlib.Path('/tmp/corpus_data')
    label_dir = base_dir / "label"
    fs.create_dir(str(base_dir))
    fs.create_dir(str(label_dir))
    test_1_phonemes = 'ɖ ɯ ɕ i k v̩'
    test_1_phonemes_and_tones = 'ɖ ɯ ˧ ɕ i ˧ k v̩ ˧˥'
    test_2_phonemes = 'g v̩ tsʰ i g v̩ k v̩'
    test_2_phonemes_and_tones = 'g v̩ ˧ tsʰ i ˩ g v̩ ˩ k v̩ ˩'
    fs.create_file(str(label_dir / "test1.phonemes"), contents=test_1_phonemes)
    fs.create_file(str(label_dir / "test1.phonemes_and_tones"), contents=test_1_phonemes_and_tones)
    fs.create_file(str(label_dir / "test2.phonemes"), contents=test_2_phonemes)
    fs.create_file(str(label_dir / "test2.phonemes_and_tones"), contents=test_1_phonemes_and_tones)
    assert base_dir.exists()
    assert label_dir.exists()

This fails with the following:

_________________________________ test_determine_labels _________________________________

fs = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x7f3706e3ff28>

>   ???
E   AssertionError: assert False
E    +  where False = <bound method Path.exists of PosixPath('/tmp/corpus_data')>()
E    +    where <bound method Path.exists of PosixPath('/tmp/corpus_data')> = PosixPath('/tmp/corpus_data').exists

home/janis/persephone/persephone/tests/test_corpus.py:42: AssertionError

Also I notice the stacktrace is not quite right here either with the > ???

Does this imply that pathlib operations can't be relied upon?

@shuttle1987
Copy link
Author

Is the stacktrace issue related to #381?

@mrbean-bremen
Copy link
Member

Is the stacktrace issue related to #381?

Exactly. This should be fixed in master for Python 3.
I will have a look at the other issue in the evening or the weekend.

@mrbean-bremen
Copy link
Member

mrbean-bremen commented Jun 1, 2018

The following works fine for me:

# -*- coding: utf-8 -*-
import pathlib


def test_determine_labels(fs):
    base_dir = pathlib.Path('/tmp/corpus_data')
    label_dir = base_dir / "label"
    fs.create_dir(str(base_dir))
    fs.create_dir(str(label_dir))
    test_1_phonemes = 'ɖ ɯ ɕ i k v̩'
    fs.create_file(str(label_dir / "test1.phonemes"),
                   contents=test_1_phonemes, encoding='utf-8')
    assert base_dir.exists()
    assert label_dir.exists()

Note that I had to add the utf-8 stuff because I tested this under Windows, where UTF-8 is not the default encoding - under Linux it should not be needed (though it would make the code more compatible).
The relevent change is the pathlib import - the import inside the additional patcher context does not work and is not needed. The fs fixture already has a patcher instantiated that takes care of the patching, so the additional patcher tries to patch it again, and removes the patching after going out of context.

mrbean-bremen added a commit to mrbean-bremen/pyfakefs that referenced this issue Jun 1, 2018
- concerns create_file(), create_dir(), create_symlink(), add_real_file() and add_real_directory()
- closes pytest-dev#409
mrbean-bremen added a commit that referenced this issue Jun 2, 2018
- concerns create_file(), create_dir(), create_symlink(), add_real_file() and add_real_directory()
- closes #409
@shuttle1987
Copy link
Author

Thanks for the patch!

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

Successfully merging a pull request may close this issue.

2 participants