Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
OpenDAS
vllm_cscc
Commits
ada6f91d
Unverified
Commit
ada6f91d
authored
Jan 06, 2026
by
Nikhil G
Committed by
GitHub
Jan 06, 2026
Browse files
Fix RecursionError in MediaWithBytes unpickling (#31191)
Signed-off-by:
Nikhil Ghosh
<
nikhil@anyscale.com
>
parent
8becf146
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
39 additions
and
1 deletion
+39
-1
tests/multimodal/test_image.py
tests/multimodal/test_image.py
+33
-0
tools/pre_commit/check_pickle_imports.py
tools/pre_commit/check_pickle_imports.py
+1
-0
vllm/multimodal/base.py
vllm/multimodal/base.py
+5
-1
No files found.
tests/multimodal/test_image.py
View file @
ada6f91d
# SPDX-License-Identifier: Apache-2.0
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import
pickle
from
pathlib
import
Path
from
pathlib
import
Path
import
numpy
as
np
import
numpy
as
np
import
pytest
import
pytest
from
PIL
import
Image
,
ImageChops
from
PIL
import
Image
,
ImageChops
from
vllm.multimodal.base
import
MediaWithBytes
from
vllm.multimodal.image
import
ImageMediaIO
,
convert_image_mode
from
vllm.multimodal.image
import
ImageMediaIO
,
convert_image_mode
pytestmark
=
pytest
.
mark
.
cpu_test
pytestmark
=
pytest
.
mark
.
cpu_test
...
@@ -157,3 +159,34 @@ def test_rgba_background_color_validation():
...
@@ -157,3 +159,34 @@ def test_rgba_background_color_validation():
ImageMediaIO
(
rgba_background_color
=
(
0
,
0
,
0
))
# Should not raise
ImageMediaIO
(
rgba_background_color
=
(
0
,
0
,
0
))
# Should not raise
ImageMediaIO
(
rgba_background_color
=
[
255
,
255
,
255
])
# Should not raise
ImageMediaIO
(
rgba_background_color
=
[
255
,
255
,
255
])
# Should not raise
ImageMediaIO
(
rgba_background_color
=
(
128
,
128
,
128
))
# Should not raise
ImageMediaIO
(
rgba_background_color
=
(
128
,
128
,
128
))
# Should not raise
def
test_media_with_bytes_pickle_roundtrip
():
"""Regression test for pickle/unpickle of MediaWithBytes.
Verifies that MediaWithBytes can be pickled and unpickled without
RecursionError. See: https://github.com/vllm-project/vllm/issues/30818
"""
original_image
=
Image
.
open
(
ASSETS_DIR
/
"image1.png"
).
convert
(
"RGB"
)
original_bytes
=
b
"test_bytes_data"
wrapper
=
MediaWithBytes
(
media
=
original_image
,
original_bytes
=
original_bytes
)
# Verify attribute delegation works before pickling
assert
wrapper
.
width
==
original_image
.
width
assert
wrapper
.
height
==
original_image
.
height
assert
wrapper
.
mode
==
original_image
.
mode
# Pickle and unpickle (this would cause RecursionError before the fix)
pickled
=
pickle
.
dumps
(
wrapper
)
unpickled
=
pickle
.
loads
(
pickled
)
# Verify the unpickled object works correctly
assert
unpickled
.
original_bytes
==
original_bytes
assert
unpickled
.
media
.
width
==
original_image
.
width
assert
unpickled
.
media
.
height
==
original_image
.
height
# Verify attribute delegation works after unpickling
assert
unpickled
.
width
==
original_image
.
width
assert
unpickled
.
height
==
original_image
.
height
assert
unpickled
.
mode
==
original_image
.
mode
tools/pre_commit/check_pickle_imports.py
View file @
ada6f91d
...
@@ -27,6 +27,7 @@ ALLOWED_FILES = {
...
@@ -27,6 +27,7 @@ ALLOWED_FILES = {
"vllm/distributed/device_communicators/shm_broadcast.py"
,
"vllm/distributed/device_communicators/shm_broadcast.py"
,
"vllm/distributed/device_communicators/shm_object_storage.py"
,
"vllm/distributed/device_communicators/shm_object_storage.py"
,
"vllm/utils/hashing.py"
,
"vllm/utils/hashing.py"
,
"tests/multimodal/test_image.py"
,
"tests/tokenizers_/test_hf.py"
,
"tests/tokenizers_/test_hf.py"
,
"tests/utils_/test_hashing.py"
,
"tests/utils_/test_hashing.py"
,
"benchmarks/kernels/graph_machete_bench.py"
,
"benchmarks/kernels/graph_machete_bench.py"
,
...
...
vllm/multimodal/base.py
View file @
ada6f91d
...
@@ -34,7 +34,11 @@ class MediaWithBytes(Generic[_T]):
...
@@ -34,7 +34,11 @@ class MediaWithBytes(Generic[_T]):
def
__getattr__
(
self
,
name
:
str
):
def
__getattr__
(
self
,
name
:
str
):
"""Delegate attribute access to the underlying media object."""
"""Delegate attribute access to the underlying media object."""
# This is only called when the attribute is not found on self
# Guard against recursion during unpickling when media isn't set yet.
# pickle creates objects without calling __init__, so self.media may
# not exist when __getattr__ is called for methods like __setstate__.
if
"media"
not
in
self
.
__dict__
:
raise
AttributeError
(
name
)
return
getattr
(
self
.
media
,
name
)
return
getattr
(
self
.
media
,
name
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment