As other said, it resolves to the current path and therefore exists, but here's why,
pathlib.Path is acutally a subclass of pathlib.PurePath which assumes the current directory when the (argument) is empty (equivalent to pathsegments).''
You can prove that empirically like this,
from pathlib import PurePath
print(PurePath())
>>>> .
I assume there is an advantage gained by defining the Path('') to be the same as Path('.').
Correct. Even though I'm not the creator of that lib, I assume this is for syntax and logical reasons. Indeed, people often want to refer to the current directory to compute something dynamically. Therefore, for the same reason points to the current directory, the lib creator probably wanted to let you write something like this,.
>>>> p = Path() # or possibly Path('.')
>>> [x for x in p.iterdir() if x.is_dir()]
that would list sub directories.
Basically, see this as a default. It was logic that the default path returned by was the current directory. Thus, logically, an empty string value should have the same behavior.Path()
You need to patch the class, not the instance. It is enough to patch the method on the class, as it defines the Path method for the whole of the exists library (pathlib, PosixPath, WindowsPath and PurePosixPath all inherit the implementation):PureWindowsPath
>>> from unittest.mock import patch
>>> from pathlib import Path
>>> p = Path('~/test.py')
>>> with patch.object(Path, 'exists') as mock_exists:
... mock_exists.return_value = True
... p.exists()
...
True
>>> with patch.object(Path, 'exists') as mock_exists:
... mock_exists.return_value = False
... p.exists()
...
False
>>> with patch.object(Path, 'exists') as mock_exists:
... mock_exists.return_value = 'Anything you like, actually'
... p.exists()
...
'Anything you like, actually'
The classes use pathlib to keep their memory footprint low, which has the side-effect of their instances not supporting arbitrary attribute assignment.__slots__
Use for directories only:os.path.isdir
>>> import os
>>> os.path.isdir('new_folder')
True
Use for both files and directories:os.path.exists
>>> import os
>>> os.path.exists(os.path.join(os.getcwd(), 'new_folder', 'file.txt'))
False
Alternatively, you can use :pathlib
>>> from pathlib import Path
>>> Path('new_folder').is_dir()
True
>>> (Path.cwd() / 'new_folder' / 'file.txt').exists()
False
Your example works as expected, because doesn't take any arguments. The path you are interested in is saved in the pathlib.Path.exists object.Path
side_effect, you can just patch pathlib.Path.exists with your own function that does what you need:import pathlib
from unittest import TestCase
from unittest.mock import patch
def my_exists(self):
# self is the Path instance, str(Path) returns the path string
return str(self) == "a"
class MyTest(TestCase):
def test_exists(self):
with patch.object(pathlib.Path, 'exists', my_exists):
self.assertTrue(pathlib.Path("a").exists())
self.assertFalse(pathlib.Path("b").exists())
Yes, that is :Path.mkdir
pathlib.Path('/tmp/sub1/sub2').mkdir(parents=True, exist_ok=True)
From the docs:
If parents is true, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX
command).mkdir -pIf parents is false (the default), a missing parent raises
.FileNotFoundErrorIf exist_ok is false (the default),
is raised if the target directory already exists.FileExistsErrorIf exist_ok is true,
exceptions will be ignored (same behavior as the POSIXFileExistsErrorcommand), but only if the last path component is not an existing non-directory file.mkdir -p
If you pass in an argument with spaces in it, you need to surround it with quotation marks (), so it knows that you're not passing in multiple arguments. Also, as a general rule of thumb, don't include spaces in filenames."