You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Negative truncate lengths raise ENOSPC / ValueError instead of OSError(EINVAL) like the real OS #1372
Negative truncate lengths raise the wrong error under the fake filesystem: the real OS rejects them with OSError(EINVAL), but the fake raises OSError(ENOSPC) on the os.truncate/os.ftruncate paths and a plain ValueError on the file-object path. Code that handles invalid truncates by catching OSError (or by checking errno.EINVAL) behaves differently between the real and fake filesystem.
os.truncate(p, -1) # OSError: [Errno 28] No space left on device: 'f'os.ftruncate(fd, -1) # OSError: [Errno 28] No space left on devicef.truncate(-1) # ValueError: negative size value -1 (not even an OSError)
Root cause
FakeFile._check_positive_int reuses ENOSPC for the negative/non-int case, and FakeOsModule.truncate/ftruncate funnel negative lengths into the size setter.
FakeFileWrapper._truncate_wrapper delegates to the underlying StringIO/BytesIO, which raises ValueError("negative size value -1") — correct for real in-memory streams, but not for a file opened on the (fake) filesystem, where CPython raises OSError(EINVAL).
Real in-memory streams must keep the ValueError (real StringIO.truncate(-1) raises it too), so the fix belongs at the file end of the fake layer, not in the shared StringIO wrapper.
Expected behavior
For a file on the fake filesystem, all three forms should raise OSError with errno.EINVAL and the same message shape as the real OS. I'll send a PR.
Update while looking into this: #1343 (open since September) already covers the os.truncate() and os.ftruncate() parts with the same EINVAL plus permission checks — credit to @kratos0718 for getting there first. I've re-scoped the PR I mentioned to the piece #1343 does not touch: the file-object path, where open(...).truncate(-1) raises ValueError instead of an OSError (see #1373).
Activity
rahul05ranjan commentedon Nov 9, 2026
Update while looking into this: #1343 (open since September) already covers the
os.truncate()andos.ftruncate()parts with the sameEINVALplus permission checks — credit to @kratos0718 for getting there first. I've re-scoped the PR I mentioned to the piece #1343 does not touch: the file-object path, whereopen(...).truncate(-1)raisesValueErrorinstead of anOSError(see #1373).