or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-auditing.mddata-models.mddependency-sources.mdfix-resolution.mdindex.mdoutput-formats.mdvulnerability-services.md

fix-resolution.mddocs/

0

# Fix Resolution

1

2

Functionality for resolving and applying fixes to vulnerable dependencies. This module handles the process of determining appropriate fix versions and coordinating upgrades.

3

4

## Capabilities

5

6

### Fix Version Classes

7

8

Base classes representing fix versions and their resolution status.

9

10

```python { .api }

11

@dataclass(frozen=True)

12

class FixVersion:

13

"""

14

Represents an abstract dependency fix version.

15

16

This class cannot be constructed directly.

17

"""

18

19

dep: ResolvedDependency

20

"""

21

The dependency that needs to be fixed.

22

"""

23

24

def is_skipped(self) -> bool:

25

"""

26

Check whether the FixVersion was unable to be resolved.

27

28

Returns:

29

True if this is a SkippedFixVersion, False otherwise

30

"""

31

```

32

33

### Resolved Fix Version

34

35

Represents a successfully resolved fix version.

36

37

```python { .api }

38

@dataclass(frozen=True)

39

class ResolvedFixVersion(FixVersion):

40

"""

41

Represents a dependency fix version that was successfully resolved.

42

"""

43

44

version: Version

45

"""

46

The resolved fix version to upgrade to.

47

"""

48

```

49

50

### Skipped Fix Version

51

52

Represents a fix version that could not be resolved.

53

54

```python { .api }

55

@dataclass(frozen=True)

56

class SkippedFixVersion(FixVersion):

57

"""

58

Represents a dependency fix version that was unable to be resolved.

59

"""

60

61

skip_reason: str

62

"""

63

The reason why this fix version could not be resolved.

64

"""

65

```

66

67

### Exceptions

68

69

Exception classes related to fix resolution.

70

71

```python { .api }

72

class FixResolutionImpossible(Exception):

73

"""

74

Raised when resolve_fix_versions fails to find a fix version without known vulnerabilities.

75

"""

76

```

77

78

### Fix Resolution Functions

79

80

Functions for resolving fix versions from vulnerability results.

81

82

```python { .api }

83

def resolve_fix_versions(

84

dependency_results: Iterator[tuple[Dependency, list[VulnerabilityResult]]],

85

service: VulnerabilityService,

86

state: AuditState = AuditState(),

87

) -> Iterator[FixVersion]:

88

"""

89

Resolve fix versions for vulnerabilities.

90

91

Takes dependency audit results and determines appropriate fix versions

92

for each vulnerable dependency.

93

94

Parameters:

95

- dependency_results: Iterator of (dependency, vulnerabilities) tuples

96

- service: VulnerabilityService to query for additional information

97

- state: AuditState for progress tracking

98

99

Returns:

100

Iterator of FixVersion objects (either ResolvedFixVersion or SkippedFixVersion)

101

"""

102

```

103

104

## Usage Examples

105

106

### Basic Fix Resolution

107

108

```python

109

from pip_audit._fix import resolve_fix_versions

110

from pip_audit._audit import Auditor

111

from pip_audit._dependency_source import PipSource

112

from pip_audit._service import PyPIService

113

114

# Perform audit and resolve fixes

115

service = PyPIService()

116

source = PipSource()

117

auditor = Auditor(service=service)

118

119

# Get audit results

120

audit_results = auditor.audit(source)

121

122

# Resolve fix versions

123

fix_versions = resolve_fix_versions(audit_results, service)

124

125

for fix_version in fix_versions:

126

if fix_version.is_skipped():

127

print(f"Cannot fix {fix_version.dep.name}: {fix_version.skip_reason}")

128

else:

129

print(f"Fix {fix_version.dep.name} v{fix_version.dep.version} -> v{fix_version.version}")

130

```

131

132

### Applying Fixes

133

134

```python

135

from pip_audit._fix import resolve_fix_versions

136

from pip_audit._audit import Auditor

137

from pip_audit._dependency_source import RequirementSource

138

from pip_audit._service import PyPIService

139

140

# Setup components

141

service = PyPIService()

142

source = RequirementSource("requirements.txt")

143

auditor = Auditor(service=service)

144

145

# Get vulnerabilities and resolve fixes

146

audit_results = list(auditor.audit(source))

147

vulnerable_results = [(dep, vulns) for dep, vulns in audit_results if vulns]

148

149

if vulnerable_results:

150

print(f"Found {len(vulnerable_results)} packages with vulnerabilities")

151

152

# Resolve fix versions

153

fix_versions = list(resolve_fix_versions(iter(vulnerable_results), service))

154

155

# Apply fixes

156

for fix_version in fix_versions:

157

if not fix_version.is_skipped():

158

try:

159

source.fix(fix_version)

160

print(f"Fixed {fix_version.dep.name} -> v{fix_version.version}")

161

except Exception as e:

162

print(f"Failed to fix {fix_version.dep.name}: {e}")

163

else:

164

print(f"Skipped {fix_version.dep.name}: {fix_version.skip_reason}")

165

```

166

167

### Fix Resolution with State Tracking

168

169

```python

170

from pip_audit._fix import resolve_fix_versions

171

from pip_audit._audit import Auditor

172

from pip_audit._dependency_source import PyProjectSource

173

from pip_audit._service import OsvService

174

from pip_audit._state import AuditState

175

176

# Custom state handler for progress tracking

177

class ProgressTracker:

178

def update_state(self, message: str, logs: str | None = None):

179

print(f"Progress: {message}")

180

181

def initialize(self):

182

print("Starting fix resolution...")

183

184

def finalize(self):

185

print("Fix resolution completed.")

186

187

# Setup with state tracking

188

tracker = ProgressTracker()

189

state = AuditState(members=[tracker])

190

191

service = OsvService()

192

source = PyProjectSource("pyproject.toml")

193

auditor = Auditor(service=service)

194

195

# Perform audit with state tracking

196

state.initialize()

197

audit_results = auditor.audit(source)

198

199

# Resolve fixes with progress updates

200

fix_versions = resolve_fix_versions(audit_results, service, state=state)

201

202

resolved_count = 0

203

skipped_count = 0

204

205

for fix_version in fix_versions:

206

if fix_version.is_skipped():

207

skipped_count += 1

208

else:

209

resolved_count += 1

210

211

state.finalize()

212

print(f"Summary: {resolved_count} fixes resolved, {skipped_count} skipped")

213

```

214

215

### Advanced Fix Strategy

216

217

```python

218

from pip_audit._fix import resolve_fix_versions

219

from pip_audit._audit import Auditor

220

from pip_audit._dependency_source import PipSource

221

from pip_audit._service import PyPIService

222

from packaging.version import Version

223

224

def choose_best_fix_version(vulnerabilities, available_versions):

225

"""

226

Custom logic to choose the best fix version from available options.

227

"""

228

# Get all fix versions from vulnerabilities

229

all_fix_versions = set()

230

for vuln in vulnerabilities:

231

all_fix_versions.update(vuln.fix_versions)

232

233

# Filter to versions that fix all vulnerabilities

234

valid_fixes = []

235

for version in all_fix_versions:

236

fixes_all = True

237

for vuln in vulnerabilities:

238

if version not in vuln.fix_versions:

239

fixes_all = False

240

break

241

if fixes_all:

242

valid_fixes.append(version)

243

244

# Choose the minimum version that fixes all issues

245

return min(valid_fixes) if valid_fixes else None

246

247

# Example usage

248

service = PyPIService()

249

source = PipSource()

250

auditor = Auditor(service=service)

251

252

# Get audit results and apply custom fix resolution

253

for dependency, vulnerabilities in auditor.audit(source):

254

if vulnerabilities:

255

# Use custom logic to determine best fix

256

best_fix = choose_best_fix_version(vulnerabilities, [])

257

if best_fix:

258

print(f"Recommended fix for {dependency.name}: v{best_fix}")

259

else:

260

print(f"No suitable fix found for {dependency.name}")

261

```