0
# Execution and Exception Utilities
1
2
Utilities for code execution, exception handling, and print functionality that work across Python versions. These functions provide unified interfaces for executing code, handling exceptions, and printing output that work identically on Python 2 and 3.
3
4
## Capabilities
5
6
### Code Execution
7
8
Function for executing Python code with proper namespace handling across versions.
9
10
```python { .api }
11
def exec_(_code_: str | CodeType, _globs_: dict | None = None, _locs_: dict | None = None) -> None
12
"""Execute code in the given namespaces."""
13
```
14
15
**Parameters:**
16
- `_code_`: String containing Python code or compiled code object
17
- `_globs_`: Global namespace dictionary (defaults to caller's globals)
18
- `_locs_`: Local namespace dictionary (defaults to caller's locals)
19
20
**Usage Examples:**
21
22
```python
23
import six
24
25
# Execute code string
26
code = """
27
x = 10
28
y = 20
29
result = x + y
30
"""
31
namespace = {}
32
six.exec_(code, namespace)
33
print(namespace['result']) # 30
34
35
# Execute with specific globals and locals
36
global_vars = {'math': __import__('math')}
37
local_vars = {}
38
six.exec_("result = math.pi * 2", global_vars, local_vars)
39
print(local_vars['result']) # 6.283185307179586
40
41
# Execute compiled code
42
compiled_code = compile("print('Hello from exec')", '<string>', 'exec')
43
six.exec_(compiled_code)
44
```
45
46
### Exception Handling
47
48
Functions for raising and reraising exceptions with proper traceback handling.
49
50
```python { .api }
51
def reraise(tp: type[BaseException] | None, value: BaseException | None, tb: TracebackType | None = None) -> None
52
"""Reraise an exception with its original traceback."""
53
54
def raise_from(value: BaseException, from_value: BaseException | None) -> None
55
"""Raise exception from another exception (Python 3 syntax)."""
56
```
57
58
**Usage Examples:**
59
60
```python
61
import six
62
import sys
63
64
# Reraise exception with original traceback
65
def handle_error():
66
try:
67
# Some operation that might fail
68
raise ValueError("Original error")
69
except Exception:
70
exc_info = sys.exc_info()
71
# Do some logging or cleanup
72
print("Handling error...")
73
# Reraise with original traceback
74
six.reraise(*exc_info)
75
76
# Exception chaining (Python 3 style)
77
def process_data(data):
78
try:
79
return int(data)
80
except ValueError as e:
81
new_error = RuntimeError("Failed to process data")
82
six.raise_from(new_error, e) # Chain exceptions
83
84
# Usage
85
try:
86
process_data("invalid")
87
except RuntimeError as e:
88
print(f"Error: {e}")
89
print(f"Caused by: {e.__cause__}") # Original ValueError
90
```
91
92
### Print Function
93
94
Print function with Python 3 semantics that works on both Python versions.
95
96
```python { .api }
97
def print_(*args, **kwargs) -> None
98
"""Print function with Python 3 semantics."""
99
```
100
101
**Keyword Arguments:**
102
- `sep`: String inserted between values (default: ' ')
103
- `end`: String appended after the last value (default: '\n')
104
- `file`: File object to write to (default: sys.stdout)
105
- `flush`: Whether to forcibly flush the stream (default: False)
106
107
**Usage Examples:**
108
109
```python
110
import six
111
import sys
112
113
# Basic printing with custom separator
114
six.print_("A", "B", "C", sep="-") # A-B-C
115
116
# Custom end character
117
six.print_("Loading", end="")
118
six.print_(".", end="")
119
six.print_(".", end="")
120
six.print_(".") # Loading...
121
122
# Print to different file
123
with open("output.txt", "w") as f:
124
six.print_("Hello, file!", file=f)
125
126
# Print to stderr
127
six.print_("Error message", file=sys.stderr)
128
129
# Force flushing (useful for progress indicators)
130
for i in range(5):
131
six.print_(f"Processing {i}", end=" ", flush=True)
132
time.sleep(1)
133
six.print_() # Final newline
134
```
135
136
## Common Usage Patterns
137
138
```python
139
import six
140
import sys
141
import traceback
142
143
# Dynamic code execution with error handling
144
def safe_exec(code_string, context=None):
145
"""Safely execute code with proper error handling."""
146
if context is None:
147
context = {}
148
149
try:
150
six.exec_(code_string, context)
151
return context
152
except Exception as e:
153
six.print_(f"Execution failed: {e}", file=sys.stderr)
154
traceback.print_exc()
155
return None
156
157
# Custom exception handling with reraise
158
class DataProcessor:
159
def __init__(self):
160
self.debug = True
161
162
def process(self, data):
163
try:
164
return self._internal_process(data)
165
except Exception:
166
if self.debug:
167
six.print_("Debug: Processing failed for data:", data, file=sys.stderr)
168
169
# Log the error and reraise with original traceback
170
exc_info = sys.exc_info()
171
self._log_error(*exc_info)
172
six.reraise(*exc_info)
173
174
def _internal_process(self, data):
175
# Simulate some processing that might fail
176
if not data:
177
raise ValueError("Empty data provided")
178
return data.upper()
179
180
def _log_error(self, exc_type, exc_value, exc_tb):
181
six.print_(f"Error logged: {exc_type.__name__}: {exc_value}",
182
file=sys.stderr)
183
184
# Exception chaining for better error context
185
def nested_operation():
186
"""Example of nested operations with exception chaining."""
187
188
def parse_config(config_str):
189
try:
190
return eval(config_str) # Dangerous but for example
191
except SyntaxError as e:
192
parse_error = ValueError(f"Invalid configuration format")
193
six.raise_from(parse_error, e)
194
195
def load_config(filename):
196
try:
197
with open(filename) as f:
198
return parse_config(f.read())
199
except (IOError, OSError) as e:
200
load_error = RuntimeError(f"Failed to load config from {filename}")
201
six.raise_from(load_error, e)
202
except ValueError as e:
203
# Re-raise parse errors with additional context
204
config_error = RuntimeError(f"Configuration error in {filename}")
205
six.raise_from(config_error, e)
206
207
return load_config("config.py")
208
209
# Advanced printing with formatting
210
def progress_printer():
211
"""Example of using print_ for progress indication."""
212
213
def print_progress(current, total, message="Processing"):
214
percent = (current / total) * 100
215
bar_length = 20
216
filled_length = int(bar_length * current // total)
217
bar = '█' * filled_length + '-' * (bar_length - filled_length)
218
219
six.print_(f'\r{message}: |{bar}| {percent:.1f}%',
220
end='', flush=True)
221
222
if current == total:
223
six.print_() # Final newline
224
225
# Simulate progress
226
import time
227
total_items = 10
228
for i in range(total_items + 1):
229
print_progress(i, total_items)
230
time.sleep(0.1)
231
232
# Template execution system
233
class TemplateEngine:
234
"""Simple template engine using exec_."""
235
236
def __init__(self):
237
self.globals = {
238
'six': six,
239
'__builtins__': __builtins__
240
}
241
242
def render(self, template, context=None):
243
if context is None:
244
context = {}
245
246
# Create isolated namespace
247
namespace = self.globals.copy()
248
namespace.update(context)
249
250
# Template processing code
251
template_code = f"""
252
output = []
253
def write(text):
254
output.append(str(text))
255
256
{template}
257
258
result = ''.join(output)
259
"""
260
261
try:
262
six.exec_(template_code, namespace)
263
return namespace['result']
264
except Exception as e:
265
error_msg = f"Template rendering failed: {e}"
266
six.print_(error_msg, file=sys.stderr)
267
raise RuntimeError(error_msg) from e
268
269
# Usage example
270
template = '''
271
write("Hello, ")
272
write(name)
273
write("! You have ")
274
write(count)
275
write(" messages.")
276
'''
277
278
engine = TemplateEngine()
279
result = engine.render(template, {'name': 'Alice', 'count': 5})
280
six.print_(result) # Hello, Alice! You have 5 messages.
281
```