Skip to content

Pillow >=12 breaks pil_to_numpy() via private PIL.Image API arity change #3782

Description

@bjoernellens1

Description

nerfstudio/data/utils/data_utils.py's pil_to_numpy() calls PIL.Image._getencoder(...).setimage(im.im) directly — a private, undocumented API used as a fast-path replacement for Image.tobytes(). Pillow 12 changed the arity/signature of this private encoder API, so this call breaks with a fresh Pillow install.

pyproject.toml's Pillow>=10.3.0 pin is open-ended, so a plain pip install nerfstudio (or any fresh environment resolve) can pull in Pillow 12 and hit this immediately — it's not a hypothetical edge case, it broke a from-scratch install during ROCm porting work on this fork.

Reproduction

Fresh install with no upper Pillow bound resolves to Pillow >=12, then any code path touching pil_to_numpy() (mask loading, at minimum — see call site at data_utils.py:68) raises at that call.

Root cause

Image._getencoder(im.mode, "raw", im.mode) followed by e.setimage(im.im) bypasses PIL's own public tobytes()/frombytes() path, presumably for performance (avoiding an intermediate bytes copy). Pillow 12's internal encoder object's setimage() no longer accepts the same arguments this code assumes.

Suggested fix

Two options, in order of preference:

  1. A source-level fix: reimplement pil_to_numpy() against Pillow 12's actual current private encoder signature (need to check exactly what changed), or drop the private-API fast path entirely in favor of np.asarray(im) / im.tobytes() + np.frombuffer(...), accepting whatever performance difference that has.
  2. A minimal mitigation: tighten the pyproject.toml pin to Pillow<12 until a real fix lands, following the precedent of past Pillow-compatibility pins in this repo (e.g. Fix core tests with Pillow>=10.3.0 #3034, Fix pillow version to avoid error with ANTIALIAS (Fix #2378) #2446).

We worked around this in our own fork with a Pillow<12 pin at the Docker image level (not in pyproject.toml itself), which isn't upstreamable as a real fix — flagging this here rather than opening a PR with just the same band-aid, since a maintainer may prefer the source-level fix.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions