shelve.Shelf.sync() leaves writeback disabled if writing a cached entry fails
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
Research direction
The bug is in Lib/shelve.py, specifically in the Shelf.sync() method. Look at the loop that writes cached entries back and where self.writeback is set. Add a finally block to restore writeback to its original state on any exception. Run the provided test script to verify the fix, and check if there are existing tests for shelve in the test suite (likely Lib/test/test_shelve.py).
Written by the indexing model from the issue text.
Description
Bug report
Bug description:
Shelf.sync() sets self.writeback to False while it writes the cached entries back, and only sets it back to True after the loop. If writing one of the entries raises (for example, a cached object that can no longer be pickled), the exception propagates as expected, but writeback stays False. The shelf keeps working, and later mutations of accessed objects are silently lost:
import shelve
class Unpicklable:
def __reduce__(self):
raise RuntimeError("cannot pickle")
d = {}
s = shelve.Shelf(d, writeback=True)
s["a"] = []
s["a"].append(Unpicklable())
try:
s.sync()
except RuntimeError:
pass
print(s.writeback) # False, expected True
s["a"].clear()
s["b"] = [1]
s["b"].append(2)
s.close()
print(shelve.Shelf(d)["b"]) # [1], expected [1, 2]
The cached entries are still in s.cache after the failure, so the caller could fix the offending object and call sync() again, but by then the shelf is no longer in writeback mode.
Restoring writeback in a finally block would fix this, leaving the cache intact so sync() can be retried.
CPython versions tested on:
3.13, 3.14, 3.15, 3.16, CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-157977
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 36k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 608
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from python/cpython
-
extension-modules topic-socket type-bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
python/cpython#158285 · 4 comments ·
Maintainers usually reply within 1 day
-
3.14: Windows on Arm build fails since windows-11-arm migrated to windows-11-vs2026-armPossibly taken @chris-eibl claimed this 3 days ago. Open3.14 build infra OS-windows
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
python/cpython#158244 · 6 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
docs pending
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
python/cpython#157339 · 10 comments ·
Maintainers usually reply within 1 day
-
stdlib type-feature
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
python/cpython#155601 · 2 comments ·
Maintainers usually reply within 1 day
-
stdlib type-feature
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
python/cpython#153771 · 5 comments ·
Maintainers usually reply within 1 day
Similar issues
-
customer-reported
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Azure/azure-cli#34150 · 1 comment ·
Maintainers usually reply within 1 day
-
community-request
Difficulty 1/5 Under an hour Newbie friendliness 95/100
NVIDIA-NeMo/Curator#2464 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
WeblateOrg/translation-finder#1099 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
trezor/trezor-firmware#7997 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day