Skip to content

Commit 5105e31

Browse files
authored
Add with statement feature (#58)
* Add with statement feature * Update Python.swift * Update PythonRuntimeTests.swift * Update Python.swift * Update Python.swift * Update PythonRuntimeTests.swift
1 parent 939019f commit 5105e31

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

PythonKit/Python.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,15 @@ public struct PythonInterface {
721721
public var versionInfo: PythonObject {
722722
return self.import("sys").version_info
723723
}
724+
725+
/// Emulates a Python `with` statement.
726+
/// - Parameter object: A context manager object.
727+
/// - Parameter body: A closure to call on the result of `object.__enter__()`.
728+
public func with(_ object: PythonObject, _ body: (PythonObject) throws -> Void) rethrows {
729+
let yieldValue = object.__enter__()
730+
try body(yieldValue)
731+
yieldValue.__exit__()
732+
}
724733
}
725734

726735
//===----------------------------------------------------------------------===//

Tests/PythonKitTests/PythonRuntimeTests.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,23 @@ class PythonRuntimeTests: XCTestCase {
334334
}
335335
XCTAssertEqual(bytes, otherBytes)
336336
}
337+
338+
/// Tests an emulation of the Python `with` statement.
339+
///
340+
/// Mirrors:
341+
/// ```python
342+
/// with open('temp', 'w') as opened_file:
343+
/// opened_file.write('Contents')
344+
/// with open('temp', 'r') as opened_file:
345+
/// contents = opened_file.read()
346+
/// ```
347+
func testWith() {
348+
Python.with(Python.open("temp", "w")) { opened_file in
349+
opened_file.write("Contents")
350+
}
351+
Python.with(Python.open("temp", "r")) { opened_file in
352+
let contents = opened_file.read()
353+
XCTAssertEqual("Contents", String(contents)!)
354+
}
355+
}
337356
}

0 commit comments

Comments
 (0)