or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mddata-models.mdenvironment-detection.mdindex.mdoutput-rendering.mdpackage-discovery.mdvalidation.mdwarning-system.md

warning-system.mddocs/

0

# Warning System

1

2

Configurable warning and error reporting system with different verbosity levels and output control for handling dependency conflicts, validation issues, and other diagnostic information.

3

4

## Capabilities

5

6

### Warning Types

7

8

Enumeration defining different warning behavior levels.

9

10

```python { .api }

11

WarningType = Enum("WarningType", ["SILENCE", "SUPPRESS", "FAIL"])

12

```

13

14

The three warning levels control output and exit behavior:

15

16

- **SILENCE**: No warning output, always return exit code 0

17

- **SUPPRESS**: Print warnings to stderr, but return exit code 0

18

- **FAIL**: Print warnings to stderr and return exit code 1 if any warnings occurred

19

20

### WarningPrinter Class

21

22

Main class for managing warning output and tracking warning state.

23

24

```python { .api }

25

class WarningPrinter:

26

"""Non-thread safe class that handles printing warning logic."""

27

28

def __init__(self, warning_type: WarningType = WarningType.SUPPRESS) -> None:

29

"""

30

Initialize warning printer with specified behavior.

31

32

Parameters:

33

- warning_type: Controls warning output and exit code behavior

34

"""

35

36

@property

37

def warning_type(self) -> WarningType:

38

"""Current warning type setting."""

39

40

@warning_type.setter

41

def warning_type(self, new_warning_type: WarningType) -> None:

42

"""Update warning type setting."""

43

44

def should_warn(self) -> bool:

45

"""

46

Check if warnings should be printed.

47

48

Returns:

49

False for SILENCE, True for SUPPRESS and FAIL

50

"""

51

52

def has_warned_with_failure(self) -> bool:

53

"""

54

Check if warnings were printed with failure setting.

55

56

Returns:

57

True if warnings occurred and warning_type is FAIL

58

"""

59

60

def print_single_line(self, line: str) -> None:

61

"""

62

Print a single warning line to stderr.

63

64

Marks that a warning has occurred for exit code determination.

65

66

Parameters:

67

- line: Warning message to print

68

"""

69

70

def print_multi_line(

71

self,

72

summary: str,

73

print_func: Callable[[], None],

74

ignore_fail: bool = False

75

) -> None:

76

"""

77

Print a multi-line warning with custom formatting.

78

79

Parameters:

80

- summary: Warning summary/title

81

- print_func: Callback that prints the detailed warning content

82

- ignore_fail: If True, don't mark as failure warning

83

"""

84

```

85

86

### Global Warning Printer

87

88

Function to access the global warning printer instance.

89

90

```python { .api }

91

def get_warning_printer() -> WarningPrinter:

92

"""

93

Get the global warning printer instance.

94

95

Returns:

96

Shared WarningPrinter instance used throughout pipdeptree

97

"""

98

```

99

100

## Usage Examples

101

102

### Basic Warning Configuration

103

104

```python

105

from pipdeptree._warning import get_warning_printer, WarningType

106

107

# Get global warning printer

108

warning_printer = get_warning_printer()

109

110

# Configure warning behavior

111

warning_printer.warning_type = WarningType.FAIL

112

113

# Check configuration

114

if warning_printer.should_warn():

115

print("Warnings will be printed")

116

117

if warning_printer.warning_type == WarningType.FAIL:

118

print("Warnings will cause exit code 1")

119

```

120

121

### Single Line Warnings

122

123

```python

124

from pipdeptree._warning import get_warning_printer

125

126

warning_printer = get_warning_printer()

127

128

# Print simple warning

129

warning_printer.print_single_line("Package version conflict detected")

130

131

# Check if this was a failure warning

132

if warning_printer.has_warned_with_failure():

133

print("This warning should cause non-zero exit code")

134

```

135

136

### Multi-Line Warning Output

137

138

```python

139

from pipdeptree._warning import get_warning_printer

140

141

def print_detailed_conflicts():

142

"""Function that prints detailed conflict information."""

143

print("* package-a==1.0")

144

print(" - dependency-x [required: >=2.0, installed: 1.5]")

145

print("* package-b==2.0")

146

print(" - dependency-y [required: <1.0, installed: 1.2]")

147

148

warning_printer = get_warning_printer()

149

150

# Print multi-line warning with custom content

151

warning_printer.print_multi_line(

152

summary="Conflicting dependencies found",

153

print_func=print_detailed_conflicts

154

)

155

156

# Output:

157

# Warning!!! Conflicting dependencies found:

158

# * package-a==1.0

159

# - dependency-x [required: >=2.0, installed: 1.5]

160

# * package-b==2.0

161

# - dependency-y [required: <1.0, installed: 1.2]

162

# ------------------------------------------------------------------------

163

```

164

165

### Integration with CLI

166

167

```python

168

from pipdeptree._cli import get_options

169

from pipdeptree._warning import get_warning_printer, WarningType

170

171

# Parse CLI warning option

172

options = get_options(['--warn', 'fail'])

173

174

# Configure warning printer based on CLI option

175

warning_printer = get_warning_printer()

176

warning_printer.warning_type = options.warn

177

178

# Use throughout application

179

if warning_printer.should_warn():

180

warning_printer.print_single_line("Validation issue detected")

181

182

# Determine exit code

183

exit_code = 1 if warning_printer.has_warned_with_failure() else 0

184

```

185

186

### Integration with Validation

187

188

```python

189

from pipdeptree._validate import validate, conflicting_deps

190

from pipdeptree._warning import get_warning_printer

191

192

# Configure warnings

193

warning_printer = get_warning_printer()

194

warning_printer.warning_type = WarningType.SUPPRESS

195

196

# Validation uses warning printer internally

197

validate(dependency_tree) # Prints warnings if conflicts found

198

199

# Check if validation found issues

200

if warning_printer.has_warned_with_failure():

201

print("Validation failed")

202

203

# Manual conflict checking with warning integration

204

conflicts = conflicting_deps(dependency_tree)

205

if conflicts and warning_printer.should_warn():

206

warning_printer.print_multi_line(

207

"Dependency conflicts detected",

208

lambda: render_conflicts_text(conflicts)

209

)

210

```

211

212

## Warning Output Format

213

214

### Single Line Format

215

216

Simple warning messages printed directly to stderr:

217

218

```

219

Package pattern 'nonexistent*' not found in dependency tree

220

```

221

222

### Multi-Line Format

223

224

Structured warnings with header, content, and footer:

225

226

```

227

Warning!!! Conflicting dependencies found:

228

* Django==3.0.0

229

- requests [required: >=2.25.0, installed: 2.20.0]

230

* mypackage==1.0.0

231

- urllib3 [required: >=1.26, installed: 1.25.11]

232

------------------------------------------------------------------------

233

```

234

235

### Informational Messages

236

237

Some multi-line warnings can be marked as informational:

238

239

```

240

Warning!!! Invalid requirement strings found:

241

mypackage

242

Skipping "invalid>=requirement string"

243

NOTE: This warning isn't a failure warning.

244

------------------------------------------------------------------------

245

```

246

247

## Integration Points

248

249

### CLI Warning Control

250

251

The warning system integrates with CLI argument parsing:

252

253

```bash

254

# Suppress warnings but show them

255

pipdeptree --warn suppress

256

257

# Silence all warnings

258

pipdeptree --warn silence

259

260

# Treat warnings as failures

261

pipdeptree --warn fail

262

```

263

264

### Validation Integration

265

266

Validation functions automatically use the warning system:

267

268

- **Conflict detection**: Prints conflicts when `should_warn()` returns True

269

- **Cycle detection**: Prints circular dependencies when enabled

270

- **Invalid requirements**: Reports malformed requirement strings

271

272

### Text Output Integration

273

274

The warning system only activates for text output modes:

275

276

```python

277

# Warnings disabled for structured output formats

278

is_text_output = not any([options.json, options.json_tree, options.output_format])

279

if not is_text_output:

280

options.warn = WarningType.SILENCE

281

```

282

283

### Exit Code Determination

284

285

The warning system controls application exit codes:

286

287

```python

288

def _determine_return_code(warning_printer: WarningPrinter) -> int:

289

"""Determine exit code based on warning state."""

290

return 1 if warning_printer.has_warned_with_failure() else 0

291

```

292

293

## Thread Safety

294

295

The `WarningPrinter` class is explicitly **not thread-safe**:

296

297

- Maintains internal state (`_has_warned` flag)

298

- Not designed for concurrent access

299

- Global instance should be accessed from single thread

300

301

For multi-threaded applications, create separate `WarningPrinter` instances per thread or implement external synchronization.

302

303

## State Management

304

305

The warning printer tracks warning state internally:

306

307

- **Initial state**: `_has_warned = False`

308

- **After warning**: `_has_warned = True` (for failure warnings)

309

- **Reset**: No built-in reset mechanism (create new instance if needed)

310

311

This state tracking enables proper exit code determination and failure detection throughout the application lifecycle.