1- import os
2- import unittest
3- import clr
4-
5- # Import required .NET namespaces
6- clr .AddReference ("System" )
7- clr .AddReference ("System.IO" )
8- from System import IDisposable
1+ import pytest
2+
93from System .IO import MemoryStream , FileStream , FileMode , File , Path , StreamWriter
104
11- class DisposableContextManagerTests (unittest .TestCase ):
12- """Tests for Python's context manager protocol with .NET IDisposable objects"""
13-
14- def test_memory_stream_context_manager (self ):
15- """Test that MemoryStream can be used as a context manager"""
16- data = bytes ([1 , 2 , 3 , 4 , 5 ])
17-
18- # Using with statement with MemoryStream
19- with MemoryStream () as stream :
20- # Convert Python bytes to .NET byte array for proper writing
21- from System import Array , Byte
22- dotnet_bytes = Array [Byte ](data )
23- stream .Write (dotnet_bytes , 0 , len (dotnet_bytes ))
24-
25- self .assertEqual (5 , stream .Length )
26- stream .Position = 0
27-
28- # Create a .NET byte array to read into
29- buffer = Array [Byte ](5 )
30- stream .Read (buffer , 0 , 5 )
31-
32- # Convert back to Python bytes for comparison
33- result = bytes (buffer )
34- self .assertEqual (data , result )
35-
36- # The stream should be disposed (closed) after the with block
37- with self .assertRaises (Exception ):
38- stream .Position = 0 # This should fail because the stream is closed
39-
40- def test_file_stream_context_manager (self ):
41- """Test that FileStream can be used as a context manager"""
42- # Create a temporary file path
43- temp_path = Path .Combine (Path .GetTempPath (), Path .GetRandomFileName ())
44-
45- try :
46- # Write data to the file using with statement
47- data = "Hello, context manager!"
48- with FileStream (temp_path , FileMode .Create ) as fs :
49- writer = StreamWriter (fs )
50- writer .Write (data )
51- writer .Flush ()
52-
53- # Verify the file was written and stream was closed
54- self .assertTrue (File .Exists (temp_path ))
55- content = File .ReadAllText (temp_path )
56- self .assertEqual (data , content )
57-
58- # The stream should be disposed after the with block
59- with self .assertRaises (Exception ):
60- fs .Position = 0 # This should fail because the stream is closed
61- finally :
62- # Clean up
63- if File .Exists (temp_path ):
64- File .Delete (temp_path )
65-
66- def test_disposable_in_multiple_contexts (self ):
67- """Test that using .NET IDisposable objects in multiple contexts works correctly"""
68- # Create multiple streams and check that they're all properly disposed
69-
70- # Create a list to track if streams were properly disposed
71- # (we'll check this by trying to access the stream after disposal)
72- streams_disposed = [False , False ]
73-
74- # Use nested context managers with .NET IDisposable objects
75- with MemoryStream () as outer_stream :
76- # Write some data to the outer stream
77- from System import Array , Byte
78- outer_data = Array [Byte ]([10 , 20 , 30 ])
79- outer_stream .Write (outer_data , 0 , len (outer_data ))
80-
81- # Check that the outer stream is usable
82- self .assertEqual (3 , outer_stream .Length )
83-
84- with MemoryStream () as inner_stream :
85- # Write different data to the inner stream
86- inner_data = Array [Byte ]([40 , 50 , 60 , 70 ])
87- inner_stream .Write (inner_data , 0 , len (inner_data ))
88-
89- # Check that the inner stream is usable
90- self .assertEqual (4 , inner_stream .Length )
91-
92- # Try to use the inner stream - should fail because it's disposed
93- try :
94- inner_stream .Position = 0
95- except Exception :
96- streams_disposed [1 ] = True
97-
98- # Try to use the outer stream - should fail because it's disposed
5+
6+ def test_memory_stream_context_manager ():
7+ """Test that MemoryStream can be used as a context manager"""
8+ data = bytes ([1 , 2 , 3 , 4 , 5 ])
9+
10+ with MemoryStream () as stream :
11+ # Convert Python bytes to .NET byte array for proper writing
12+ from System import Array , Byte
13+
14+ dotnet_bytes = Array [Byte ](data )
15+ stream .Write (dotnet_bytes , 0 , len (dotnet_bytes ))
16+
17+ assert stream .Length == 5
18+ stream .Position = 0
19+
20+ # Create a .NET byte array to read into
21+ buffer = Array [Byte ](5 )
22+ stream .Read (buffer , 0 , 5 )
23+
24+ # Convert back to Python bytes for comparison
25+ result = bytes (buffer )
26+ assert result == data
27+
28+ # The stream should be disposed (closed) after the with block
29+ with pytest .raises (Exception ):
30+ stream .Position = 0 # This should fail because the stream is closed
31+
32+
33+ def test_file_stream_context_manager (tmpdir : str ):
34+ """Test that FileStream can be used as a context manager"""
35+ # Create a temporary file path
36+ temp_path = Path .Combine (str (tmpdir ), Path .GetRandomFileName ())
37+
38+ try :
39+ # Write data to the file using with statement
40+ data = "Hello, context manager!"
41+ with FileStream (temp_path , FileMode .Create ) as fs :
42+ writer = StreamWriter (fs )
43+ writer .Write (data )
44+ writer .Flush ()
45+
46+ # Verify the file was written and stream was closed
47+ assert File .Exists (temp_path )
48+ content = File .ReadAllText (temp_path )
49+ assert content == data
50+
51+ # The stream should be disposed after the with block
52+ with pytest .raises (Exception ):
53+ fs .Position = 0 # This should fail because the stream is closed
54+ finally :
55+ # Clean up
56+ if File .Exists (temp_path ):
57+ File .Delete (temp_path )
58+
59+
60+ def test_disposable_in_multiple_contexts ():
61+ """Test that using .NET IDisposable objects in multiple contexts works correctly"""
62+ # Create multiple streams and check that they're all properly disposed
63+
64+ # Create a list to track if streams were properly disposed
65+ # (we'll check this by trying to access the stream after disposal)
66+ streams_disposed = [False , False ]
67+
68+ # Use nested context managers with .NET IDisposable objects
69+ with MemoryStream () as outer_stream :
70+ # Write some data to the outer stream
71+ from System import Array , Byte
72+
73+ outer_data = Array [Byte ]([10 , 20 , 30 ])
74+ outer_stream .Write (outer_data , 0 , len (outer_data ))
75+
76+ # Check that the outer stream is usable
77+ assert outer_stream .Length == 3
78+
79+ with MemoryStream () as inner_stream :
80+ # Write different data to the inner stream
81+ inner_data = Array [Byte ]([40 , 50 , 60 , 70 ])
82+ inner_stream .Write (inner_data , 0 , len (inner_data ))
83+
84+ # Check that the inner stream is usable
85+ assert inner_stream .Length == 4
86+
87+ # Try to use the inner stream - should fail because it's disposed
9988 try :
100- outer_stream .Position = 0
89+ inner_stream .Position = 0
10190 except Exception :
102- streams_disposed [0 ] = True
103-
104- # Verify both streams were properly disposed
105- self .assertTrue (all (streams_disposed ))
106-
107- def test_exception_handling (self ):
108- """Test that exceptions propagate correctly through the context manager"""
109- with self .assertRaises (ValueError ):
110- with MemoryStream () as stream :
111- raise ValueError ("Test exception" )
112-
113- # Stream should be disposed despite the exception
114- with self .assertRaises (Exception ):
115- stream .Position = 0
116-
117- if __name__ == "__main__" :
118- unittest .main ()
91+ streams_disposed [1 ] = True
92+
93+ # Try to use the outer stream - should fail because it's disposed
94+ try :
95+ outer_stream .Position = 0
96+ except Exception :
97+ streams_disposed [0 ] = True
98+
99+ # Verify both streams were properly disposed
100+ assert all (streams_disposed )
101+
102+
103+ def test_exception_handling ():
104+ """Test that exceptions propagate correctly through the context manager"""
105+ with pytest .raises (ValueError ):
106+ with MemoryStream () as stream :
107+ raise ValueError ("Test exception" )
108+
109+ # Stream should be disposed despite the exception
110+ with pytest .raises (Exception ):
111+ stream .Position = 0
0 commit comments