CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-furl

URL manipulation made simple.

65

1.58x
Overview
Eval results
Files

path.mddocs/

Path Manipulation

The Path class provides comprehensive URL path manipulation with segment-based access, automatic percent-encoding/decoding, and support for both absolute and relative paths. Path objects handle the complexities of URL path formatting while providing an intuitive interface.

Capabilities

Path Construction and Loading

Create and load path objects from strings with automatic segment parsing and encoding handling.

class Path:
    def __init__(self, path='', force_absolute=lambda _: False, strict=False):
        """
        Initialize a Path object.
        
        Args:
            path (str): Path string to parse
            force_absolute (callable): Function to determine if path should be absolute
            strict (bool): Enable strict parsing mode
        """
        
    def load(self, path):
        """
        Load a path string into the Path object.
        
        Args:
            path (str): Path string to parse and load
            
        Returns:
            Path: Self for method chaining
        """

Usage:

from furl import Path

# Create from string
p = Path('/api/v1/users')
print(p.segments)  # ['api', 'v1', 'users']

# Create empty path
p = Path()
p.load('/new/path/here')
print(p.segments)  # ['new', 'path', 'here']

# Relative path
rel_path = Path('relative/path')
print(rel_path.isabsolute)  # False

Segment Manipulation

Direct manipulation of path segments with automatic encoding and path reconstruction.

class Path:
    @property
    def segments(self) -> list[str]:
        """
        List of path segments (percent-decoded).
        Segments are automatically decoded and can be manipulated directly.
        """
        
    @segments.setter
    def segments(self, segments: list[str]):
        """Set path segments list"""
        
    def add(self, path):
        """
        Add path segments to the existing path.
        
        Args:
            path (str): Path string with segments to add
            
        Returns:
            Path: Self for method chaining
        """
        
    def set(self, path):
        """
        Set the path, replacing all existing segments.
        
        Args:
            path (str): New path string
            
        Returns:
            Path: Self for method chaining
        """
        
    def remove(self, path):
        """
        Remove path segments.
        
        Args:
            path (str|bool): Path segments to remove, or True to remove all
            
        Returns:
            Path: Self for method chaining
        """

Usage:

p = Path('/api/v1')

# Direct segment manipulation
p.segments.append('users')
p.segments.append('123')
print(str(p))  # '/api/v1/users/123'

# Add path segments
p.add('profile')
print(str(p))  # '/api/v1/users/123/profile'

# Set new path (replaces existing)
p.set('/different/path')
print(p.segments)  # ['different', 'path']

# Remove segments
p.remove('path')
print(p.segments)  # ['different']

# Remove all segments
p.remove(True)
print(str(p))  # '/'

Path Properties

Access path characteristics and metadata.

class Path:
    @property
    def isabsolute(self) -> bool:
        """
        Boolean indicating if path is absolute (starts with /).
        For URL paths with netloc, this becomes read-only True.
        """
        
    @isabsolute.setter
    def isabsolute(self, isabsolute: bool):
        """Set absolute path flag (may be read-only in URL context)"""
        
    @property
    def isdir(self) -> bool:
        """
        Boolean indicating if path represents a directory.
        True if path ends with empty segment (trailing slash).
        """
        
    @property
    def isfile(self) -> bool:
        """
        Boolean indicating if path represents a file.
        True if path doesn't end with empty segment (no trailing slash).
        """

Usage:

# Directory path (ends with /)
dir_path = Path('/api/v1/')
print(dir_path.isdir)   # True
print(dir_path.isfile)  # False
print(dir_path.segments)  # ['api', 'v1', '']

# File path (no trailing /)
file_path = Path('/api/v1/users')
print(file_path.isdir)   # False
print(file_path.isfile)  # True

# Absolute vs relative
abs_path = Path('/absolute/path')
print(abs_path.isabsolute)  # True

rel_path = Path('relative/path')
print(rel_path.isabsolute)  # False

# Make relative path absolute
rel_path.isabsolute = True
print(str(rel_path))  # '/relative/path'

Path Normalization

Normalize paths by resolving relative references and cleaning segments.

class Path:
    def normalize(self):
        """
        Normalize the path by resolving . and .. segments.
        
        Returns:
            Path: Self for method chaining
        """

Usage:

# Path with relative references
messy_path = Path('/api/../api/v1/./users/../users')
print(messy_path.segments)  # ['api', '..', 'api', 'v1', '.', 'users', '..', 'users']

messy_path.normalize()
print(messy_path.segments)  # ['api', 'v1', 'users']
print(str(messy_path))     # '/api/v1/users'

Path String Operations

Convert paths to strings and perform path operations.

class Path:
    def __str__(self) -> str:
        """
        Convert path to string with proper encoding.
        
        Returns:
            str: Percent-encoded path string
        """
        
    def __truediv__(self, path) -> 'Path':
        """
        Path division operator (/) for joining paths.
        
        Args:
            path (str): Path segment to join
            
        Returns:
            Path: New Path object with joined path
        """
        
    def __eq__(self, other) -> bool:
        """Check path equality"""
        
    def __bool__(self) -> bool:
        """Boolean evaluation (True if path has segments)"""
        
    def asdict(self) -> dict:
        """
        Convert path to dictionary representation.
        
        Returns:
            dict: Dictionary with path metadata
        """

Usage:

base_path = Path('/api/v1')

# String conversion with encoding
path_with_spaces = Path('/path with spaces/and special chars!')
print(str(path_with_spaces))  # '/path%20with%20spaces/and%20special%20chars!'

# Path joining with / operator
full_path = base_path / 'users' / '123'
print(str(full_path))  # '/api/v1/users/123'

# Path comparison
path1 = Path('/api/v1')
path2 = Path('/api/v1')
print(path1 == path2)  # True

# Boolean evaluation
empty_path = Path()
print(bool(empty_path))  # False

non_empty = Path('/something')
print(bool(non_empty))  # True

# Dictionary representation
path_dict = base_path.asdict()
print(path_dict)  # Contains path metadata

Encoding and Unicode Support

Paths automatically handle percent-encoding and Unicode characters:

# Unicode characters in paths
unicode_path = Path('/пользователи/123')
print(str(unicode_path))  # Properly encoded

# Percent-encoded input
encoded_path = Path('/users%20with%20spaces')
print(encoded_path.segments)  # ['users with spaces'] - automatically decoded

# Special characters
special_path = Path('/special/chars/^`<>[]"#/?')
print(str(special_path))  # '/special/chars/%5E%60%3C%3E%5B%5D%22%23%2F%3F'

URL Context Behavior

When a Path is part of a furl object with a netloc (host), certain behaviors change:

from furl import furl

# Path in URL context
f = furl('http://example.com/path')
print(f.path.isabsolute)  # True (required for URLs with netloc)

# Attempting to make URL path relative raises error
try:
    f.path.isabsolute = False
except AttributeError as e:
    print("Cannot make URL path relative when netloc is present")

# Fragment paths don't have this restriction
f.fragment.path.isabsolute = False  # This works fine

Error Handling

Path objects handle various error conditions:

  • Invalid characters: Special characters are automatically encoded
  • Relative references: .. and . segments can be normalized
  • Empty segments: Handled correctly for directory vs file distinction
  • Unicode support: Proper encoding/decoding of international characters
  • Strict mode: Additional validation when strict=True

Install with Tessl CLI

npx tessl i tessl/pypi-furl

docs

core-url.md

fragment.md

index.md

path.md

query.md

utilities.md

tile.json