Skip to content

Rework internal copy/convert APIs to get rid of ImagingNew2Dirty - #10103

Draft
akx wants to merge 2 commits into
python-pillow:mainfrom
akx:i2nd
Draft

akx wants to merge 2 commits into
python-pillow:mainfrom
akx:i2nd

Conversation

@akx

@akx akx commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

I was looking at documenting some of the internal functions in the wake of looking at #10075 and #10098 and stumbled upon ImagingNew2Dirty and realized... that's not right.

Refs #9910 (which just recently renamed convert2 into convert_into).


The ImagingNew2Dirty internal API was ugly because there was no way to tell whether it had actually allocated new memory or not, and as a result, some conversion functions could free memory that belonged to the caller.

  • ImagingConvert no longer takes an output image; it always returns a newly allocated image. The new ImagingConvertBlock does the same, but allocates a single contiguous block.
  • At the C extension surface, convert_into(image) (used only by ImageTk.PhotoImage.paste) is replaced by convert_block(mode), which returns a new block image converted into the given mode.
  • ImagingCopy2 is renamed to ImagingCopyInto, and only copies into an existing image; ImagingCopy always allocates a new image.

The `ImagingNew2Dirty` internal API was ugly because there was
no way to tell whether it had actually allocated new memory or not,
and as a result, some conversion functions could free memory that
belonged to the caller.

* `ImagingConvert` no longer takes an output image;
  it always returns a newly allocated image.
  The new `ImagingConvertBlock` does the same,
  but allocates a single contiguous block.
* At the C extension surface, `convert_into(image)`
  (used only by `ImageTk.PhotoImage.paste`) is replaced by
  `convert_block(mode)`, which returns a new block image converted
  into the given mode.
* `ImagingCopy2` is renamed to `ImagingCopyInto`,
  and only copies into an existing image;
  `ImagingCopy` always allocates a new image.
@akx

akx commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Hm, @radarhere, now that I think of it: removing new_block means there's no guaranteed-thread-safe way to create a block-allocated image anymore? (as we know from #10082, the global flag is shared between threads...) I wonder if there is new_block usage in the wild.

@radarhere

Copy link
Copy Markdown
Member

As long as the Python API stays the same, it should be fine. The function isn't exactly complex, should we ever need that functionality again and want to restore it.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants