or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-functions.mdconfig-exceptions.mdcore-functions.mdhelper-functions.mdindex.md

helper-functions.mddocs/

0

# Helper Functions

1

2

Utility functions and classes that build upon varname's core functionality to provide convenient patterns for common use cases. These helpers make it easier to integrate varname capabilities into applications.

3

4

## Capabilities

5

6

### Variable Name Registration

7

8

Decorator to automatically add `__varname__` support to classes and functions, enabling them to access their assigned variable names.

9

10

```python { .api }

11

def register(

12

cls_or_func: type = None,

13

frame: int = 1,

14

ignore: IgnoreType = None,

15

multi_vars: bool = False,

16

raise_exc: bool = True,

17

strict: bool = True

18

) -> Union[Type, Callable]:

19

"""

20

A decorator to register __varname__ to a class or function.

21

22

Args:

23

cls_or_func: The class or function to register. When used as @register

24

without parentheses, this receives the decorated object.

25

frame: Nth frame used to retrieve the variable name (same as varname)

26

ignore: Frames to be ignored (same as varname)

27

multi_vars: Whether allow multiple variables (same as varname)

28

raise_exc: Whether to raise exception on failure (same as varname)

29

strict: Whether to only return name for direct assignments (same as varname)

30

31

Returns:

32

The decorated class or function with __varname__ attribute support

33

34

Note:

35

After decoration, instances/calls will have a __varname__ attribute

36

containing the variable name they were assigned to.

37

"""

38

```

39

40

#### Usage Examples

41

42

```python

43

from varname.helpers import register

44

45

# Class registration

46

@register

47

class DataProcessor:

48

def __init__(self, data):

49

self.data = data

50

print(f"Created {self.__varname__} processor")

51

52

def process(self):

53

return f"Processing with {self.__varname__}"

54

55

# Usage

56

main_processor = DataProcessor([1, 2, 3]) # Prints: Created main_processor processor

57

result = main_processor.process() # Returns: "Processing with main_processor"

58

59

# Function registration

60

@register

61

def create_connection():

62

print(f"Creating connection: {create_connection.__varname__}")

63

return f"Connection_{create_connection.__varname__}"

64

65

db_conn = create_connection() # Prints: Creating connection: db_conn

66

# db_conn == "Connection_db_conn"

67

68

# With parameters

69

@register(frame=2, strict=False)

70

class FlexibleProcessor:

71

def __init__(self):

72

self.name = self.__varname__

73

74

def factory():

75

return FlexibleProcessor()

76

77

flexible = factory() # flexible.name == "flexible"

78

```

79

80

### Value Wrapper with Name Storage

81

82

A wrapper class that stores both a value and the variable name it was assigned to, useful for debugging and introspection.

83

84

```python { .api }

85

class Wrapper:

86

"""A wrapper with ability to retrieve the variable name."""

87

88

def __init__(

89

self,

90

value: Any,

91

frame: int = 1,

92

ignore: IgnoreType = None,

93

raise_exc: bool = True,

94

strict: bool = True

95

):

96

"""

97

Initialize wrapper with value and retrieve variable name.

98

99

Args:

100

value: The value to be wrapped

101

frame: Nth frame used to retrieve variable name (same as varname)

102

ignore: Frames to be ignored (same as varname)

103

raise_exc: Whether to raise exception on failure (same as varname)

104

strict: Whether to only return name for direct assignments (same as varname)

105

"""

106

107

@property

108

def name(self) -> str:

109

"""The variable name to which the instance is assigned."""

110

111

@property

112

def value(self) -> Any:

113

"""The value this wrapper wraps."""

114

115

def __str__(self) -> str:

116

"""Returns repr(self.value)."""

117

118

def __repr__(self) -> str:

119

"""Returns formatted representation with name and value."""

120

```

121

122

#### Usage Examples

123

124

```python

125

from varname.helpers import Wrapper

126

127

# Basic wrapper usage

128

data_wrapper = Wrapper([1, 2, 3, 4])

129

print(data_wrapper.name) # "data_wrapper"

130

print(data_wrapper.value) # [1, 2, 3, 4]

131

print(data_wrapper) # [1, 2, 3, 4]

132

print(repr(data_wrapper)) # <Wrapper (data_wrapper): [1, 2, 3, 4]>

133

134

# With complex objects

135

class Config:

136

def __init__(self, **kwargs):

137

self.__dict__.update(kwargs)

138

139

app_config = Wrapper(Config(debug=True, port=8080))

140

print(f"Config name: {app_config.name}") # Config name: app_config

141

print(f"Debug mode: {app_config.value.debug}") # Debug mode: True

142

143

# Multiple wrappers

144

user_data = Wrapper({"name": "Alice", "age": 30})

145

system_data = Wrapper({"version": "1.0", "env": "prod"})

146

147

wrappers = [user_data, system_data]

148

for wrapper in wrappers:

149

print(f"{wrapper.name}: {wrapper.value}")

150

# user_data: {'name': 'Alice', 'age': 30}

151

# system_data: {'version': '1.0', 'env': 'prod'}

152

```

153

154

### Debug Printing with Variable Names

155

156

Print variables with their names automatically retrieved, making debugging output more informative.

157

158

```python { .api }

159

def debug(

160

var,

161

*more_vars,

162

prefix: str = "DEBUG: ",

163

merge: bool = False,

164

repr: bool = True,

165

sep: str = "=",

166

vars_only: bool = False

167

) -> None:

168

"""

169

Print variable names and values for debugging.

170

171

Args:

172

var: The variable to print

173

*more_vars: Other variables to print

174

prefix: Prefix to add to each debug line

175

merge: Whether to merge all variables in one line instead of separate lines

176

repr: Whether to print values using repr() (True) or str() (False)

177

sep: Separator between variable name and value

178

vars_only: Whether to only include variables in output (vs expressions)

179

180

Note:

181

Uses nameof internally to get variable names, so inherits its limitations

182

in REPL/exec environments.

183

"""

184

```

185

186

#### Usage Examples

187

188

```python

189

from varname.helpers import debug

190

191

# Basic debug printing

192

x = 42

193

y = "hello"

194

debug(x, y)

195

# DEBUG: x=42

196

# DEBUG: y='hello'

197

198

# Custom formatting

199

debug(x, y, prefix=">>> ", sep=" -> ", merge=True)

200

# >>> x -> 42, y -> 'hello'

201

202

# With expressions (vars_only=False)

203

items = [1, 2, 3]

204

debug(len(items), items[0], vars_only=False)

205

# DEBUG: len(items)=3

206

# DEBUG: items[0]=1

207

208

# Complex objects without repr

209

class Person:

210

def __init__(self, name):

211

self.name = name

212

def __str__(self):

213

return f"Person({self.name})"

214

215

person = Person("Bob")

216

debug(person, repr=False)

217

# DEBUG: person=Person(Bob)

218

```

219

220

### JavaScript-like Object Creation

221

222

Create dictionaries using variable names as keys automatically, similar to JavaScript's object shorthand.

223

224

```python { .api }

225

def jsobj(

226

*args: Any,

227

vars_only: bool = True,

228

frame: int = 1,

229

**kwargs: Any

230

) -> Dict[str, Any]:

231

"""

232

Create a JavaScript-like object (dict) using variable names as keys.

233

234

Args:

235

*args: Positional arguments whose names will become keys

236

vars_only: Whether to only allow variables as arguments (vs expressions)

237

frame: Frame adjustment for name retrieval

238

**kwargs: Keyword arguments to include in the resulting dict

239

240

Returns:

241

Dictionary mapping argument names to their values, plus any kwargs

242

243

Note:

244

Uses nameof internally to get variable names from positional arguments.

245

Keyword arguments are included as-is.

246

"""

247

```

248

249

#### Usage Examples

250

251

```python

252

from varname.helpers import jsobj

253

254

# Basic usage

255

username = "alice"

256

user_id = 12345

257

active = True

258

259

user = jsobj(username, user_id, active)

260

# user == {'username': 'alice', 'user_id': 12345, 'active': True}

261

262

# With keyword arguments

263

user = jsobj(username, user_id, role="admin", permissions=["read", "write"])

264

# user == {

265

# 'username': 'alice',

266

# 'user_id': 12345,

267

# 'role': 'admin',

268

# 'permissions': ['read', 'write']

269

# }

270

271

# Nested objects

272

server_config = jsobj(

273

username,

274

user_id,

275

database=jsobj(host="localhost", port=5432),

276

cache=jsobj(enabled=True, ttl=3600)

277

)

278

# server_config == {

279

# 'username': 'alice',

280

# 'user_id': 12345,

281

# 'database': {'host': 'localhost', 'port': 5432},

282

# 'cache': {'enabled': True, 'ttl': 3600}

283

# }

284

285

# With expressions (vars_only=False)

286

items = [1, 2, 3]

287

result = jsobj(len(items), items[0], vars_only=False, total=sum(items))

288

# result == {'len(items)': 3, 'items[0]': 1, 'total': 6}

289

```

290

291

### Code Execution with Source Visibility

292

293

Execute code where the source is visible at runtime, enabling varname functions to work in dynamic execution contexts.

294

295

```python { .api }

296

def exec_code(

297

code: str,

298

globals: Dict[str, Any] = None,

299

locals: Dict[str, Any] = None,

300

/,

301

sourcefile: PathLike | str = None,

302

frame: int = 1,

303

ignore: IgnoreType = None,

304

**kwargs: Any

305

) -> None:

306

"""

307

Execute code where source code is visible at runtime.

308

309

Args:

310

code: The code string to execute

311

globals: Global namespace for execution (defaults to caller's globals)

312

locals: Local namespace for execution (defaults to caller's locals)

313

sourcefile: Optional file path to write source code to for visibility

314

frame: Frame adjustment for namespace retrieval

315

ignore: Frames to ignore when retrieving namespace

316

**kwargs: Additional arguments passed to exec()

317

318

Note:

319

This function makes varname operations work inside exec'd code by

320

ensuring the source code is available for AST analysis. Without this,

321

exec'd code cannot use varname functions effectively.

322

"""

323

```

324

325

#### Usage Examples

326

327

```python

328

from varname.helpers import exec_code, varname

329

330

# Basic code execution with varname support

331

code = '''

332

def create_item():

333

return varname()

334

335

my_item = create_item()

336

print(f"Created: {my_item}") # Will print: Created: my_item

337

'''

338

339

exec_code(code)

340

341

# With custom globals/locals

342

local_vars = {'data': [1, 2, 3]}

343

global_vars = {'varname': varname}

344

345

code = '''

346

def process():

347

name = varname()

348

return f"Processing {name} with {len(data)} items"

349

350

result = process()

351

'''

352

353

exec_code(code, globals=global_vars, locals=local_vars)

354

print(local_vars['result']) # Processing result with 3 items

355

356

# With source file for debugging

357

import tempfile

358

from pathlib import Path

359

360

with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:

361

source_file = f.name

362

363

code = '''

364

from varname.helpers import debug

365

366

x = 42

367

y = "test"

368

debug(x, y)

369

'''

370

371

exec_code(code, sourcefile=source_file)

372

# DEBUG: x=42

373

# DEBUG: y='test'

374

375

# Clean up

376

Path(source_file).unlink()

377

```

378

379

## Integration Patterns

380

381

### Factory Pattern with Name Awareness

382

383

```python

384

from varname.helpers import register

385

from varname.helpers import Wrapper

386

387

@register

388

class NamedFactory:

389

@classmethod

390

def create(cls, *args, **kwargs):

391

instance = cls(*args, **kwargs)

392

instance._factory_name = cls.__varname__

393

return instance

394

395

# Automatic name detection in factory

396

user_factory = NamedFactory.create()

397

print(user_factory._factory_name) # "user_factory"

398

399

# Combined with Wrapper

400

class SmartFactory:

401

def __init__(self, config):

402

self.config = config

403

404

def create_component(self):

405

return Wrapper({"factory": "smart", "config": self.config})

406

407

factory = SmartFactory({"debug": True})

408

component = factory.create_component()

409

print(f"Component {component.name} created") # Component component created

410

```

411

412

### Configuration Management

413

414

```python

415

from varname.helpers import jsobj, debug

416

417

def load_config():

418

# Database settings

419

db_host = "localhost"

420

db_port = 5432

421

db_name = "myapp"

422

423

# Cache settings

424

cache_enabled = True

425

cache_ttl = 3600

426

427

# Create config using variable names

428

config = {

429

"database": jsobj(db_host, db_port, db_name),

430

"cache": jsobj(cache_enabled, cache_ttl)

431

}

432

433

# Debug the configuration

434

debug(config, prefix="CONFIG: ")

435

return config

436

437

config = load_config()

438

# CONFIG: config={'database': {'db_host': 'localhost', ...}, ...}

439

```