Skip to content

pathlib

Path() - Create Path objects from strings.

Path properties - name, stem, suffix, parent, parts.

Path checks - exists(), is_file(), is_dir(), is_absolute().

Path manipulation - with_name(), with_suffix(), with_stem().

Path I/O - read_text(), write_text(), read_bytes(), write_bytes().

Directory operations - mkdir(), rmdir(), iterdir().

Path resolution - resolve(), absolute().

Globbing - glob(), rglob().

Basic: Create Path from string.

def test_path_basic(self):
    """Basic: Create Path from string."""
    p = Path('/home/user')
    assert isinstance(p, Path)
    assert str(p) == '/home/user'

Verification: ✅ Tested in CI

Feature: Create Path from multiple parts.

def test_path_from_parts(self):
    """Feature: Create Path from multiple parts."""
    p = Path('home', 'user', 'documents')
    if sys.platform == 'win32':
        assert str(p) == 'home\\user\\documents'
    else:
        assert str(p) == 'home/user/documents'

Verification: ✅ Tested in CI

Feature: Use / operator to join paths.

def test_path_slash_operator(self):
    """Feature: Use / operator to join paths."""
    p = Path('/home') / 'user' / 'documents'
    if sys.platform == 'win32':
        assert 'user' in str(p) and 'documents' in str(p)
    else:
        assert str(p) == '/home/user/documents'

Verification: ✅ Tested in CI

Feature: Current directory as Path('.').

def test_path_current_directory(self):
    """Feature: Current directory as Path('.')."""
    p = Path('.')
    assert isinstance(p, Path)
    assert p.exists()

Verification: ✅ Tested in CI

Edge: Empty string creates current directory path.

def test_path_empty_string(self):
    """Edge: Empty string creates current directory path."""
    p = Path('')
    assert str(p) == '.'

Verification: ✅ Tested in CI

Basic: Get filename with name property.

def test_path_name(self):
    """Basic: Get filename with name property."""
    p = Path('/home/user/document.txt')
    assert p.name == 'document.txt'

Verification: ✅ Tested in CI

Feature: Get filename without extension.

def test_path_stem(self):
    """Feature: Get filename without extension."""
    p = Path('/home/user/document.txt')
    assert p.stem == 'document'

Verification: ✅ Tested in CI

Feature: Get file extension.

def test_path_suffix(self):
    """Feature: Get file extension."""
    p = Path('/home/user/document.txt')
    assert p.suffix == '.txt'

Verification: ✅ Tested in CI

Feature: Get all extensions for compound suffixes.

def test_path_suffixes(self):
    """Feature: Get all extensions for compound suffixes."""
    p = Path('/home/user/archive.tar.gz')
    assert p.suffixes == ['.tar', '.gz']

Verification: ✅ Tested in CI

Feature: Get parent directory.

def test_path_parent(self):
    """Feature: Get parent directory."""
    p = Path('/home/user/documents/file.txt')
    assert str(p.parent) == '/home/user/documents'

Verification: ✅ Tested in CI

Feature: Get all parent directories.

def test_path_parents(self):
    """Feature: Get all parent directories."""
    p = Path('/home/user/documents')
    parents = list(p.parents)
    assert '/home/user' in str(parents[0])
    assert '/home' in str(parents[1])

Verification: ✅ Tested in CI

Property: Path split into parts.

def test_path_parts(self):
    """Property: Path split into parts."""
    p = Path('/home/user/documents')
    if sys.platform == 'win32':
        assert 'user' in p.parts and 'documents' in p.parts
    else:
        assert p.parts == ('/', 'home', 'user', 'documents')

Verification: ✅ Tested in CI

Edge: Files without extension have empty suffix.

def test_path_no_suffix(self):
    """Edge: Files without extension have empty suffix."""
    p = Path('/home/user/README')
    assert p.suffix == ''
    assert p.stem == 'README'

Verification: ✅ Tested in CI

Edge: Hidden files (starting with .) handled correctly.

def test_path_hidden_file(self):
    """Edge: Hidden files (starting with .) handled correctly."""
    p = Path('/home/user/.bashrc')
    assert p.name == '.bashrc'
    assert p.stem == '.bashrc'
    assert p.suffix == ''

Verification: ✅ Tested in CI

Basic: Path.exists() returns True for existing file.

def test_exists_true(self, tmp_path):
    """Basic: Path.exists() returns True for existing file."""
    file = tmp_path / 'test.txt'
    file.write_text('data')
    assert file.exists() is True

Verification: ✅ Tested in CI

Basic: Path.exists() returns False for non-existent path.

def test_exists_false(self):
    """Basic: Path.exists() returns False for non-existent path."""
    p = Path('/nonexistent/path')
    assert p.exists() is False

Verification: ✅ Tested in CI

Feature: is_file() returns True for files.

def test_is_file(self, tmp_path):
    """Feature: is_file() returns True for files."""
    file = tmp_path / 'test.txt'
    file.write_text('data')
    assert file.is_file() is True
    assert tmp_path.is_file() is False

Verification: ✅ Tested in CI

Feature: is_dir() returns True for directories.

def test_is_dir(self, tmp_path):
    """Feature: is_dir() returns True for directories."""
    assert tmp_path.is_dir() is True
    file = tmp_path / 'test.txt'
    file.write_text('data')
    assert file.is_dir() is False

Verification: ✅ Tested in CI

Feature: is_absolute() checks for absolute paths.

def test_is_absolute(self):
    """Feature: is_absolute() checks for absolute paths."""
    assert Path('/home/user').is_absolute() is True
    assert Path('relative/path').is_absolute() is False

Verification: ✅ Tested in CI

def test_is_symlink(self, tmp_path):
    """Feature: is_symlink() detects symbolic links."""
    if sys.platform == 'win32':
        pytest.skip('Symlinks require admin on Windows')
    target = tmp_path / 'target.txt'
    target.write_text('data')
    link = tmp_path / 'link.txt'
    link.symlink_to(target)
    assert link.is_symlink() is True
    assert target.is_symlink() is False

Verification: ✅ Tested in CI

Basic: Replace filename with with_name().

def test_with_name(self):
    """Basic: Replace filename with with_name()."""
    p = Path('/home/user/old.txt')
    new_p = p.with_name('new.txt')
    assert str(new_p) == '/home/user/new.txt'

Verification: ✅ Tested in CI

Feature: Change file extension with with_suffix().

def test_with_suffix(self):
    """Feature: Change file extension with with_suffix()."""
    p = Path('/home/user/document.txt')
    new_p = p.with_suffix('.md')
    assert str(new_p) == '/home/user/document.md'

Verification: ✅ Tested in CI

Feature: Change filename without extension (Python 3.9+).

def test_with_stem(self):
    """Feature: Change filename without extension (Python 3.9+)."""
    if not hasattr(Path, 'with_stem'):
        pytest.skip('with_stem() requires Python 3.9+')
    p = Path('/home/user/old.txt')
    new_p = p.with_stem('new')
    assert str(new_p) == '/home/user/new.txt'

Verification: ✅ Tested in CI

Edge: Remove suffix with empty string.

def test_with_suffix_remove(self):
    """Edge: Remove suffix with empty string."""
    p = Path('/home/user/document.txt')
    new_p = p.with_suffix('')
    assert str(new_p) == '/home/user/document'

Verification: ✅ Tested in CI

Edge: with_suffix() only changes last extension.

def test_with_suffix_compound(self):
    """Edge: with_suffix() only changes last extension."""
    p = Path('/home/user/archive.tar.gz')
    new_p = p.with_suffix('.bz2')
    assert str(new_p) == '/home/user/archive.tar.bz2'

Verification: ✅ Tested in CI

Basic: Write text to file with write_text().

def test_write_text_basic(self, tmp_path):
    """Basic: Write text to file with write_text()."""
    file = tmp_path / 'test.txt'
    file.write_text('Hello, World!')
    assert file.read_text() == 'Hello, World!'

Verification: ✅ Tested in CI

Basic: Read text from file with read_text().

def test_read_text_basic(self, tmp_path):
    """Basic: Read text from file with read_text()."""
    file = tmp_path / 'test.txt'
    file.write_text('Content')
    content = file.read_text()
    assert content == 'Content'

Verification: ✅ Tested in CI

Feature: Write binary data with write_bytes().

def test_write_bytes(self, tmp_path):
    """Feature: Write binary data with write_bytes()."""
    file = tmp_path / 'data.bin'
    data = b'\x00\x01\x02\x03'
    file.write_bytes(data)
    assert file.read_bytes() == data

Verification: ✅ Tested in CI

Feature: Read binary data with read_bytes().

def test_read_bytes(self, tmp_path):
    """Feature: Read binary data with read_bytes()."""
    file = tmp_path / 'data.bin'
    data = b'binary data'
    file.write_bytes(data)
    assert file.read_bytes() == data

Verification: ✅ Tested in CI

Feature: Specify encoding when writing text.

def test_write_text_encoding(self, tmp_path):
    """Feature: Specify encoding when writing text."""
    file = tmp_path / 'utf8.txt'
    file.write_text('Hello 世界', encoding='utf-8')
    content = file.read_text(encoding='utf-8')
    assert content == 'Hello 世界'

Verification: ✅ Tested in CI

Edge: write_text() overwrites existing content.

def test_write_text_overwrites(self, tmp_path):
    """Edge: write_text() overwrites existing content."""
    file = tmp_path / 'test.txt'
    file.write_text('first')
    file.write_text('second')
    assert file.read_text() == 'second'

Verification: ✅ Tested in CI

Basic: Create directory with mkdir().

def test_mkdir_basic(self, tmp_path):
    """Basic: Create directory with mkdir()."""
    new_dir = tmp_path / 'new_directory'
    new_dir.mkdir()
    assert new_dir.exists()
    assert new_dir.is_dir()

Verification: ✅ Tested in CI

Feature: Create parent directories with parents=True.

def test_mkdir_parents(self, tmp_path):
    """Feature: Create parent directories with parents=True."""
    nested = tmp_path / 'a' / 'b' / 'c'
    nested.mkdir(parents=True)
    assert nested.exists()
    assert (tmp_path / 'a').exists()
    assert (tmp_path / 'a' / 'b').exists()

Verification: ✅ Tested in CI

Feature: mkdir() with exist_ok=True doesn't raise error.

def test_mkdir_exist_ok(self, tmp_path):
    """Feature: mkdir() with exist_ok=True doesn't raise error."""
    new_dir = tmp_path / 'dir'
    new_dir.mkdir()
    new_dir.mkdir(exist_ok=True)

Verification: ✅ Tested in CI

Feature: Remove empty directory with rmdir().

def test_rmdir(self, tmp_path):
    """Feature: Remove empty directory with rmdir()."""
    new_dir = tmp_path / 'to_remove'
    new_dir.mkdir()
    assert new_dir.exists()
    new_dir.rmdir()
    assert not new_dir.exists()

Verification: ✅ Tested in CI

Feature: Iterate directory contents with iterdir().

def test_iterdir(self, tmp_path):
    """Feature: Iterate directory contents with iterdir()."""
    (tmp_path / 'file1.txt').write_text('a')
    (tmp_path / 'file2.txt').write_text('b')
    (tmp_path / 'subdir').mkdir()
    items = list(tmp_path.iterdir())
    assert len(items) == 3
    names = [p.name for p in items]
    assert 'file1.txt' in names
    assert 'file2.txt' in names
    assert 'subdir' in names

Verification: ✅ Tested in CI

Error: mkdir() without parents raises if parent missing.

def test_mkdir_parents_false_raises(self, tmp_path):
    """Error: mkdir() without parents raises if parent missing."""
    nested = tmp_path / 'a' / 'b' / 'c'
    with pytest.raises(FileNotFoundError):
        nested.mkdir(parents=False)

Verification: ✅ Tested in CI

Error: mkdir() on existing directory raises FileExistsError.

def test_mkdir_exists_raises(self, tmp_path):
    """Error: mkdir() on existing directory raises FileExistsError."""
    new_dir = tmp_path / 'dir'
    new_dir.mkdir()
    with pytest.raises(FileExistsError):
        new_dir.mkdir(exist_ok=False)

Verification: ✅ Tested in CI

Basic: Resolve relative path to absolute.

def test_resolve_basic(self, tmp_path):
    """Basic: Resolve relative path to absolute."""
    file = tmp_path / 'test.txt'
    file.write_text('data')
    relative = Path(file.name)
    resolved = (tmp_path / relative).resolve()
    assert resolved.is_absolute()

Verification: ✅ Tested in CI

Feature: Convert to absolute path with absolute().

def test_absolute(self, tmp_path):
    """Feature: Convert to absolute path with absolute()."""
    file = tmp_path / 'test.txt'
    file.write_text('data')
    absolute = file.absolute()
    assert absolute.is_absolute()

Verification: ✅ Tested in CI

def test_resolve_symlinks(self, tmp_path):
    """Feature: resolve() follows symbolic links."""
    if sys.platform == 'win32':
        pytest.skip('Symlinks require admin on Windows')
    target = tmp_path / 'target.txt'
    target.write_text('data')
    link = tmp_path / 'link.txt'
    link.symlink_to(target)
    resolved = link.resolve()
    assert resolved == target.resolve()

Verification: ✅ Tested in CI

Basic: Find files matching pattern with glob().

def test_glob_basic(self, tmp_path):
    """Basic: Find files matching pattern with glob()."""
    (tmp_path / 'file1.txt').write_text('a')
    (tmp_path / 'file2.txt').write_text('b')
    (tmp_path / 'file3.md').write_text('c')
    txt_files = list(tmp_path.glob('*.txt'))
    assert len(txt_files) == 2
    names = [p.name for p in txt_files]
    assert 'file1.txt' in names
    assert 'file2.txt' in names

Verification: ✅ Tested in CI

Feature: Recursive glob with ** pattern.

def test_glob_recursive(self, tmp_path):
    """Feature: Recursive glob with ** pattern."""
    (tmp_path / 'file.txt').write_text('a')
    subdir = tmp_path / 'subdir'
    subdir.mkdir()
    (subdir / 'nested.txt').write_text('b')
    all_txt = list(tmp_path.glob('**/*.txt'))
    assert len(all_txt) == 2

Verification: ✅ Tested in CI

Feature: Recursive glob with rglob().

def test_rglob(self, tmp_path):
    """Feature: Recursive glob with rglob()."""
    (tmp_path / 'file.txt').write_text('a')
    subdir = tmp_path / 'subdir'
    subdir.mkdir()
    (subdir / 'nested.txt').write_text('b')
    all_txt = list(tmp_path.rglob('*.txt'))
    assert len(all_txt) == 2

Verification: ✅ Tested in CI

Edge: glob() returns empty for no matches.

def test_glob_no_matches(self, tmp_path):
    """Edge: glob() returns empty for no matches."""
    matches = list(tmp_path.glob('*.nonexistent'))
    assert matches == []

Verification: ✅ Tested in CI

Feature: Use ? wildcard in glob patterns.

def test_glob_question_mark(self, tmp_path):
    """Feature: Use ? wildcard in glob patterns."""
    (tmp_path / 'file1.txt').write_text('a')
    (tmp_path / 'file2.txt').write_text('b')
    (tmp_path / 'file10.txt').write_text('c')
    matches = list(tmp_path.glob('file?.txt'))
    assert len(matches) == 2

Verification: ✅ Tested in CI