Skip to content

Conversation

@csm10495
Copy link
Contributor

@csm10495 csm10495 commented Nov 6, 2025

What do these changes do?

Fixes bug where frozenlists can't be pickled.

Are there changes in behavior for the user?

Not directly. Though this fixes a behavior change introduced after 1.6.0

Related issue number

#683

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modifications, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep the list in alphabetical order, the file is sorted by name.
  • Add a new news fragment into the CHANGES folder
    • name it <issue_id>.<category> for example (588.bugfix)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure category is one of the following:
      • .bugfix: Signifying a bug fix.
      • .feature: Signifying a new feature.
      • .breaking: Signifying a breaking change or removal of something public.
      • .doc: Signifying a documentation improvement.
      • .packaging: Signifying a packaging or tooling change that may be relevant to downstreams.
      • .contrib: Signifying an improvement to the contributor/development experience.
      • .misc: Anything that does not fit the above; usually, something not of interest to users.
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."

@codecov
Copy link

codecov bot commented Nov 7, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.35%. Comparing base (b51a6d0) to head (861e60d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #718      +/-   ##
==========================================
+ Coverage   94.90%   95.35%   +0.44%     
==========================================
  Files          10       10              
  Lines         726      796      +70     
  Branches       48       60      +12     
==========================================
+ Hits          689      759      +70     
  Misses         13       13              
  Partials       24       24              
Flag Coverage Δ
CI-GHA 95.22% <100.00%> (+0.46%) ⬆️
MyPy 64.63% <59.25%> (-0.54%) ⬇️
OS-Linux 98.75% <93.93%> (-0.96%) ⬇️
OS-Windows 98.00% <89.39%> (-1.71%) ⬇️
OS-macOS 98.00% <89.39%> (-1.71%) ⬇️
Py-3.10.11 98.00% <89.39%> (-1.71%) ⬇️
Py-3.10.19 98.75% <93.93%> (-0.96%) ⬇️
Py-3.11.14 98.75% <93.93%> (-0.96%) ⬇️
Py-3.11.9 98.00% <89.39%> (-1.71%) ⬇️
Py-3.12.10 98.00% <89.39%> (-1.71%) ⬇️
Py-3.12.12 98.75% <93.93%> (-0.96%) ⬇️
Py-3.13.8 98.00% <89.39%> (-1.71%) ⬇️
Py-3.13.9 98.75% <93.93%> (-0.96%) ⬇️
Py-3.13.9t 98.75% <93.93%> (-0.96%) ⬇️
Py-3.14.0 98.75% <93.93%> (-0.96%) ⬇️
Py-3.14.0t 98.75% <93.93%> (-0.96%) ⬇️
Py-3.9.13 98.00% <89.39%> (-1.71%) ⬇️
Py-3.9.24 98.75% <93.93%> (-0.96%) ⬇️
Py-pypy3.10.16-7.3.19 96.00% <81.81%> (-2.82%) ⬇️
Py-pypy3.9.19-7.3.16 96.00% <81.81%> (-2.82%) ⬇️
VM-macos-latest 98.00% <89.39%> (-1.71%) ⬇️
VM-ubuntu-latest 98.75% <93.93%> (-0.96%) ⬇️
VM-windows-11-arm 98.00% <89.39%> (-1.71%) ⬇️
VM-windows-latest 98.00% <89.39%> (-1.71%) ⬇️
pytest 98.75% <93.93%> (-0.96%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@webknjaz webknjaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to introduce snapshot testing — a mechanic allowing us to be sure that pickling/unpickling remains working across different versions of frozenlist. The idea is that they'd be stored in-repo and so pickles created now would keep being checked for years to come. Multidict has something like that but it's too DIY.

Could you try some of the proper plugins?

syrupy and inline-snapshot look quite active. But since I haven't played with them, I can't tell which one would feel more organic to use. Hence the need for some research.

@csm10495
Copy link
Contributor Author

csm10495 commented Nov 8, 2025

I think this needs to introduce snapshot testing — a mechanic allowing us to be sure that pickling/unpickling remains working across different versions of frozenlist. The idea is that they'd be stored in-repo and so pickles created now would keep being checked for years to come. Multidict has something like that but it's too DIY.

Could you try some of the proper plugins?

syrupy and inline-snapshot look quite active. But since I haven't played with them, I can't tell which one would feel more organic to use. Hence the need for some research.

I'm not fully sure I follow here. Pickling is safe when the serialized data is sent to newer python versions, but not necessarily older ones. I don't think we have a guarantee that we can pickle to binary then unpickle years from now if the structure changes. What types of guarantees are you looking to test?

@webknjaz
Copy link
Member

webknjaz commented Nov 8, 2025

What types of guarantees are you looking to test?

Mostly that a pickle created with older frozenlist can be unpickled into the same structure with a newer one. Do you think it's an overkill for now?

@webknjaz webknjaz closed this in #719 Nov 8, 2025
@webknjaz
Copy link
Member

webknjaz commented Nov 8, 2025

Looks like GH autoclosed this because of the keyword 😂. Reopening.

@webknjaz webknjaz reopened this Nov 8, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds pickle and deepcopy support to FrozenList, enabling it to be used with multiprocessing. The implementation adds __reduce__ and __deepcopy__ methods to both the pure Python (PyFrozenList) and Cython (CFrozenList) implementations, with proper handling of the frozen state and circular references.

Key changes:

  • Implemented __reduce__ and __deepcopy__ methods for both PyFrozenList and CFrozenList
  • Added comprehensive tests for deepcopy with circular references and pickling
  • Added contributor and changelog entries

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
frozenlist/init.py Added __deepcopy__ and __reduce__ methods to PyFrozenList, plus helper function _reconstruct_pyfrozenlist for unpickling
frozenlist/_frozenlist.pyx Added __deepcopy__, __reduce__, and __setstate__ methods to the Cython FrozenList implementation
tests/test_frozenlist.py Added tests for deepcopy with circular frozen lists and pickling with both frozen and unfrozen states
CONTRIBUTORS.txt Added Charles Machalow to the contributors list
CHANGES/718.bugfix.rst Added changelog entry documenting the pickle support bugfix
docs/spelling_wordlist.txt Added "unpickled" to the spelling wordlist
CHANGES/650.contrib Reformatted multi-line entry to single line (incidental change)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@csm10495
Copy link
Contributor Author

csm10495 commented Nov 9, 2025

What types of guarantees are you looking to test?

Mostly that a pickle created with older frozenlist can be unpickled into the same structure with a newer one. Do you think it's an overkill for now?

I think its overkill since as long as the physical structure of frozenlist doesn't change in a non compatible way (like internal property names changing) it would be forwards compatible via pickle. In terms of other cases: I don't think libraries typically guarantee pickling cross versions anyways.

The big use case is for serialization by multiprocessing.

csm10495 and others added 6 commits November 8, 2025 17:27
Add contributors / changes updates

Add missing file
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <[email protected]>
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <[email protected]>
csm10495 and others added 2 commits November 8, 2025 17:28
Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <[email protected]>
@csm10495 csm10495 requested a review from webknjaz November 9, 2025 02:07
@Dreamsorcerer
Copy link
Member

A forward compatibility test would be nice (though I won't insist). Such a test would look something like this:
https://github.com/aio-libs/aiohttp/blob/056d9297b2cb96c83466a3eaac3055acd9432229/tests/test_cookiejar.py#L1030

@csm10495
Copy link
Contributor Author

csm10495 commented Nov 9, 2025

A forward compatibility test would be nice (though I won't insist). Such a test would look something like this: https://github.com/aio-libs/aiohttp/blob/056d9297b2cb96c83466a3eaac3055acd9432229/tests/test_cookiejar.py#L1030

I'm not a huge fan of it but I'll add one. I'm don't think there are guarantees for binary format cross version normally.

…r memo checking in deepcopy, use better way for self-including check test
@Dreamsorcerer
Copy link
Member

Dreamsorcerer commented Nov 9, 2025

I'm not a huge fan of it but I'll add one. I'm don't think there are guarantees for binary format cross version normally.

Yeah, unfortunately, that test comes from users complaining when we broke forward compatibility. We won't guarantee it, but we can atleast avoid it in patch releases and warn them in the changelog.

… a bit more natively.

Make the testing a bit smarter to auto skip CFrozenList tests if they don't apply.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants