Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Frozen benedict allows deleting nested keys through root keypath APIs

Open
#634 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
Half a day
Newbie friendliness
62/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
data

Research direction

Start with the existing frozen check on keypath assignment in the public benedict class, then trace how del, pop and the keylist path reach KeylistDict and BaseDict, which skip that check. Reproduce with the two snippets in the report and read test_freeze_prevents_setitem_keypath as the model for a new test. Done means deletion and pop on a frozen root raise TypeError and leave contents unchanged, while a separately obtained child stays mutable.

Written by the indexing model from the issue text.

Description

Python version

CPython 3.12.14 on Linux.

Package version

0.40.0, reproduced from main at c4c8a58d517b4ceaa21b6d7529afe1527446100e.

Current behavior (bug description)

Root keypath assignment on a frozen benedict raises TypeError, but deletion and pop through the same root object still remove nested values:

from benedict import benedict

d = benedict({"a": {"b": 1}}).freeze()
del d["a.b"]
print(d)  # {'a': {}}

d = benedict({"a": {"b": 1}}).freeze()
print(d.pop("a.b"))  # 1
print(d)  # {'a': {}}

By comparison, benedict({"a": {"b": 1}}).freeze()["a.b"] = 2 raises TypeError. That behavior is already covered by test_freeze_prevents_setitem_keypath from the original freeze implementation.

The same deletion inconsistency occurs with keylists, list indexes such as values[0], and a custom keypath separator.

Expected behavior

Deletion and pop invoked on a frozen root benedict should check that object's frozen state, consistently with its existing keypath assignment behavior. A failed operation should leave its contents unchanged. pop with a default should follow the same rule as the existing top-level frozen pop behavior.

The documented shallow freeze remains useful: a separately obtained child such as d["a"] should remain mutable. This report concerns the root keypath API; it does not request recursively frozen children.

KeylistDict resolves the nested parent and deletes or pops directly from it, so the root BaseDict check is skipped. Checking at the public benedict layer, where the keypath assignment check already lives, would keep the change limited to this API.

Related #613/#614 concern deriving new dictionaries from a frozen source, rather than deleting values from it.

Disclosure: reproduced and investigated with Codex. No human review is claimed.

Dominant language
Python
Stars
1.6k
Forks
63
Avg merge
1d 23h
Merged PRs (30d)
21

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from fabiocaccamo/python-benedict

All issues in fabiocaccamo/python-benedict

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.