or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compilation.mddecorators.mdfunction-creation.mdindex.mdpartial.mdsignature-utils.mdwrapping.md

signature-utils.mddocs/

0

# Signature Manipulation

1

2

Utilities for programmatically modifying function signatures by adding or removing parameters. These functions enable dynamic signature construction and are the building blocks used by other makefun utilities for signature modifications.

3

4

```python

5

from typing import Union, Iterable

6

from inspect import Signature, Parameter

7

```

8

9

## Capabilities

10

11

### Adding Parameters to Signatures

12

13

Add parameters to existing signatures at specific positions with automatic parameter kind inference.

14

15

```python { .api }

16

def add_signature_parameters(s: Signature,

17

first: Union[str, Parameter, Iterable[Union[str, Parameter]]] = (),

18

last: Union[str, Parameter, Iterable[Union[str, Parameter]]] = (),

19

custom: Union[Parameter, Iterable[Parameter]] = (),

20

custom_idx: int = -1) -> Signature:

21

"""

22

Adds parameters to an existing signature, returning a new Signature instance.

23

24

Parameters:

25

- s: Signature, original signature to modify

26

- first: Union[str, Parameter, Iterable[Union[str, Parameter]]], default ()

27

Parameters to add at the beginning of the parameter list.

28

Strings are converted to Parameter objects with auto-inferred kinds.

29

- last: Union[str, Parameter, Iterable[Union[str, Parameter]]], default ()

30

Parameters to add at the end of the parameter list.

31

Strings are converted to Parameter objects with auto-inferred kinds.

32

- custom: Union[Parameter, Iterable[Parameter]], default ()

33

Parameter objects to add at a custom position specified by custom_idx

34

- custom_idx: int, default -1

35

Position to insert custom parameters (supports negative indexing)

36

37

Returns:

38

Signature: New signature with added parameters

39

40

Raises:

41

ValueError: If parameter names conflict with existing parameters

42

43

Note:

44

- Parameter kinds are auto-inferred based on context when strings are provided

45

- Maintains proper parameter ordering and kind constraints

46

- Preserves return annotation from original signature

47

"""

48

```

49

50

### Removing Parameters from Signatures

51

52

Remove specified parameters from existing signatures by name.

53

54

```python { .api }

55

def remove_signature_parameters(s: Signature, *param_names: str) -> Signature:

56

"""

57

Removes parameters from an existing signature, returning a new Signature instance.

58

59

Parameters:

60

- s: Signature, original signature to modify

61

- *param_names: str, names of parameters to remove

62

63

Returns:

64

Signature: New signature with specified parameters removed

65

66

Raises:

67

KeyError: If any parameter name is not found in the signature

68

"""

69

```

70

71

### Usage Examples

72

73

#### Basic Parameter Addition

74

75

```python

76

from makefun import add_signature_parameters

77

from inspect import signature, Parameter

78

79

def original_func(x: int, y: str) -> str:

80

return f"{x}: {y}"

81

82

original_sig = signature(original_func)

83

84

# Add parameters at the beginning

85

new_sig = add_signature_parameters(original_sig, first="prefix: str = 'Result'")

86

print(new_sig) # (prefix: str = 'Result', x: int, y: str) -> str

87

88

# Add parameters at the end

89

new_sig2 = add_signature_parameters(original_sig, last=["suffix: str = '!'", "verbose: bool = False"])

90

print(new_sig2) # (x: int, y: str, suffix: str = '!', verbose: bool = False) -> str

91

92

# Add parameters at both ends

93

new_sig3 = add_signature_parameters(original_sig,

94

first="timestamp: float",

95

last="debug: bool = False")

96

print(new_sig3) # (timestamp: float, x: int, y: str, debug: bool = False) -> str

97

```

98

99

#### Using Parameter Objects

100

101

```python

102

from makefun import add_signature_parameters

103

from inspect import signature, Parameter

104

105

def base_func(data: list) -> int:

106

return len(data)

107

108

base_sig = signature(base_func)

109

110

# Create Parameter objects explicitly

111

log_param = Parameter('log_level', Parameter.KEYWORD_ONLY, default='INFO', annotation=str)

112

timeout_param = Parameter('timeout', Parameter.POSITIONAL_OR_KEYWORD, default=30, annotation=int)

113

114

# Add using Parameter objects

115

enhanced_sig = add_signature_parameters(base_sig,

116

first=timeout_param,

117

last=log_param)

118

print(enhanced_sig) # (timeout: int = 30, data: list, *, log_level: str = 'INFO') -> int

119

```

120

121

#### Custom Position Insertion

122

123

```python

124

from makefun import add_signature_parameters

125

from inspect import signature, Parameter

126

127

def func_with_many_params(a: int, b: str, c: float, d: bool = True) -> dict:

128

return {"a": a, "b": b, "c": c, "d": d}

129

130

original_sig = signature(func_with_many_params)

131

132

# Insert parameter at specific position (between b and c)

133

middle_param = Parameter('inserted', Parameter.POSITIONAL_OR_KEYWORD, default="middle", annotation=str)

134

new_sig = add_signature_parameters(original_sig, custom=middle_param, custom_idx=2)

135

print(new_sig) # (a: int, b: str, inserted: str = 'middle', c: float, d: bool = True) -> dict

136

137

# Insert multiple parameters at custom position

138

multi_params = [

139

Parameter('opt1', Parameter.POSITIONAL_OR_KEYWORD, annotation=str),

140

Parameter('opt2', Parameter.POSITIONAL_OR_KEYWORD, default=42, annotation=int)

141

]

142

new_sig2 = add_signature_parameters(original_sig, custom=multi_params, custom_idx=1)

143

print(new_sig2) # (a: int, opt1: str, opt2: int = 42, b: str, c: float, d: bool = True) -> dict

144

```

145

146

#### Automatic Parameter Kind Inference

147

148

```python

149

from makefun import add_signature_parameters

150

from inspect import signature, Parameter

151

152

def base_func(x: int, *, y: str) -> str:

153

"""Function with keyword-only parameter."""

154

return f"{x}: {y}"

155

156

base_sig = signature(base_func)

157

158

# When adding to the beginning, kinds are inferred from first existing parameter

159

new_sig = add_signature_parameters(base_sig, first="prefix: str")

160

print(new_sig) # (prefix: str, x: int, *, y: str) -> str

161

162

# When adding to the end, kinds are inferred from last existing parameter

163

new_sig2 = add_signature_parameters(base_sig, last="suffix: str = '!'")

164

print(new_sig2) # (x: int, *, y: str, suffix: str = '!') -> str

165

166

# Complex example with var-positional

167

def var_func(a: int, *args, **kwargs) -> None:

168

pass

169

170

var_sig = signature(var_func)

171

new_var_sig = add_signature_parameters(var_sig, first="prefix: str")

172

# Results in positional-only for prefix due to *args presence

173

```

174

175

#### Basic Parameter Removal

176

177

```python

178

from makefun import remove_signature_parameters

179

from inspect import signature

180

181

def complex_func(a: int, b: str, c: float = 1.0, d: bool = True, *, e: str = "default") -> dict:

182

return {"a": a, "b": b, "c": c, "d": d, "e": e}

183

184

original_sig = signature(complex_func)

185

186

# Remove single parameter

187

simplified_sig = remove_signature_parameters(original_sig, "c")

188

print(simplified_sig) # (a: int, b: str, d: bool = True, *, e: str = 'default') -> dict

189

190

# Remove multiple parameters

191

minimal_sig = remove_signature_parameters(original_sig, "c", "d", "e")

192

print(minimal_sig) # (a: int, b: str) -> dict

193

```

194

195

#### Combined Operations

196

197

```python

198

from makefun import add_signature_parameters, remove_signature_parameters

199

from inspect import signature

200

201

def original_func(old_param: int, deprecated_arg: str, x: float, y: bool = True) -> str:

202

return f"Result: {old_param}, {deprecated_arg}, {x}, {y}"

203

204

original_sig = signature(original_func)

205

206

# First remove deprecated parameters

207

cleaned_sig = remove_signature_parameters(original_sig, "old_param", "deprecated_arg")

208

print(cleaned_sig) # (x: float, y: bool = True) -> str

209

210

# Then add new parameters

211

modernized_sig = add_signature_parameters(cleaned_sig,

212

first="config: dict",

213

last="verbose: bool = False")

214

print(modernized_sig) # (config: dict, x: float, y: bool = True, verbose: bool = False) -> str

215

```

216

217

#### Working with Complex Signatures

218

219

```python

220

from makefun import add_signature_parameters, remove_signature_parameters

221

from inspect import signature, Parameter

222

223

def complex_original(a: int, b: str = "default", *args, c: float, d: bool = True, **kwargs) -> dict:

224

"""Function with all parameter types."""

225

return {"a": a, "b": b, "args": args, "c": c, "d": d, "kwargs": kwargs}

226

227

original_sig = signature(complex_original)

228

229

# Remove some parameters

230

modified_sig = remove_signature_parameters(original_sig, "b", "d")

231

print(modified_sig) # (a: int, *args, c: float, **kwargs) -> dict

232

233

# Add parameters respecting the existing structure

234

final_sig = add_signature_parameters(modified_sig,

235

first="version: str = '1.0'", # Before positional

236

last="timeout: int = 30") # After keyword-only

237

print(final_sig) # (version: str = '1.0', a: int, *args, c: float, timeout: int = 30, **kwargs) -> dict

238

```

239

240

#### Error Handling

241

242

```python

243

from makefun import add_signature_parameters, remove_signature_parameters

244

from inspect import signature

245

246

def sample_func(x: int, y: str) -> str:

247

return f"{x}: {y}"

248

249

sample_sig = signature(sample_func)

250

251

# Duplicate parameter name error

252

try:

253

add_signature_parameters(sample_sig, first="x: float") # 'x' already exists

254

except ValueError as e:

255

print(f"Duplicate parameter error: {e}")

256

257

# Parameter not found error

258

try:

259

remove_signature_parameters(sample_sig, "nonexistent_param")

260

except KeyError as e:

261

print(f"Parameter not found error: {e}")

262

```

263

264

### Integration with Function Creation

265

266

These utilities are commonly used with `create_function` and other makefun functions:

267

268

```python

269

from makefun import add_signature_parameters, create_function

270

from inspect import signature

271

272

def base_implementation(config, x, y, debug):

273

if debug:

274

print(f"Config: {config}, Processing x={x}, y={y}")

275

return x + y

276

277

def simple_func(x: int, y: int) -> int:

278

"""Simple addition function."""

279

return x + y

280

281

# Get base signature and enhance it

282

base_sig = signature(simple_func)

283

enhanced_sig = add_signature_parameters(base_sig,

284

first="config: dict = {}",

285

last="debug: bool = False")

286

287

# Create new function with enhanced signature

288

enhanced_func = create_function(enhanced_sig, base_implementation,

289

func_name="enhanced_addition")

290

291

print(enhanced_func(5, 3)) # 8 (basic usage)

292

print(enhanced_func(5, 3, debug=True)) # 8 with debug output

293

print(enhanced_func({"mode": "fast"}, 5, 3)) # 8 with config

294

```

295

296

### Practical Applications

297

298

#### API Versioning

299

300

```python

301

from makefun import remove_signature_parameters, add_signature_parameters

302

from inspect import signature

303

304

def api_v1(data: dict, format: str = "json", deprecated_param: bool = True) -> dict:

305

"""Original API version."""

306

return {"version": "v1", "data": data, "format": format}

307

308

# Create v2 API signature by removing deprecated parameter and adding new ones

309

v1_sig = signature(api_v1)

310

v2_base = remove_signature_parameters(v1_sig, "deprecated_param")

311

v2_sig = add_signature_parameters(v2_base, last=["validate: bool = True", "timeout: int = 30"])

312

313

print(v2_sig) # (data: dict, format: str = 'json', validate: bool = True, timeout: int = 30) -> dict

314

```

315

316

#### Configuration Management

317

318

```python

319

from makefun import add_signature_parameters

320

from inspect import signature

321

322

def core_processor(data: list) -> dict:

323

"""Core data processing logic."""

324

return {"processed": len(data), "items": data}

325

326

# Add configuration parameters for different environments

327

base_sig = signature(core_processor)

328

329

# Development environment - add debugging

330

dev_sig = add_signature_parameters(base_sig,

331

first="debug: bool = True",

332

last="log_level: str = 'DEBUG'")

333

334

# Production environment - add performance monitoring

335

prod_sig = add_signature_parameters(base_sig,

336

first="monitor: bool = True",

337

last=["timeout: int = 300", "retries: int = 3"])

338

339

print("Development:", dev_sig)

340

print("Production:", prod_sig)

341

```