Skip to content

fix: Deterministically close file handles in the content linter - #77

Open
uditstocks wants to merge 1 commit into
p2pdotme:mainfrom
uditstocks:fix/lint-content-file-handle
Open

fix: Deterministically close file handles in the content linter#77
uditstocks wants to merge 1 commit into
p2pdotme:mainfrom
uditstocks:fix/lint-content-file-handle

Conversation

@uditstocks

Copy link
Copy Markdown
Contributor

Summary

check_file() in scripts/lint_content.py opened each content file with open(path, encoding="utf-8").read() and never closed the handle, relying on CPython's reference-counting to clean it up implicitly. This PR wraps the read in a with block so the handle is released deterministically, and switches to .splitlines() for cleaner line splitting.

Before

for lineno, line in enumerate(open(path, encoding="utf-8").read().split("\n"), 1):

After

with open(path, encoding="utf-8") as f:
lines = f.read().splitlines()
for lineno, line in enumerate(lines, 1):

Why this matters

Small change, but it removes a real class of fragility from CI-critical tooling:

Removes a latent CI failure. This linter gates every PR. Leaked handles pile up until GC runs, and on some platforms that surfaces as OSError: Too many open files, a red pipeline caused by nothing in the actual diff. with closes each file the moment we're done.

Correct by intent, not by luck. The old code only closed because CPython's refcounting happens to collect the handle right away, a guarantee that doesn't hold on other runtimes (e.g. PyPy). with makes the close explicit and portable.

Safe on failure paths. If an exception is raised mid-read, with still releases the handle; the previous form could leave it open.

Sets the pattern others copy. Foundational tooling gets read and cloned, so the idiomatic form here keeps the anti-pattern from spreading.

Scope

No behavioral change to any lint rule; identical input produces identical output.
Touches a single function; the parsing and validation logic is unchanged.

Testing

Ran the linter locally against content/*.md; results are identical to main.

open(path).read() in check_file() left the file handle open, relying on
CPython refcount cleanup to close it. Wrap the read in a `with` block so
the handle is released deterministically, and use splitlines() in place
of split("\n").
@netlify

netlify Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploy Preview for p2p-documentation ready!

Name Link
🔨 Latest commit 547d94f
🔍 Latest deploy log https://app.netlify.com/projects/p2p-documentation/deploys/6a6579726d677a00082a433f
😎 Deploy Preview https://deploy-preview-77--p2p-documentation.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Shashwat-Shukla

Shashwat-Shukla commented Jul 26, 2026

Copy link
Copy Markdown

good fix on the with block
makes the handle release deterministic instead of relying on CPython's refcount to clean it up. the PyPy callout in the description is a nice touch. clean PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants