Skip to content

feat: implement __replace__ on BaseContainer for copy.replace (#1920) - #2568

Closed
hamid-digitalmarketer wants to merge 2 commits into
dry-python:masterfrom
hamid-digitalmarketer:feat/issue-1920-copy-replace-container
Closed

hamid-digitalmarketer wants to merge 2 commits into
dry-python:masterfrom
hamid-digitalmarketer:feat/issue-1920-copy-replace-container

Conversation

@hamid-digitalmarketer

Copy link
Copy Markdown

Summary

Fixes #1920

Problem

Python 3.13 introduced copy.replace(obj, **changes) which relies on the __replace__() protocol method. Currently, BaseContainer does not define __replace__, preventing users from using copy.replace on containers like Result, Maybe, IO, etc.

Solution

  • Implemented __replace__(self: _ContainerType, **changes: Any) -> _ContainerType on BaseContainer in returns/primitives/container.py:
    • Accepts inner_value (the constructor parameter name) or _inner_value (the slot attribute name) and constructs a new instance of the same type.
    • Raises a descriptive TypeError if unexpected keyword arguments are provided or if both inner_value and _inner_value are specified.
    • Calling without arguments returns an equal copy (self.__class__(self._inner_value)).
  • Implemented specialized __replace__ on _Nothing in returns/maybe.py:
    • Returns self when inner_value is None.
    • Raises a TypeError if a non-None value is supplied to preserve the empty state semantics.

Tests Added

Added tests/test_primitives/test_container/test_base_container/test_replace.py:

  • Property-based testing with Hypothesis verifying replacement with integers and text.
  • Parametrized tests across concrete container types (Success, Failure, Some, IO, Nothing).
  • Error-handling assertions for unexpected keyword arguments and ambiguous parameter values.
  • Standard library copy.replace integration test (conditionally executed on Python 3.13+).

Verification

  • Tested with pytest --no-cov tests/test_primitives/test_container/test_base_container/test_replace.py:
    10 passed, 1 skipped in 0.82s
    

Contributor Direct Contact

For direct communication regarding this contribution, technical questions, collaboration, or follow-up:
Direct Contact / WhatsApp: +923167417135
Please feel free to contact me directly to discuss the implementation or coordinate further improvements.

@hamid-digitalmarketer
hamid-digitalmarketer force-pushed the feat/issue-1920-copy-replace-container branch from c26569f to 9664961 Compare October 29, 2026 10:24
@sobolevn sobolevn closed this Oct 29, 2026
@codspeed

codspeed Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 10.59%

1 warning, 1 note

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

ℹ️ 2 benchmarks have no flamegraph

The flamegraph wasn't generated: the symbols of the profiling trace could not be resolved, because no information about the language frames was collected.

See affected benchmarks

❌ 1 regressed benchmark
✅ 21 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ CPU Simulation test_safe_decorator 67.8 µs 75.8 µs -10.59%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing hamid-digitalmarketer:feat/issue-1920-copy-replace-container (9664961) with master (ea76fb5)

Open in CodSpeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Support copy.replace from 3.13

3 participants