diff --git a/CHANGELOG.md b/CHANGELOG.md index 328847a..b686214 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] - TBD +### Fixed + +- Properly close file descriptors opened by `harfile`. + +## [0.3.1] - 2025-08-17 + ### Added - `HarFile.flush` method. diff --git a/src/harfile/__init__.py b/src/harfile/__init__.py index 91dbbc5..b89b06b 100644 --- a/src/harfile/__init__.py +++ b/src/harfile/__init__.py @@ -53,6 +53,7 @@ class HarFile: _comment: str | None _is_first_entry: bool = True _has_preable: bool = False + _is_managed_fd: bool = False closed: bool = False def __init__( @@ -81,9 +82,13 @@ def open( fd: IO[str] if isinstance(name_or_fd, (str, PathLike)): fd = builtins.open(name_or_fd, "w") + is_managed = True else: fd = name_or_fd - return cls(fd=fd, creator=creator, browser=browser, comment=comment) + is_managed = False + instance = cls(fd=fd, creator=creator, browser=browser, comment=comment) + instance._is_managed_fd = is_managed + return instance def close(self) -> None: """Close the HAR file.""" @@ -94,6 +99,8 @@ def close(self) -> None: self._write_preamble() self._has_preable = True self._write_postscript() + if self._is_managed_fd: + self._fd.close() def flush(self) -> None: self._fd.flush() @@ -109,6 +116,9 @@ def __exit__( ) -> None: if type is None: self.close() + elif self._is_managed_fd: + self._fd.close() + self.closed = True return None def add_entry( diff --git a/tests/test_har.py b/tests/test_har.py index 583ad51..274d830 100644 --- a/tests/test_har.py +++ b/tests/test_har.py @@ -432,13 +432,15 @@ def test_close(): buffer = io.StringIO() with harfile.open(buffer) as har: har.close() + assert har.closed def test_exception(): buffer = io.StringIO() with pytest.raises(ZeroDivisionError): - with harfile.open(buffer): + with harfile.open(buffer) as har: raise ZeroDivisionError + assert har.closed assert buffer.getvalue() == "" @@ -451,7 +453,6 @@ def test_with_comments(): comment="EXAMPLE-3", ): pass - print(buffer.getvalue()) assert ( buffer.getvalue() == """{