or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

environment-reporting.mdimport-tracking.mdindex.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Utility functions for package version detection, version comparison, and environment detection. These functions provide the building blocks used by the reporting system.

3

4

## Capabilities

5

6

### Constants

7

8

```python { .api }

9

MODULE_NOT_FOUND = 'Module not found'

10

MODULE_TROUBLE = 'Trouble importing'

11

VERSION_NOT_FOUND = 'Version unknown'

12

```

13

14

### Version Detection

15

16

Get version information for any installed package using multiple detection strategies.

17

18

```python { .api }

19

def get_version(module: str | ModuleType) -> tuple[str, str | None]:

20

"""

21

Get the version of a module by passing the package or its name.

22

23

This function tries multiple strategies to detect version information:

24

1. importlib.metadata (preferred)

25

2. Common version attributes (__version__, version)

26

3. Known package-specific version locations

27

4. Package-specific version methods

28

29

Parameters:

30

- module (str | ModuleType): Name of module to import or the module itself

31

32

Returns:

33

- tuple[str, str | None]: (package_name, version_string)

34

- version_string can be None if version cannot be determined

35

- Returns MODULE_NOT_FOUND if module cannot be imported

36

- Returns MODULE_TROUBLE if module import fails with error

37

- Returns VERSION_NOT_FOUND if module loads but version cannot be found

38

"""

39

```

40

41

### Version Comparison

42

43

Compare version strings to check if a package meets minimum version requirements.

44

45

```python { .api }

46

def meets_version(version: str, meets: str) -> bool:

47

"""

48

Check if a version string meets a minimum version requirement.

49

50

This is a simplified version comparison tool. For robust version

51

comparison, consider using the 'packaging' library.

52

53

Parameters:

54

- version (str): Version string to check (e.g., '1.2.3')

55

- meets (str): Required minimum version (e.g., '1.2.0')

56

57

Returns:

58

- bool: True if version >= meets, False otherwise

59

60

Raises:

61

- ValueError: If version strings have more than 3 parts

62

- AssertionError: If versions are not comparable

63

64

Examples:

65

>>> meets_version('1.2.3', '1.2.0')

66

True

67

>>> meets_version('1.1.9', '1.2.0')

68

False

69

"""

70

71

def version_tuple(v: str) -> tuple[int, ...]:

72

"""

73

Convert a version string to a tuple of integers.

74

75

Non-numeric version components are converted to 0.

76

Version strings shorter than 3 parts are padded with 0.

77

78

Parameters:

79

- v (str): Version string (e.g., '1.2.3dev0')

80

81

Returns:

82

- tuple[int, ...]: Tuple of integers (e.g., (1, 2, 3))

83

84

Raises:

85

- ValueError: If version string has more than 3 parts

86

87

Examples:

88

>>> version_tuple('1.2.3')

89

(1, 2, 3)

90

>>> version_tuple('1.2.3dev0')

91

(1, 2, 0)

92

>>> version_tuple('1.2')

93

(1, 2, 0)

94

"""

95

```

96

97

### Environment Detection

98

99

Detect the Python execution environment to enable environment-specific formatting.

100

101

```python { .api }

102

def in_ipython() -> bool:

103

"""

104

Check if running in an IPython environment.

105

106

Returns:

107

- bool: True if in IPython, False otherwise

108

"""

109

110

def in_ipykernel() -> bool:

111

"""

112

Check if running in an ipykernel (most likely Jupyter) environment.

113

114

Note: This detects if using an ipykernel but cannot distinguish between

115

Jupyter Notebook, JupyterLab, QtConsole, or other frontends.

116

117

Returns:

118

- bool: True if using an ipykernel, False otherwise

119

"""

120

```

121

122

### Standard Library Detection

123

124

Get information about Python's standard library modules for filtering purposes.

125

126

```python { .api }

127

def get_standard_lib_modules() -> set[str]:

128

"""

129

Return a set of names of all modules in the standard library.

130

131

This is used internally to filter out standard library modules from

132

package reports and import tracking.

133

134

Returns:

135

- set[str]: Set of standard library module names

136

"""

137

```

138

139

### Distribution Dependencies

140

141

Get dependency information for installed packages using distribution metadata.

142

143

```python { .api }

144

def get_distribution_dependencies(dist_name: str) -> list[str]:

145

"""

146

Get the dependencies of a specified package distribution.

147

148

Uses importlib.metadata to read distribution metadata and extract

149

required dependencies. This is used internally by AutoReport to

150

automatically include package dependencies in reports.

151

152

Parameters:

153

- dist_name (str): Name of the package distribution

154

155

Returns:

156

- list[str]: List of dependency package names

157

158

Raises:

159

- PackageNotFoundError: If the distribution is not found

160

"""

161

```

162

163

## Usage Examples

164

165

### Version Detection

166

167

```python

168

import scooby

169

import numpy

170

171

# Get version by module name

172

name, version = scooby.get_version('numpy')

173

print(f"{name}: {version}") # numpy: 1.21.0

174

175

# Get version by module object

176

name, version = scooby.get_version(numpy)

177

print(f"{name}: {version}") # numpy: 1.21.0

178

179

# Handle missing packages

180

name, version = scooby.get_version('nonexistent_package')

181

print(f"{name}: {version}") # nonexistent_package: Module not found

182

183

# Handle packages without version info

184

name, version = scooby.get_version('some_local_module')

185

print(f"{name}: {version}") # some_local_module: Version unknown

186

187

# Check against constants

188

import scooby

189

from scooby.report import MODULE_NOT_FOUND

190

191

name, version = scooby.get_version('missing_pkg')

192

if version == MODULE_NOT_FOUND:

193

print(f"Package {name} is not installed")

194

```

195

196

### Version Comparison

197

198

```python

199

import scooby

200

201

# Check if installed version meets requirements

202

name, version = scooby.get_version('numpy')

203

if version and scooby.meets_version(version, '1.19.0'):

204

print("NumPy version is sufficient")

205

else:

206

print("NumPy version is too old or not installed")

207

208

# Version comparison examples

209

print(scooby.meets_version('1.2.3', '1.2.0')) # True

210

print(scooby.meets_version('1.1.9', '1.2.0')) # False

211

print(scooby.meets_version('2.0.0', '1.9.9')) # True

212

213

# Convert version strings to tuples for custom comparison

214

v1 = scooby.version_tuple('1.2.3dev0') # (1, 2, 0)

215

v2 = scooby.version_tuple('1.2.3') # (1, 2, 3)

216

print(v1 < v2) # True

217

```

218

219

### Environment Detection

220

221

```python

222

import scooby

223

224

# Detect execution environment

225

if scooby.in_ipykernel():

226

print("Running in Jupyter (or similar ipykernel environment)")

227

# Use HTML output

228

report = scooby.Report()

229

display(report) # Will use _repr_html_()

230

elif scooby.in_ipython():

231

print("Running in IPython")

232

# Use enhanced IPython features

233

report = scooby.Report()

234

print(report)

235

else:

236

print("Running in standard Python")

237

# Use plain text output

238

report = scooby.Report()

239

print(report)

240

```

241

242

### Standard Library Filtering

243

244

```python

245

import scooby

246

247

# Get all standard library modules

248

stdlib_modules = scooby.get_standard_lib_modules()

249

print(f"Standard library contains {len(stdlib_modules)} modules")

250

251

# Check if a module is in standard library

252

def is_third_party(module_name):

253

return module_name not in stdlib_modules

254

255

print(is_third_party('os')) # False (standard library)

256

print(is_third_party('numpy')) # True (third party)

257

print(is_third_party('json')) # False (standard library)

258

```

259

260

### Distribution Dependencies

261

262

```python

263

from scooby.report import get_distribution_dependencies

264

from importlib.metadata import PackageNotFoundError

265

266

# Get dependencies for a package

267

try:

268

deps = get_distribution_dependencies('matplotlib')

269

print(f"matplotlib dependencies: {deps}")

270

# Example output: ['numpy', 'python-dateutil', 'pyparsing', ...]

271

except PackageNotFoundError:

272

print("Package not found")

273

274

# Use in combination with version checking

275

def analyze_package_ecosystem(package_name):

276

"""Analyze a package and its entire dependency tree."""

277

try:

278

# Get the main package version

279

name, version = scooby.get_version(package_name)

280

print(f"Main package: {name} {version}")

281

282

# Get its dependencies

283

deps = get_distribution_dependencies(package_name)

284

print(f"Dependencies ({len(deps)}): {', '.join(deps)}")

285

286

# Check versions of all dependencies

287

for dep in deps:

288

dep_name, dep_version = scooby.get_version(dep)

289

print(f" {dep_name}: {dep_version}")

290

291

except PackageNotFoundError:

292

print(f"Package {package_name} not found")

293

294

# Analyze an entire ecosystem

295

analyze_package_ecosystem('matplotlib')

296

```

297

298

### Comprehensive Package Analysis

299

300

```python

301

import scooby

302

303

def analyze_package(package_name):

304

"""Comprehensive analysis of a package."""

305

name, version = scooby.get_version(package_name)

306

307

print(f"Package: {name}")

308

print(f"Version: {version}")

309

310

if version and version not in ['Module not found', 'Trouble importing', 'Version unknown']:

311

# Check version requirements

312

if scooby.meets_version(version, '1.0.0'):

313

print("βœ“ Meets minimum version 1.0.0")

314

else:

315

print("βœ— Below minimum version 1.0.0")

316

317

# Show version tuple

318

v_tuple = scooby.version_tuple(version)

319

print(f"Version tuple: {v_tuple}")

320

321

# Check if it's third-party

322

stdlib_modules = scooby.get_standard_lib_modules()

323

if name in stdlib_modules:

324

print("πŸ“¦ Standard library module")

325

else:

326

print("πŸ”§ Third-party package")

327

328

# Analyze various packages

329

for pkg in ['numpy', 'os', 'requests', 'nonexistent']:

330

analyze_package(pkg)

331

print()

332

```

333

334

### Custom Version Checking

335

336

```python

337

import scooby

338

339

def check_requirements(requirements):

340

"""

341

Check if installed packages meet version requirements.

342

343

Args:

344

requirements (dict): {package_name: min_version}

345

346

Returns:

347

dict: {package_name: (installed_version, meets_requirement)}

348

"""

349

import scooby

350

from scooby.report import MODULE_NOT_FOUND, MODULE_TROUBLE, VERSION_NOT_FOUND

351

352

results = {}

353

354

for package, min_version in requirements.items():

355

name, installed = scooby.get_version(package)

356

357

if installed in [MODULE_NOT_FOUND, MODULE_TROUBLE, VERSION_NOT_FOUND]:

358

meets_req = False

359

else:

360

meets_req = scooby.meets_version(installed, min_version)

361

362

results[name] = (installed, meets_req)

363

364

return results

365

366

# Check project requirements

367

requirements = {

368

'numpy': '1.19.0',

369

'pandas': '1.3.0',

370

'matplotlib': '3.3.0'

371

}

372

373

results = check_requirements(requirements)

374

for package, (version, meets) in results.items():

375

status = "βœ“" if meets else "βœ—"

376

print(f"{status} {package}: {version}")

377

```