Skip to content

Check permissions and length in fake os.truncate and os.ftruncate - #1343

Open
kratos0718 wants to merge 2 commits into
pytest-dev:mainfrom
kratos0718:truncate-checks
Open

kratos0718 wants to merge 2 commits into
pytest-dev:mainfrom
kratos0718:truncate-checks

Conversation

@kratos0718

@kratos0718 kratos0718 commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Describe the changes

  • os.truncate() on a read-only file succeeded and emptied it; the real call raises EACCES (checked with is_root() like the other permission checks).
  • os.ftruncate() on a descriptor opened with O_RDONLY truncated the file; POSIX raises EINVAL. Left unchanged under Windows, where I could not check the real behavior.
  • a negative length raised ENOSPC from the size setter; both calls raise EINVAL. os.truncate(fd, ...) now goes through ftruncate, so it gets the same checks.

The new tests also run against the real fs (TEST_REAL_FS=1 passes on macOS and as a non-root user on Linux), and they fail without the change.

Tasks

  • Unit tests added that reproduce the issue or prove feature is working
  • Fix or feature added
  • Entry to release notes added
  • Pre-commit CI shows no errors
  • Unit tests passing
  • For documentation changes: The Read the Docs preview builds and looks as expected

@davidlbaird

Copy link
Copy Markdown
Collaborator

Please add an issue so that this change can be tracked in CHANGES.md.

os.truncate succeeded on a read-only file, os.ftruncate truncated a file
through a descriptor opened read-only, and a negative length raised
ENOSPC. The real calls raise EACCES, EINVAL and EINVAL.
@kratos0718

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and added a CHANGES.md entry under Unreleased that points to this PR (per the suggestion on #1344 that the PR can serve as the reference). I can open a separate issue as well if you prefer.

CPython's Windows os.truncate checks the result of _chsize_s with < 0,
but _chsize_s returns a positive errno, so the error is dropped and the
file is left as it was. os.ftruncate checks != 0 and still raises.
@kratos0718

Copy link
Copy Markdown
Contributor Author

The Windows failures came from the real-fs run: under Windows, os.truncate(path, -1) does not raise, because CPython checks the result of _chsize_s with < 0 while it returns a positive errno (python/cpython#159630). os.ftruncate checks != 0 and does raise. The fake now leaves the file unchanged in that case under Windows, and the test expects that. If the CPython fix lands, this will need a version check.

@mrbean-bremen

Copy link
Copy Markdown
Member

Please rebase and resolve the conflicts - otherwise the tests won't run (seems to be a new behavior).

This branch has not been deployed

No deployments
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.

3 participants