or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-yacs

A lightweight library for defining and managing system configurations for scientific experimentation.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/yacs@0.1.x

To install, run

npx @tessl/cli install tessl/pypi-yacs@0.1.0

0

# YACS

1

2

YACS (Yet Another Configuration System) is a lightweight Python library for defining and managing system configurations in scientific experimentation and machine learning research. It provides a simple, YAML-based serialization format for reproducible experimental configurations with support for command line overrides and both local variable and global singleton usage patterns.

3

4

## Package Information

5

6

- **Package Name**: yacs

7

- **Language**: Python

8

- **Installation**: `pip install yacs`

9

- **Dependencies**: PyYAML

10

11

## Core Imports

12

13

```python

14

from yacs.config import CfgNode as CN

15

```

16

17

Alternative import for backward compatibility:

18

19

```python

20

from yacs.config import load_cfg

21

```

22

23

## Basic Usage

24

25

```python

26

from yacs.config import CfgNode as CN

27

28

# Create a configuration node

29

cfg = CN()

30

31

# Set configuration values

32

cfg.SYSTEM = CN()

33

cfg.SYSTEM.NUM_GPUS = 8

34

cfg.SYSTEM.NUM_WORKERS = 4

35

36

cfg.TRAIN = CN()

37

cfg.TRAIN.HYPERPARAMETER_1 = 0.1

38

cfg.TRAIN.SCALES = (2, 4, 8, 16)

39

40

# Merge from YAML file

41

cfg.merge_from_file("experiment.yaml")

42

43

# Merge from command line arguments

44

opts = ["SYSTEM.NUM_GPUS", 2, "TRAIN.SCALES", "(1, 2, 4)"]

45

cfg.merge_from_list(opts)

46

47

# Freeze configuration to prevent modifications

48

cfg.freeze()

49

50

# Access values using attribute or dictionary syntax

51

print(f"Using {cfg.SYSTEM.NUM_GPUS} GPUs")

52

print(f"Training scales: {cfg.TRAIN.SCALES}")

53

54

# Clone configuration for variations

55

cfg2 = cfg.clone()

56

cfg2.defrost()

57

cfg2.TRAIN.HYPERPARAMETER_1 = 0.2

58

cfg2.freeze()

59

```

60

61

## Architecture

62

63

YACS uses a single main class `CfgNode` that extends Python's built-in `dict` with additional configuration management capabilities:

64

65

- **Attribute Access**: Access configuration values using both dictionary keys and object attributes

66

- **Immutability**: Freeze/defrost configurations to control modification

67

- **Hierarchical Structure**: Nested configurations using recursive CfgNode instances

68

- **Type Validation**: Ensures configuration values are of valid types

69

- **Serialization**: YAML-based serialization for human-readable configuration files

70

71

## Capabilities

72

73

### Configuration Creation and Management

74

75

Create and manage hierarchical configuration structures with support for nested values and type validation.

76

77

```python { .api }

78

class CfgNode(dict):

79

"""

80

Configuration node that extends dict with additional configuration management capabilities.

81

82

Class Constants:

83

- IMMUTABLE: "__immutable__" - Key for storing immutability state

84

- DEPRECATED_KEYS: "__deprecated_keys__" - Key for storing deprecated keys set

85

- RENAMED_KEYS: "__renamed_keys__" - Key for storing renamed keys mapping

86

- NEW_ALLOWED: "__new_allowed__" - Key for storing new key allowance flag

87

"""

88

89

def __init__(self, init_dict=None, key_list=None, new_allowed=False):

90

"""

91

Create a configuration node.

92

93

Parameters:

94

- init_dict (dict, optional): Initial dictionary to populate the CfgNode

95

- key_list (list[str], optional): List of names indexing this CfgNode from root

96

- new_allowed (bool): Whether adding new keys is allowed when merging

97

"""

98

```

99

100

### Configuration Merging

101

102

Merge configurations from various sources including YAML files, Python files, other CfgNode objects, and command line arguments.

103

104

```python { .api }

105

def merge_from_file(self, cfg_filename):

106

"""

107

Load a YAML or Python config file and merge it into this CfgNode.

108

109

Parameters:

110

- cfg_filename (str): Path to config file (.yaml, .yml, or .py)

111

"""

112

113

def merge_from_other_cfg(self, cfg_other):

114

"""

115

Merge another CfgNode into this CfgNode.

116

117

Parameters:

118

- cfg_other (CfgNode): Configuration to merge

119

"""

120

121

def merge_from_list(self, cfg_list):

122

"""

123

Merge config from key-value pairs list (e.g., from command line).

124

125

Parameters:

126

- cfg_list (list): Alternating keys and values, e.g., ['FOO.BAR', 0.5, 'BAZ', 'value']

127

"""

128

```

129

130

### State Management

131

132

Control configuration mutability and create independent copies.

133

134

```python { .api }

135

def freeze(self):

136

"""Make this CfgNode and all children immutable."""

137

138

def defrost(self):

139

"""Make this CfgNode and all children mutable."""

140

141

def is_frozen(self):

142

"""

143

Check if configuration is frozen.

144

145

Returns:

146

bool: True if frozen, False if mutable

147

"""

148

149

def clone(self):

150

"""

151

Create a deep copy of this CfgNode.

152

153

Returns:

154

CfgNode: Independent copy of the configuration

155

"""

156

```

157

158

### Serialization

159

160

Convert configurations to and from YAML format for storage and human readability.

161

162

```python { .api }

163

def dump(self, **kwargs):

164

"""

165

Serialize configuration to YAML string.

166

167

Parameters:

168

**kwargs: Additional arguments passed to yaml.safe_dump()

169

170

Returns:

171

str: YAML representation of the configuration

172

"""

173

174

@classmethod

175

def load_cfg(cls, cfg_file_obj_or_str):

176

"""

177

Load configuration from file object or YAML string.

178

179

Parameters:

180

- cfg_file_obj_or_str (str or file): YAML string, file object, or Python source file

181

- For strings: parsed as YAML

182

- For file objects: loaded based on extension (.yaml/.yml/.py)

183

- For .py files: must export 'cfg' attribute as dict or CfgNode

184

185

Returns:

186

CfgNode: Loaded configuration

187

"""

188

```

189

190

### Deprecated and Renamed Key Management

191

192

Handle configuration evolution by managing deprecated and renamed keys.

193

194

```python { .api }

195

def register_deprecated_key(self, key):

196

"""

197

Register a key as deprecated. Deprecated keys are ignored during merging with a warning.

198

199

Parameters:

200

- key (str): Fully-qualified key to deprecate (e.g., 'SECTION.SUBSECTION.KEY')

201

"""

202

203

def register_renamed_key(self, old_name, new_name, message=None):

204

"""

205

Register a key as renamed. Raises error when old key is used.

206

207

Parameters:

208

- old_name (str): Old fully-qualified key name

209

- new_name (str): New fully-qualified key name

210

- message (str, optional): Additional message for the user

211

"""

212

213

def key_is_deprecated(self, full_key):

214

"""

215

Check if a key is deprecated.

216

217

Parameters:

218

- full_key (str): Fully-qualified key to check

219

220

Returns:

221

bool: True if key is deprecated

222

"""

223

224

def key_is_renamed(self, full_key):

225

"""

226

Check if a key has been renamed.

227

228

Parameters:

229

- full_key (str): Fully-qualified key to check

230

231

Returns:

232

bool: True if key has been renamed

233

"""

234

235

def raise_key_rename_error(self, full_key):

236

"""

237

Raise a KeyError for a renamed key with helpful migration message.

238

239

Parameters:

240

- full_key (str): The old key name that was used

241

242

Raises:

243

KeyError: With message indicating the old and new key names

244

"""

245

```

246

247

### Magic Methods and Attribute Access

248

249

Support for Python magic methods enabling dict-like and attribute-like access patterns.

250

251

```python { .api }

252

def __getattr__(self, name):

253

"""

254

Enable attribute-style access to configuration values.

255

256

Parameters:

257

- name (str): Attribute name to access

258

259

Returns:

260

Any: Value stored at the key

261

262

Raises:

263

AttributeError: If key does not exist

264

"""

265

266

def __setattr__(self, name, value):

267

"""

268

Enable attribute-style assignment of configuration values.

269

270

Parameters:

271

- name (str): Attribute name to set

272

- value (Any): Value to assign (must be valid YACS type)

273

274

Raises:

275

AttributeError: If CfgNode is frozen or name conflicts with internal state

276

"""

277

278

def __str__(self):

279

"""

280

Return human-readable string representation of the configuration.

281

282

Returns:

283

str: Formatted configuration tree

284

"""

285

286

def __repr__(self):

287

"""

288

Return detailed string representation for debugging.

289

290

Returns:

291

str: Debug representation showing class name and dict contents

292

"""

293

```

294

295

### New Key Control

296

297

Control whether new keys can be added during configuration merging.

298

299

```python { .api }

300

def is_new_allowed(self):

301

"""

302

Check if new keys are allowed.

303

304

Returns:

305

bool: True if new keys can be added during merging

306

"""

307

308

def set_new_allowed(self, is_new_allowed):

309

"""

310

Set whether new keys are allowed recursively.

311

312

Parameters:

313

- is_new_allowed (bool): Whether to allow new keys

314

"""

315

```

316

317

### Internal Methods

318

319

Advanced methods for internal configuration processing and tree creation.

320

321

```python { .api }

322

@classmethod

323

def _create_config_tree_from_dict(cls, dic, key_list):

324

"""

325

Create a configuration tree from a dictionary, converting nested dicts to CfgNodes.

326

327

Parameters:

328

- dic (dict): Dictionary to convert

329

- key_list (list[str]): List of keys for error reporting

330

331

Returns:

332

dict: Dictionary with nested dicts converted to CfgNodes

333

"""

334

335

@classmethod

336

def _decode_cfg_value(cls, value):

337

"""

338

Decode a raw config value into a Python object.

339

340

Parameters:

341

- value (Any): Raw value from YAML/command line (dict, str, or other)

342

343

Returns:

344

Any: Decoded Python object (CfgNode for dicts, evaluated literals for strings)

345

"""

346

347

def _immutable(self, is_immutable):

348

"""

349

Recursively set immutability state for this CfgNode and all children.

350

351

Parameters:

352

- is_immutable (bool): Whether to make the configuration immutable

353

"""

354

```

355

356

## Module Functions

357

358

### Configuration Loading

359

360

```python { .api }

361

def load_cfg(cfg_file_obj_or_str):

362

"""

363

Load configuration from file object or YAML string (backward compatibility alias).

364

365

Parameters:

366

- cfg_file_obj_or_str (str or file): YAML string, file object, or Python source file

367

368

Returns:

369

CfgNode: Loaded configuration

370

"""

371

```

372

373

## Configuration File Formats

374

375

### YAML Files

376

377

YACS supports YAML configuration files with nested structure:

378

379

```yaml

380

SYSTEM:

381

NUM_GPUS: 2

382

NUM_WORKERS: 4

383

TRAIN:

384

HYPERPARAMETER_1: 0.1

385

SCALES: [2, 4, 8, 16]

386

MODEL:

387

TYPE: "resnet50"

388

```

389

390

### Python Files

391

392

Python configuration files must export a `cfg` variable of type `dict` or `CfgNode`:

393

394

```python

395

from yacs.config import CfgNode as CN

396

397

cfg = CN()

398

cfg.TRAIN = CN()

399

cfg.TRAIN.HYPERPARAMETER_1 = 0.9

400

cfg.MODEL = CN()

401

cfg.MODEL.TYPE = "modified_model"

402

```

403

404

## Command Line Integration

405

406

YACS makes it easy to override configuration values from command line arguments:

407

408

```python

409

import argparse

410

from yacs.config import CfgNode as CN

411

412

def get_cfg_defaults():

413

cfg = CN()

414

cfg.SYSTEM = CN()

415

cfg.SYSTEM.NUM_GPUS = 8

416

cfg.TRAIN = CN()

417

cfg.TRAIN.LEARNING_RATE = 0.001

418

return cfg

419

420

if __name__ == "__main__":

421

cfg = get_cfg_defaults()

422

cfg.merge_from_file("config.yaml")

423

424

# Parse command line overrides

425

parser = argparse.ArgumentParser()

426

parser.add_argument("--opts", nargs=argparse.REMAINDER,

427

help="Modify config options using the command-line")

428

args = parser.parse_args()

429

430

if args.opts:

431

cfg.merge_from_list(args.opts)

432

433

cfg.freeze()

434

```

435

436

Usage: `python script.py --opts SYSTEM.NUM_GPUS 4 TRAIN.LEARNING_RATE 0.01`

437

438

## Type System

439

440

YACS validates configuration values against a set of allowed types:

441

442

- `str` - String values (including `unicode` in Python 2)

443

- `int` - Integer numbers

444

- `float` - Floating point numbers

445

- `bool` - Boolean values

446

- `list` - Lists of valid types

447

- `tuple` - Tuples of valid types

448

- `NoneType` - None values

449

- `CfgNode` - Nested configuration nodes

450

451

Nested dictionaries are automatically converted to CfgNode objects. Invalid types raise AssertionError during assignment or merging.

452

453

### Supported File Extensions

454

455

YACS supports loading configurations from files with these extensions:

456

457

- **YAML files**: `.yaml`, `.yml`, or no extension (treated as YAML)

458

- **Python files**: `.py` (must export a `cfg` variable)

459

460

## Error Handling

461

462

YACS provides clear error messages for common configuration issues:

463

464

- **KeyError**: Raised when trying to merge non-existent keys

465

- **ValueError**: Raised when type mismatches occur during merging

466

- **AttributeError**: Raised when trying to modify frozen configurations

467

- **AssertionError**: Raised for invalid types or malformed operations

468

469

Deprecated keys generate warnings but don't raise errors, while renamed keys raise KeyError with helpful migration messages.