or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-actions.mdcli-creation.mdcore-parser.mdindex.mdnamespace-management.mdsettings.mdsignature-arguments.mdtypes-validation.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Utility functions and classes for path handling, lazy instantiation, parser introspection, and advanced type support. These utilities provide foundational functionality used throughout jsonargparse and offer helpful tools for building sophisticated CLI applications.

3

4

## Capabilities

5

6

### Path Handling

7

8

Enhanced path class for robust file system path validation, resolution, and access control.

9

10

```python { .api }

11

class Path:

12

def __init__(self, path: Union[str, os.PathLike], mode: str = "fr"):

13

"""

14

Create a Path object with validation and access control.

15

16

Args:

17

path: File system path (relative or absolute)

18

mode: Access mode string (combinations of 'f'=file, 'd'=dir, 'r'=read, 'w'=write, 'x'=executable)

19

20

Raises:

21

TypeError: If path validation fails

22

"""

23

24

def __str__(self) -> str:

25

"""

26

Get string representation of the path.

27

28

Returns:

29

str: String path

30

"""

31

32

@property

33

def absolute(self) -> pathlib.Path:

34

"""

35

Get absolute path as pathlib.Path object.

36

37

Returns:

38

pathlib.Path: Absolute path

39

"""

40

41

def exists(self) -> bool:

42

"""

43

Check if path exists.

44

45

Returns:

46

bool: True if path exists

47

"""

48

49

def is_file(self) -> bool:

50

"""

51

Check if path is a file.

52

53

Returns:

54

bool: True if path is a file

55

"""

56

57

def is_dir(self) -> bool:

58

"""

59

Check if path is a directory.

60

61

Returns:

62

bool: True if path is a directory

63

"""

64

```

65

66

### Lazy Instantiation

67

68

Utility for creating lazy instances where class instantiation is delayed until first method call.

69

70

```python { .api }

71

def lazy_instance(init_fn: Callable[[], Any]) -> Any:

72

"""

73

Create a lazy instance that delays instantiation until first use.

74

75

Args:

76

init_fn: Function that returns the instance when called

77

78

Returns:

79

Any: Lazy proxy object that behaves like the target instance

80

"""

81

```

82

83

### Parser Introspection

84

85

Utilities for capturing and introspecting ArgumentParser instances during execution.

86

87

```python { .api }

88

def capture_parser() -> ArgumentParser:

89

"""

90

Capture the ArgumentParser being used in the current execution context.

91

92

Returns:

93

ArgumentParser: The parser instance currently being used

94

95

Raises:

96

RuntimeError: If no parser is active in current context

97

"""

98

```

99

100

### Dynamic Class Generation

101

102

Utilities for creating classes dynamically from functions and managing class introspection.

103

104

```python { .api }

105

def class_from_function(function: Callable, *args, **kwargs) -> Type:

106

"""

107

Create a dynamic class equivalent to calling a function.

108

109

Args:

110

function: Function to wrap as a class

111

*args: Positional arguments for function

112

**kwargs: Keyword arguments for function

113

114

Returns:

115

Type: Dynamic class that instantiates by calling the function

116

"""

117

118

def register_unresolvable_import_paths(*import_paths: str) -> None:

119

"""

120

Register import paths for objects whose import path cannot be automatically resolved.

121

122

Args:

123

*import_paths: Import path strings to register

124

"""

125

```

126

127

## Usage Examples

128

129

### Path Validation and Access Control

130

131

```python

132

from jsonargparse import ArgumentParser, Path

133

134

parser = ArgumentParser()

135

136

# Add path arguments with validation

137

parser.add_argument(

138

"--input-file",

139

type=Path(mode="fr"), # Must exist, be a file, and be readable

140

help="Input file path"

141

)

142

143

parser.add_argument(

144

"--output-dir",

145

type=Path(mode="dw"), # Must be a directory and writable

146

help="Output directory path"

147

)

148

149

parser.add_argument(

150

"--script",

151

type=Path(mode="fx"), # Must be a file and executable

152

help="Script to execute"

153

)

154

155

config = parser.parse_args()

156

157

# Paths are validated automatically

158

print(f"Input file: {config.input_file}")

159

print(f"Absolute path: {config.input_file.absolute}")

160

print(f"Exists: {config.input_file.exists()}")

161

print(f"Is file: {config.input_file.is_file()}")

162

163

# Use the paths

164

with open(config.input_file, 'r') as f:

165

data = f.read()

166

```

167

168

### Lazy Instance Creation

169

170

```python

171

from jsonargparse import lazy_instance

172

import expensive_module

173

174

# Create lazy instance that delays expensive initialization

175

def create_model():

176

print("Creating expensive model...")

177

return expensive_module.LargeModel()

178

179

# Model is not created yet

180

lazy_model = lazy_instance(create_model)

181

182

print("Lazy model created")

183

184

# Model is created only when first accessed

185

result = lazy_model.predict(data) # "Creating expensive model..." printed here

186

print(f"Prediction: {result}")

187

188

# Subsequent calls use the same instance

189

result2 = lazy_model.predict(more_data) # No "Creating..." message

190

```

191

192

### Parser Capture and Introspection

193

194

```python

195

from jsonargparse import ArgumentParser, capture_parser

196

197

def setup_logging_args(enable_capture: bool = True):

198

"""Function that adds logging arguments to current parser."""

199

if enable_capture:

200

# Capture the current parser being used

201

parser = capture_parser()

202

203

# Add logging arguments to captured parser

204

parser.add_argument("--log-level",

205

choices=["DEBUG", "INFO", "WARNING", "ERROR"],

206

default="INFO")

207

parser.add_argument("--log-file", type=str, help="Log file path")

208

parser.add_argument("--quiet", action="store_true", help="Suppress output")

209

210

print("Added logging arguments to parser")

211

212

# Create parser

213

parser = ArgumentParser()

214

parser.add_argument("--name", type=str, required=True)

215

216

# Add function arguments - this will capture the current parser

217

parser.add_function_arguments(setup_logging_args)

218

219

config = parser.parse_args()

220

221

print(f"Name: {config.name}")

222

print(f"Log level: {config.log_level}")

223

if config.log_file:

224

print(f"Log file: {config.log_file}")

225

```

226

227

### Dynamic Class Creation

228

229

```python

230

from jsonargparse import class_from_function, ArgumentParser

231

232

def train_model(data_path: str, epochs: int = 100, learning_rate: float = 0.001):

233

"""Train a machine learning model."""

234

print(f"Training model with data from {data_path}")

235

print(f"Epochs: {epochs}, Learning rate: {learning_rate}")

236

return {"status": "trained", "epochs": epochs}

237

238

# Create a class from the function

239

TrainingClass = class_from_function(train_model)

240

241

# Use the dynamic class with jsonargparse

242

parser = ArgumentParser()

243

parser.add_class_arguments(TrainingClass, "training")

244

245

config = parser.parse_args()

246

247

# Instantiate the dynamic class (calls the original function)

248

trainer = TrainingClass(**config.training.as_dict())

249

print(f"Training result: {trainer}")

250

```

251

252

### Import Path Registration

253

254

```python

255

from jsonargparse import register_unresolvable_import_paths

256

from some_complex_module import HardToResolveClass

257

258

# Register import paths for classes that can't be automatically resolved

259

register_unresolvable_import_paths(

260

"some_complex_module.HardToResolveClass",

261

"another_module.DynamicClass"

262

)

263

264

# Now these classes can be properly serialized and deserialized

265

# in configuration files and command line arguments

266

```

267

268

### Advanced Path Usage

269

270

```python

271

from jsonargparse import ArgumentParser, Path

272

273

parser = ArgumentParser()

274

275

# Different path modes for different use cases

276

parser.add_argument("--config", type=Path(mode="fr")) # File, readable

277

parser.add_argument("--output", type=Path(mode="fw")) # File, writable (may not exist)

278

parser.add_argument("--data-dir", type=Path(mode="dr")) # Directory, readable

279

parser.add_argument("--temp-dir", type=Path(mode="dw")) # Directory, writable

280

parser.add_argument("--script", type=Path(mode="frx")) # File, readable, executable

281

282

try:

283

config = parser.parse_args()

284

285

# All paths are validated according to their modes

286

print(f"Config file: {config.config}")

287

print(f"Output will be written to: {config.output}")

288

print(f"Data directory: {config.data_dir}")

289

print(f"Script to run: {config.script}")

290

291

except Exception as e:

292

print(f"Path validation failed: {e}")

293

```

294

295

### Combining Utilities

296

297

```python

298

from jsonargparse import ArgumentParser, Path, lazy_instance, capture_parser

299

import logging

300

301

def create_logger():

302

"""Create logger instance only when needed."""

303

logger = logging.getLogger("myapp")

304

logger.setLevel(logging.INFO)

305

handler = logging.StreamHandler()

306

formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

307

handler.setFormatter(formatter)

308

logger.addHandler(handler)

309

return logger

310

311

def setup_app_args():

312

"""Setup application-specific arguments."""

313

parser = capture_parser()

314

parser.add_argument("--debug", action="store_true")

315

parser.add_argument("--workers", type=int, default=1)

316

317

class AppConfig:

318

def __init__(self,

319

input_file: Path(mode="fr"),

320

output_dir: Path(mode="dw"),

321

log_file: Path(mode="fw") = None):

322

self.input_file = input_file

323

self.output_dir = output_dir

324

self.log_file = log_file

325

326

# Create lazy logger

327

self.logger = lazy_instance(create_logger)

328

329

def process(self):

330

self.logger.info(f"Processing {self.input_file}")

331

self.logger.info(f"Output will go to {self.output_dir}")

332

333

# Process files here

334

print(f"Processing {self.input_file} -> {self.output_dir}")

335

336

parser = ArgumentParser()

337

parser.add_class_arguments(AppConfig, "config")

338

parser.add_function_arguments(setup_app_args)

339

340

args = parser.parse_args()

341

342

app = AppConfig(**args.config.as_dict())

343

app.process()

344

345

if args.debug:

346

print("Debug mode enabled")

347

print(f"Using {args.workers} workers")

348

```

349

350

### Path Mode Reference

351

352

Path validation modes:

353

354

- `"f"` - Must be a file

355

- `"d"` - Must be a directory

356

- `"r"` - Must be readable

357

- `"w"` - Must be writable

358

- `"x"` - Must be executable

359

- `"c"` - File can be created (parent directory must exist and be writable)

360

- `"u"` - Path can be a URL

361

362

Common combinations:

363

- `"fr"` - Existing readable file

364

- `"fw"` - Writable file (may not exist yet)

365

- `"dr"` - Existing readable directory

366

- `"dw"` - Writable directory

367

- `"frx"` - Executable file

368

- `"fc"` - File that can be created