-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcontext_manager.py
More file actions
136 lines (101 loc) · 3.9 KB
/
context_manager.py
File metadata and controls
136 lines (101 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python3
"""Example demonstrating context manager usage and resource management.
The LpmTable classes support the context manager protocol, which ensures
proper cleanup of C resources even if an exception occurs.
"""
from ipaddress import IPv4Address, IPv4Network
from liblpm import LpmTableIPv4, LpmClosedError
def basic_context_manager():
"""Basic context manager usage."""
print("Basic context manager usage")
print("-" * 40)
# Resources are automatically cleaned up when exiting the 'with' block
with LpmTableIPv4() as table:
table.insert('192.168.0.0/16', 100)
result = table.lookup('192.168.1.1')
print(f"Lookup result: {result}")
print(f"Table closed inside 'with': {table.closed}")
print(f"Table closed after 'with': {table.closed}")
def exception_safety():
"""Demonstrate exception safety."""
print("\n" + "-" * 40)
print("Exception safety")
print("-" * 40)
table = None
try:
with LpmTableIPv4() as table:
table.insert('192.168.0.0/16', 100)
print("Inserted route, now raising exception...")
raise ValueError("Simulated error")
except ValueError as e:
print(f"Caught exception: {e}")
# Table should still be properly closed
print(f"Table closed despite exception: {table.closed}")
def manual_resource_management():
"""Demonstrate manual resource management without context manager."""
print("\n" + "-" * 40)
print("Manual resource management")
print("-" * 40)
table = LpmTableIPv4()
try:
table.insert('192.168.0.0/16', 100)
result = table.lookup('192.168.1.1')
print(f"Lookup result: {result}")
finally:
table.close()
print("Table manually closed")
# Verify operations fail after close
try:
table.lookup('192.168.1.1')
print("ERROR: Should have raised LpmClosedError")
except LpmClosedError:
print("Correctly raised LpmClosedError after close")
def multiple_close_is_safe():
"""Demonstrate that calling close() multiple times is safe."""
print("\n" + "-" * 40)
print("Multiple close() calls are safe")
print("-" * 40)
table = LpmTableIPv4()
table.insert('192.168.0.0/16', 100)
print("Closing table first time...")
table.close()
print(f"Closed: {table.closed}")
print("Closing table second time (should not error)...")
table.close()
print(f"Still closed: {table.closed}")
print("Closing table third time...")
table.close()
print("No errors!")
def nested_tables():
"""Demonstrate using multiple tables."""
print("\n" + "-" * 40)
print("Nested table usage")
print("-" * 40)
with LpmTableIPv4() as table_v4:
table_v4.insert('192.168.0.0/16', 100)
# Can have multiple tables open simultaneously
with LpmTableIPv4() as table_v4_alt:
table_v4_alt.insert('10.0.0.0/8', 200)
# Look up in both tables
result1 = table_v4.lookup('192.168.1.1')
result2 = table_v4_alt.lookup('10.0.0.1')
print(f"Table 1 lookup: {result1}")
print(f"Table 2 lookup: {result2}")
# table_v4_alt is now closed, but table_v4 is still open
print(f"Inner table closed: {table_v4_alt.closed}")
print(f"Outer table still open: {not table_v4.closed}")
print(f"Both tables now closed: {table_v4.closed and table_v4_alt.closed}")
def main():
"""Run all context manager examples."""
print("liblpm Python Bindings - Context Manager Example")
print("=" * 50)
print()
basic_context_manager()
exception_safety()
manual_resource_management()
multiple_close_is_safe()
nested_tables()
print("\n" + "=" * 50)
print("Context manager examples completed!")
if __name__ == '__main__':
main()