Python Development Workflow for Humans.
—
Comprehensive exception hierarchy for handling various error conditions including file operations, command execution, and dependency resolution failures. Pipenv provides specific exception types for different error scenarios to enable proper error handling and debugging.
The foundation exception class for all pipenv-specific errors.
class PipenvException(Exception):
"""
Base exception class for all pipenv-specific errors.
All pipenv exceptions inherit from this class, allowing for
broad exception catching when needed.
"""Usage examples:
from pipenv.exceptions import PipenvException
try:
# Some pipenv operation
pass
except PipenvException as e:
print(f"Pipenv error occurred: {e}")
except Exception as e:
print(f"Unexpected error: {e}")Errors related to subprocess execution and command failures.
class PipenvCmdError(PipenvException):
"""
Command execution errors.
Raised when external commands (pip, python, etc.) fail
or return non-zero exit codes.
"""
class PipenvUsageError(PipenvException):
"""
Usage and argument errors.
Raised when commands are called with invalid arguments
or in inappropriate contexts.
"""Usage examples:
from pipenv.exceptions import PipenvCmdError, PipenvUsageError
import subprocess
def run_pip_command(args):
try:
result = subprocess.run(["pip"] + args, check=True, capture_output=True, text=True)
return result.stdout
except subprocess.CalledProcessError as e:
raise PipenvCmdError(f"Pip command failed: {e}")
def validate_python_version(version):
if not version or not version.replace(".", "").isdigit():
raise PipenvUsageError(f"Invalid Python version specification: {version}")
# Usage
try:
run_pip_command(["install", "nonexistent-package"])
except PipenvCmdError as e:
print(f"Command error: {e}")
try:
validate_python_version("invalid.version")
except PipenvUsageError as e:
print(f"Usage error: {e}")Errors related to file system operations and file handling.
class PipenvFileError(PipenvException):
"""
File operation errors.
Raised when file read/write operations fail or
when required files are corrupted or inaccessible.
"""
class PipfileNotFound(PipenvException):
"""
Pipfile not found error.
Raised when operations require a Pipfile but none
can be found in the current directory or parents.
"""
class LockfileNotFound(PipenvException):
"""
Lockfile not found error.
Raised when operations require a Pipfile.lock but
none exists or is inaccessible.
"""Usage examples:
from pipenv.exceptions import PipenvFileError, PipfileNotFound, LockfileNotFound
import json
from pathlib import Path
def load_pipfile(path="Pipfile"):
pipfile_path = Path(path)
if not pipfile_path.exists():
raise PipfileNotFound(f"Pipfile not found at {pipfile_path}")
try:
with open(pipfile_path, 'r') as f:
return f.read()
except (IOError, OSError) as e:
raise PipenvFileError(f"Cannot read Pipfile: {e}")
def load_lockfile(path="Pipfile.lock"):
lockfile_path = Path(path)
if not lockfile_path.exists():
raise LockfileNotFound(f"Pipfile.lock not found at {lockfile_path}")
try:
with open(lockfile_path, 'r') as f:
return json.load(f)
except (IOError, OSError, json.JSONDecodeError) as e:
raise PipenvFileError(f"Cannot read or parse Pipfile.lock: {e}")
# Usage
try:
pipfile_content = load_pipfile()
lockfile_data = load_lockfile()
except PipfileNotFound as e:
print(f"Pipfile missing: {e}")
except LockfileNotFound as e:
print(f"Lockfile missing: {e}")
except PipenvFileError as e:
print(f"File error: {e}")Errors related to virtual environment creation and management.
class VirtualenvCreationException(PipenvException):
"""
Virtual environment creation errors.
Raised when virtual environment creation fails due to
permissions, disk space, or other system issues.
"""Usage examples:
from pipenv.exceptions import VirtualenvCreationException
import subprocess
import os
def create_virtualenv(path, python_version=None):
"""Create virtual environment with error handling."""
cmd = ["python", "-m", "venv", path]
if python_version:
cmd[0] = f"python{python_version}"
try:
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
return path
except subprocess.CalledProcessError as e:
raise VirtualenvCreationException(
f"Failed to create virtual environment at {path}: {e.stderr}"
)
except FileNotFoundError:
python_exe = cmd[0]
raise VirtualenvCreationException(
f"Python executable not found: {python_exe}"
)
# Usage
try:
venv_path = create_virtualenv("/tmp/test_venv", "3.9")
print(f"Virtual environment created at: {venv_path}")
except VirtualenvCreationException as e:
print(f"Virtualenv creation failed: {e}")Errors related to package installation and removal.
class InstallError(PipenvException):
"""
Package installation errors.
Raised when package installation fails due to dependency
conflicts, network issues, or other installation problems.
"""
class UninstallError(PipenvException):
"""
Package uninstall errors.
Raised when package removal fails due to dependencies
or system restrictions.
"""Usage examples:
from pipenv.exceptions import InstallError, UninstallError
import subprocess
def install_package(package_name, environment_path=None):
"""Install package with error handling."""
cmd = ["pip", "install", package_name]
env = os.environ.copy()
if environment_path:
env["VIRTUAL_ENV"] = environment_path
cmd = [f"{environment_path}/bin/pip", "install", package_name]
try:
result = subprocess.run(cmd, check=True, capture_output=True, text=True, env=env)
return result.stdout
except subprocess.CalledProcessError as e:
raise InstallError(f"Failed to install {package_name}: {e.stderr}")
def uninstall_package(package_name, environment_path=None):
"""Uninstall package with error handling."""
cmd = ["pip", "uninstall", "-y", package_name]
env = os.environ.copy()
if environment_path:
env["VIRTUAL_ENV"] = environment_path
cmd = [f"{environment_path}/bin/pip", "uninstall", "-y", package_name]
try:
result = subprocess.run(cmd, check=True, capture_output=True, text=True, env=env)
return result.stdout
except subprocess.CalledProcessError as e:
raise UninstallError(f"Failed to uninstall {package_name}: {e.stderr}")
# Usage
try:
install_package("requests")
print("Package installed successfully")
except InstallError as e:
print(f"Installation failed: {e}")
try:
uninstall_package("requests")
print("Package uninstalled successfully")
except UninstallError as e:
print(f"Uninstall failed: {e}")Errors related to dependency resolution and version conflicts.
class ResolutionFailure(PipenvException):
"""
Dependency resolution errors.
Raised when pip resolver cannot find a compatible
set of package versions that satisfy all requirements.
"""
class DependencyConflict(PipenvException):
"""
Dependency conflict errors.
Raised when package dependencies have incompatible
version requirements that cannot be resolved.
"""
class RequirementError(PipenvException):
"""
Requirement specification errors.
Raised when package requirement specifications are
invalid or cannot be parsed.
"""
class JSONParseError(PipenvException):
"""
JSON parsing errors.
Raised when JSON files (lockfiles, etc.) cannot be
parsed due to syntax errors or corruption.
"""
class DeployException(PipenvException):
"""
Deployment errors.
Raised when deployment operations fail due to
missing requirements or environment issues.
"""
class PipenvOptionsError(PipenvException):
"""
Options validation errors.
Raised when command-line options or configuration
values are invalid or conflicting.
"""
class SystemUsageError(PipenvException):
"""
System usage errors.
Raised when pipenv is used inappropriately on the
system or in unsupported configurations.
"""
class SetupException(PipenvException):
"""
Setup and initialization errors.
Raised when project setup or initialization
operations fail.
"""
class VirtualenvException(PipenvException):
"""
Virtual environment errors.
Raised when virtual environment operations fail
beyond creation (activation, deactivation, etc.).
"""
class VirtualenvActivationException(VirtualenvException):
"""
Virtual environment activation errors.
Raised specifically when virtual environment
activation fails or is not supported.
"""Usage examples:
from pipenv.exceptions import ResolutionFailure
def resolve_dependencies(requirements):
"""Resolve package dependencies with error handling."""
# Simulate dependency resolution
conflicts = []
# Check for version conflicts
for req1 in requirements:
for req2 in requirements:
if req1 != req2 and req1.name == req2.name:
if req1.version != req2.version:
conflicts.append((req1, req2))
if conflicts:
conflict_msg = ", ".join([
f"{req1.name} {req1.version} vs {req2.version}"
for req1, req2 in conflicts
])
raise ResolutionFailure(f"Version conflicts detected: {conflict_msg}")
return requirements
# Example requirement class
class Requirement:
def __init__(self, name, version):
self.name = name
self.version = version
# Usage
try:
requirements = [
Requirement("requests", "2.25.0"),
Requirement("requests", "2.24.0"), # Conflict!
]
resolved = resolve_dependencies(requirements)
except ResolutionFailure as e:
print(f"Resolution failed: {e}")Common patterns for handling pipenv exceptions.
from pipenv.exceptions import (
PipenvException, PipenvCmdError, PipenvFileError,
PipfileNotFound, LockfileNotFound, VirtualenvCreationException,
InstallError, UninstallError, ResolutionFailure
)
def robust_pipenv_operation():
"""Example of comprehensive error handling."""
try:
# Attempt pipenv operations
load_pipfile()
create_virtualenv("/tmp/venv")
install_package("requests")
except PipfileNotFound as e:
print(f"Setup required: {e}")
# Could create new Pipfile here
except LockfileNotFound as e:
print(f"Lock file missing: {e}")
# Could generate lock file here
except VirtualenvCreationException as e:
print(f"Environment setup failed: {e}")
# Could try alternative environment creation
except (InstallError, UninstallError) as e:
print(f"Package operation failed: {e}")
# Could retry with different options
except ResolutionFailure as e:
print(f"Dependency conflict: {e}")
# Could suggest resolution strategies
except PipenvCmdError as e:
print(f"Command failed: {e}")
# Could provide command-specific help
except PipenvFileError as e:
print(f"File operation failed: {e}")
# Could check permissions or disk space
except PipenvException as e:
print(f"General pipenv error: {e}")
# Catch-all for other pipenv errors
except Exception as e:
print(f"Unexpected error: {e}")
# Handle non-pipenv errorsimport time
from pipenv.exceptions import InstallError, PipenvCmdError
def install_with_retry(package_name, max_retries=3):
"""Install package with retry logic."""
for attempt in range(max_retries):
try:
return install_package(package_name)
except (InstallError, PipenvCmdError) as e:
if attempt == max_retries - 1:
raise e
print(f"Install attempt {attempt + 1} failed: {e}")
print(f"Retrying in {2 ** attempt} seconds...")
time.sleep(2 ** attempt)
raise InstallError(f"Failed to install {package_name} after {max_retries} attempts")from pipenv.exceptions import PipenvException
import logging
class PipenvErrorHandler:
"""Context-aware error handler for pipenv operations."""
def __init__(self, context=""):
self.context = context
self.logger = logging.getLogger(__name__)
def handle_error(self, error, operation=""):
"""Handle pipenv errors with context."""
full_context = f"{self.context} - {operation}" if operation else self.context
if isinstance(error, PipfileNotFound):
self.logger.error(f"{full_context}: Pipfile not found. Run 'pipenv install' to initialize.")
elif isinstance(error, VirtualenvCreationException):
self.logger.error(f"{full_context}: Virtual environment creation failed. Check Python installation.")
elif isinstance(error, ResolutionFailure):
self.logger.error(f"{full_context}: Dependency resolution failed. Check version requirements.")
elif isinstance(error, PipenvException):
self.logger.error(f"{full_context}: Pipenv error - {error}")
else:
self.logger.error(f"{full_context}: Unexpected error - {error}")
# Usage
handler = PipenvErrorHandler("Project Setup")
try:
# Pipenv operations
pass
except Exception as e:
handler.handle_error(e, "Installing dependencies")You can extend pipenv exceptions for application-specific error handling.
from pipenv.exceptions import PipenvException, InstallError
class ProjectSetupError(PipenvException):
"""Custom exception for project setup failures."""
pass
class DependencyConflictError(ResolutionFailure):
"""Enhanced dependency conflict error with resolution suggestions."""
def __init__(self, message, conflicts=None, suggestions=None):
super().__init__(message)
self.conflicts = conflicts or []
self.suggestions = suggestions or []
def get_resolution_help(self):
"""Get suggested resolutions for conflicts."""
if not self.suggestions:
return "No automatic resolution suggestions available."
help_text = "Suggested resolutions:\n"
for i, suggestion in enumerate(self.suggestions, 1):
help_text += f"{i}. {suggestion}\n"
return help_text
# Usage
try:
# Some operation that might conflict
pass
except ResolutionFailure as e:
# Convert to enhanced exception
enhanced_error = DependencyConflictError(
str(e),
conflicts=["requests 2.25.0 vs 2.24.0"],
suggestions=["Update all packages to compatible versions", "Use dependency_links for specific versions"]
)
print(enhanced_error.get_resolution_help())Install with Tessl CLI
npx tessl i tessl/pypi-pipenv