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

function-creation.mddocs/

0

# Dynamic Function Creation

1

2

Core functionality for creating functions dynamically from signature specifications. This capability enables runtime generation of functions with precise signature control, proper introspection support, and comprehensive metadata management.

3

4

## Capabilities

5

6

### Function Creation from Signatures

7

8

Creates functions dynamically from string signatures or Signature objects, with full control over metadata and behavior.

9

10

```python { .api }

11

def create_function(

12

func_signature: Union[str, Signature],

13

func_impl: Callable[[Any], Any],

14

func_name: str = None,

15

inject_as_first_arg: bool = False,

16

add_source: bool = True,

17

add_impl: bool = True,

18

doc: str = None,

19

qualname: str = None,

20

co_name: str = None,

21

module_name: str = None,

22

**attrs

23

) -> FunctionType:

24

"""

25

Creates a function with signature func_signature that calls func_impl.

26

27

Parameters:

28

- func_signature: Union[str, Signature]

29

Function signature specification. Can be:

30

- String without 'def': "foo(a, b: int, *args, **kwargs)" or "(a, b: int)"

31

- Signature object from inspect.signature() or manually created

32

- func_impl: Callable[[Any], Any]

33

Implementation function that will be called by generated function

34

- func_name: str, optional

35

Override for __name__ and __qualname__ attributes

36

- inject_as_first_arg: bool, default False

37

If True, inject created function as first positional argument to func_impl

38

- add_source: bool, default True

39

Add __source__ attribute containing generated function source code

40

- add_impl: bool, default True

41

Add __func_impl__ attribute pointing to func_impl

42

- doc: str, optional

43

Docstring for generated function. Defaults to func_impl.__doc__

44

- qualname: str, optional

45

Qualified name for generated function

46

- co_name: str, optional

47

Name for compiled code object

48

- module_name: str, optional

49

Module name for generated function. Defaults to func_impl.__module__

50

- **attrs: dict

51

Additional attributes to set on generated function

52

53

Returns:

54

FunctionType: Generated function with specified signature

55

56

Raises:

57

TypeError: If func_signature has invalid type

58

SyntaxError: If signature string is malformed

59

ValueError: If co_name is invalid

60

"""

61

```

62

63

### Usage Examples

64

65

#### Basic Function Creation from String

66

67

```python

68

from makefun import create_function

69

70

def my_impl(name, age, city="Unknown"):

71

return f"{name} ({age}) from {city}"

72

73

# Create function with specific signature

74

greet = create_function("greet(person_name: str, person_age: int, location: str = 'Unknown')",

75

my_impl)

76

77

print(greet("Alice", 25)) # "Alice (25) from Unknown"

78

print(greet("Bob", 30, "New York")) # "Bob (30) from New York"

79

```

80

81

#### Function Creation from Signature Object

82

83

```python

84

from makefun import create_function

85

from inspect import signature, Signature, Parameter

86

87

def calculator(operation, x, y):

88

operations = {"add": x + y, "sub": x - y, "mul": x * y}

89

return operations.get(operation, "Unknown operation")

90

91

# Create signature object manually

92

params = [

93

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

94

Parameter('a', Parameter.POSITIONAL_OR_KEYWORD, annotation=float),

95

Parameter('b', Parameter.POSITIONAL_OR_KEYWORD, annotation=float)

96

]

97

sig = Signature(parameters=params, return_annotation=float)

98

99

# Generate function with Signature object

100

calc = create_function(sig, calculator, func_name="calculate")

101

print(calc("add", 5.0, 3.0)) # 8.0

102

```

103

104

#### Advanced Metadata Control

105

106

```python

107

from makefun import create_function

108

109

def internal_handler(*args, **kwargs):

110

return f"Processed: {args}, {kwargs}"

111

112

# Create function with extensive metadata customization

113

processor = create_function(

114

"process_data(data: list, options: dict = None, verbose: bool = False)",

115

internal_handler,

116

func_name="process_data",

117

doc="Process data with optional configuration and verbosity control.",

118

qualname="DataProcessor.process_data",

119

module_name="data_processing",

120

add_source=True,

121

add_impl=True,

122

version="1.0",

123

author="Data Team"

124

)

125

126

print(processor.__name__) # "process_data"

127

print(processor.__doc__) # "Process data with optional configuration..."

128

print(processor.__module__) # "data_processing"

129

print(processor.version) # "1.0"

130

print(processor.author) # "Data Team"

131

```

132

133

#### Generator and Coroutine Support

134

135

```python

136

from makefun import create_function

137

import asyncio

138

139

def my_generator(*args, **kwargs):

140

for i in range(3):

141

yield f"Item {i}: {args}, {kwargs}"

142

143

async def my_coroutine(*args, **kwargs):

144

await asyncio.sleep(0.1)

145

return f"Async result: {args}, {kwargs}"

146

147

# Create generator function

148

gen_func = create_function("generate_items(count: int, prefix: str)", my_generator)

149

for item in gen_func(3, "test"):

150

print(item)

151

152

# Create coroutine function

153

async_func = create_function("fetch_data(url: str, timeout: int = 30)", my_coroutine)

154

result = asyncio.run(async_func("https://api.example.com", 60))

155

print(result)

156

```

157

158

#### Lambda Function Generation

159

160

```python

161

from makefun import create_function

162

163

def simple_impl(x, y):

164

return x + y

165

166

# Function name not valid identifier -> creates lambda

167

lambda_func = create_function("123invalid(x, y)", simple_impl)

168

print(lambda_func.__name__) # "<lambda>"

169

170

# Explicit lambda creation

171

lambda_func2 = create_function("(x: int, y: int)", simple_impl, co_name="<lambda>")

172

print(lambda_func2.__name__) # None (lambda functions have no __name__)

173

```

174

175

### Function Argument Handling

176

177

The generated functions automatically handle argument passing to the implementation function:

178

179

- **Keyword Arguments**: Most arguments are passed as keywords when possible for maximum flexibility

180

- **Positional-Only**: Arguments marked as positional-only are passed positionally

181

- **Var-Positional**: `*args` arguments are passed as positional arguments

182

- **Var-Keyword**: `**kwargs` arguments are passed as keyword arguments

183

184

### Signature String Format

185

186

Signature strings support the full Python function signature syntax:

187

188

```python

189

# Basic parameters

190

"func(a, b, c)"

191

192

# Type annotations

193

"func(a: int, b: str, c: float)"

194

195

# Default values

196

"func(a: int, b: str = 'default', c: float = 1.0)"

197

198

# Var-positional and var-keyword

199

"func(a: int, *args, **kwargs)"

200

201

# Keyword-only parameters (Python 3+)

202

"func(a: int, *, b: str, c: float = 1.0)"

203

204

# Positional-only parameters (Python 3.8+)

205

"func(a: int, b: str, /, c: float)"

206

207

# Return type annotation

208

"func(a: int, b: str) -> str"

209

210

# Complex example

211

"process(data: list, /, mode: str, *extra, timeout: float = 30.0, **options) -> dict"

212

```

213

214

### Error Handling

215

216

Common error scenarios and their handling:

217

218

```python

219

from makefun import create_function

220

221

# Invalid signature format

222

try:

223

create_function("invalid syntax here", lambda: None)

224

except SyntaxError as e:

225

print(f"Signature error: {e}")

226

227

# Invalid function name

228

try:

229

create_function("func(x)", lambda x: x, co_name="123invalid")

230

except ValueError as e:

231

print(f"Name error: {e}")

232

233

# Type mismatch

234

try:

235

create_function(123, lambda: None) # Should be str or Signature

236

except TypeError as e:

237

print(f"Type error: {e}")

238

```