From 4fd6c0301acf32bc9cbbf4a7516888ca06c488c5 Mon Sep 17 00:00:00 2001 From: James Troup Date: Sun, 25 Oct 2026 01:06:48 +0000 Subject: [PATCH] chore(deps): raise Pillow, cryptography, msgpack and pyarrow caps --- pyproject.toml | 10 ++++++---- requirements/base.in | 2 ++ requirements/base.txt | 12 ++++++------ requirements/development.txt | 11 +++++------ requirements/stacklet.txt | 11 +++++------ tests/unit_tests/result_set_test.py | 28 ++++++++++++++++++++++++++++ 6 files changed, 52 insertions(+), 22 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f36a99588d5e..22b9e6d1a75a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ dependencies = [ "flask-cors>=6.0.0, <7.0", "croniter>=0.3.28", "cron-descriptor", - "cryptography>=42.0.4, <47.0.0", + "cryptography>=50.0.2, <51.0.0", "deprecation>=2.1.0, <2.2.0", "flask>=2.2.5, <4.0.0", "flask-appbuilder>=5.0.2,<6", @@ -70,7 +70,7 @@ dependencies = [ # marshmallow>=4 has issues: https://github.com/apache/superset/issues/33162 "marshmallow>=3.0, <4", "marshmallow-union>=0.1", - "msgpack>=1.0.0, <1.1", + "msgpack>=1.2.3, <1.3", "nh3>=0.2.11, <0.3", "numpy>1.23.5, <2.3", "packaging", @@ -82,14 +82,16 @@ dependencies = [ "parsedatetime", "paramiko>=3.4.0", "pgsanity", - "Pillow>=11.0.0, <13", + "Pillow>=13.0.0, <14", # raise floor to match resolved pin "polyline>=2.0.0, <3.0", "pydantic>=2.8.0", "pyparsing>=3.0.6, <4", "python-dateutil", "python-dotenv", # optional dependencies for Flask but required for Superset, see https://flask.palletsprojects.com/en/stable/installation/#optional-dependencies "pygeohash", - "pyarrow>=16.1.0, <19", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693 + # <24: pyarrow 24+ infers uuid.UUID as an Arrow extension type, which needs + # stringify_extension_columns from upstream 543ad04ca0; pyarrow 26+ needs NumPy 2. + "pyarrow>=23.0.1, <24", # before upgrading pyarrow, check that all db dependencies support this, see e.g. https://github.com/apache/superset/pull/34693 "pyyaml>=6.0.0, <7.0.0", "PyJWT>=2.15.1, <3.0", # raise floor to match resolved pin; closes SCA false-positive on 2.4.x-range CVEs already fixed in 2.13.0 "redis>=5.0.0, <6.0", diff --git a/requirements/base.in b/requirements/base.in index 67b216dd999e..d6c19b236aaa 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -27,6 +27,8 @@ filelock>=3.20.3,<4.0.0 # Security: decompression bomb fix (required by aiohttp 3.13.3) brotli>=1.2.0,<2.0.0 numexpr>=2.9.0 +# Security: CVE-2026-34073 (MEDIUM) - Improper Certificate Validation +cryptography>=50.0.2,<51.0.0 # Security: Snyk - XSS vulnerability in Mako templates mako>=1.4.3,<2.0.0 # Security: CVE-2026-27459 - pyopenssl certificate validation diff --git a/requirements/base.txt b/requirements/base.txt index 9fc48a48961b..19370fab8f9d 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -86,8 +86,9 @@ cron-descriptor==1.4.5 # via apache-superset (pyproject.toml) croniter==6.0.0 # via apache-superset (pyproject.toml) -cryptography==46.0.5 +cryptography==50.0.2 # via + # -r requirements/base.in # apache-superset (pyproject.toml) # paramiko # pyopenssl @@ -234,7 +235,7 @@ marshmallow-union==0.1.15 # via apache-superset (pyproject.toml) mdurl==0.1.2 # via markdown-it-py -msgpack==1.0.8 +msgpack==1.2.3 # via apache-superset (pyproject.toml) msgspec==0.19.0 # via flask-session @@ -248,7 +249,6 @@ numpy==1.26.4 # bottleneck # numexpr # pandas - # pyarrow odfpy==1.4.1 # via pandas openapi-schema-validator==0.6.3 @@ -280,7 +280,7 @@ parsedatetime==2.6 # via apache-superset (pyproject.toml) pgsanity==0.2.9 # via apache-superset (pyproject.toml) -pillow==11.3.0 +pillow==13.0.0 # via apache-superset (pyproject.toml) platformdirs==4.3.8 # via requests-cache @@ -292,7 +292,7 @@ prison==0.2.1 # via flask-appbuilder prompt-toolkit==3.0.51 # via click-repl -pyarrow==16.1.0 +pyarrow==23.0.1 # via apache-superset (pyproject.toml) pyasn1==0.6.4 # via @@ -320,7 +320,7 @@ pyjwt==2.15.1 # redis pynacl==1.6.2 # via paramiko -pyopenssl==26.2.0 +pyopenssl==26.4.0 # via # -r requirements/base.in # shillelagh diff --git a/requirements/development.txt b/requirements/development.txt index 8c8d4a4353a6..d0d974151d1a 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -178,7 +178,7 @@ croniter==6.0.0 # via # -c requirements/base-constraint.txt # apache-superset -cryptography==46.0.5 +cryptography==50.0.2 # via # -c requirements/base-constraint.txt # apache-superset @@ -552,7 +552,7 @@ more-itertools==10.8.0 # via # jaraco-classes # jaraco-functools -msgpack==1.0.8 +msgpack==1.2.3 # via # -c requirements/base-constraint.txt # apache-superset @@ -580,7 +580,6 @@ numpy==1.26.4 # pandas # pandas-gbq # prophet - # pyarrow oauthlib==3.2.2 # via requests-oauthlib odfpy==1.4.1 @@ -655,7 +654,7 @@ pgsanity==0.2.9 # via # -c requirements/base-constraint.txt # apache-superset -pillow==11.3.0 +pillow==13.0.0 # via # -c requirements/base-constraint.txt # apache-superset @@ -710,7 +709,7 @@ psycopg2-binary==2.9.9 # via apache-superset py-key-value-aio==0.4.4 # via fastmcp -pyarrow==16.1.0 +pyarrow==23.0.1 # via # -c requirements/base-constraint.txt # apache-superset @@ -778,7 +777,7 @@ pynacl==1.6.2 # via # -c requirements/base-constraint.txt # paramiko -pyopenssl==26.2.0 +pyopenssl==26.4.0 # via # -c requirements/base-constraint.txt # shillelagh diff --git a/requirements/stacklet.txt b/requirements/stacklet.txt index 30f723d95bff..e536f4ace7e3 100644 --- a/requirements/stacklet.txt +++ b/requirements/stacklet.txt @@ -165,7 +165,7 @@ croniter==6.0.0 # via # -c requirements/base-constraint.txt # apache-superset -cryptography==46.0.5 +cryptography==50.0.2 # via # -c requirements/base-constraint.txt # apache-superset @@ -450,7 +450,7 @@ more-itertools==11.1.0 # via # jaraco-classes # jaraco-functools -msgpack==1.0.8 +msgpack==1.2.3 # via # -c requirements/base-constraint.txt # apache-superset @@ -468,7 +468,6 @@ numpy==1.26.4 # apache-superset # bottleneck # pandas - # pyarrow odfpy==1.4.1 # via # -c requirements/base-constraint.txt @@ -520,7 +519,7 @@ pgsanity==0.2.9 # via # -c requirements/base-constraint.txt # apache-superset -pillow==11.3.0 +pillow==13.0.0 # via # -c requirements/base-constraint.txt # apache-superset @@ -551,7 +550,7 @@ psycopg2-binary==2.9.9 # via apache-superset py-key-value-aio==0.4.5 # via fastmcp-slim -pyarrow==16.1.0 +pyarrow==23.0.1 # via # -c requirements/base-constraint.txt # apache-superset @@ -608,7 +607,7 @@ pynacl==1.6.2 # via # -c requirements/base-constraint.txt # paramiko -pyopenssl==26.2.0 +pyopenssl==26.4.0 # via # -c requirements/base-constraint.txt # shillelagh diff --git a/tests/unit_tests/result_set_test.py b/tests/unit_tests/result_set_test.py index 25df635247d1..e2f6f9ffd163 100644 --- a/tests/unit_tests/result_set_test.py +++ b/tests/unit_tests/result_set_test.py @@ -244,3 +244,31 @@ def test_empty_column_names_do_not_rename_explicit_synthetic_names() -> None: df = result_set.to_pandas_df() assert list(df.columns) == ["_col_1", "_col_0"] assert df.iloc[0].tolist() == [10, 20] + + +def test_uuid_column_is_stringified() -> None: + """ + UUID columns must render as readable strings, not raw bytes. + + PyArrow >= 21 infers Python ``uuid.UUID`` values as the canonical ``uuid`` + extension type (16-byte binary) instead of raising while building the array. + That bypasses the stringification fallback, so without explicit handling the + values surface in the results grid as garbled bytes / ``[bytes]``. + ``SupersetResultSet`` must stringify any Arrow extension type. + + Regression test for the pyarrow 20 -> 24 upgrade. + """ + import uuid + + ids = [ + uuid.UUID("f4787a4f-2541-4f8a-9b5e-1e2d3c4b5a6f"), + uuid.UUID("00000000-0000-0000-0000-000000000000"), + ] + data = [(ids[0],), (ids[1],)] + description = [("uuid", "uuid", None, None, None, None, True)] + result_set = SupersetResultSet(data, description, BaseEngineSpec) # type: ignore + + df = result_set.to_pandas_df() + assert df["uuid"].tolist() == [str(i) for i in ids] + # values are readable UUID strings, not raw bytes + assert all(value is None or isinstance(value, str) for value in df["uuid"].tolist())