Accept array-like objects in param.Array via __array__ protocol#1114
Open
ghostiee-11 wants to merge 2 commits intoholoviz:mainfrom
Open
Accept array-like objects in param.Array via __array__ protocol#1114ghostiee-11 wants to merge 2 commits intoholoviz:mainfrom
ghostiee-11 wants to merge 2 commits intoholoviz:mainfrom
Conversation
param.Array currently only accepts numpy ndarray instances. With pandas 2.x defaulting to pyarrow-backed string columns, df["col"].values returns an ArrowStringArray which param.Array rejects with a ValueError, even though the object fully supports the numpy array protocol via __array__. This overrides _validate_class_ in Array to also accept objects that implement __array__ or __array_interface__, while still rejecting plain lists, strings, and other non-array types.
There was a problem hiding this comment.
Pull request overview
This PR updates param.Array validation to accept non-ndarray “array-like” objects (e.g. pandas ExtensionArray / pyarrow-backed arrays) via NumPy array protocols, and adds tests to cover the new acceptance/rejection behavior.
Changes:
- Extend
param.Arrayto treat values with__array__/__array_interface__as valid. - Add unit tests ensuring array-like acceptance and list/string rejection.
- Add pandas-focused coverage for ExtensionArray types (Categorical + pyarrow string array when available).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
param/parameters.py | Loosens Array validation to accept array-protocol objects; expands docstring. |
tests/testnumpy.py | Adds tests for __array__, __array_interface__, rejection cases, and pandas ExtensionArray acceptance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
param/parameters.py Outdated
Comment on lines +2255 to +2257
| def _is_array_like(val): | ||
| """Return True if *val* supports the numpy array protocol.""" | ||
| return hasattr(val, '__array__') or hasattr(val, '__array_interface__') |
Comment on lines +2259 to +2264
| def _validate_class_(self, val, class_, is_instance): | ||
| # Accept array-like objects (e.g. pandas ExtensionArray, | ||
| # ArrowStringArray) that support the numpy array protocol. | ||
| if is_instance and not isinstance(val, class_) and self._is_array_like(val): | ||
| return | ||
| super()._validate_class_(val, class_, is_instance) |
param/parameters.py Outdated
Comment on lines +2235 to +2237
| Accepts numpy ``ndarray`` objects as well as array-like objects that | ||
| implement the ``__array__`` protocol (e.g. pandas ``ExtensionArray`` | ||
| subclasses such as ``ArrowStringArray``). |
tests/testnumpy.py Outdated
Comment on lines +157 to +158
| except (ImportError, TypeError): | ||
| pass # pyarrow not installed, skip this sub-test |
- Use getattr with try/except instead of hasattr to handle objects where property access raises non-AttributeError - Verify __array__ is callable, __array_interface__ is not None - serialize: fall back to numpy.asarray(value).tolist() when value lacks .tolist() method - Docstring: mention both __array__ and __array_interface__ protocols - Tests: broaden pyarrow exception catch, add serialize assertions for both the fallback path and pandas ExtensionArray
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
I was building a Panel dashboard that uses
param.Arrayto store label arrays from a pandas DataFrame. With pandas 2.x using pyarrow as the default string backend,df["label"].valuesreturns anArrowStringArrayinstead of a numpy array. This causesparam.Arrayto reject it with aValueError, even though the object fully supports the numpy array protocol.I had to work around this everywhere with
np.array(df[col].tolist())which felt unnecessary since the object already implements__array__.Fix
I overrode
_validate_class_inArrayto also accept objects implementing__array__or__array_interface__, while still rejecting plain lists, strings, and other non-array types.After
Changes
param/parameters.py: Added_is_array_like()static method and_validate_class_()override inArrayto accept objects with__array__or__array_interface__protocoltests/testnumpy.py: Added 5 new tests covering__array__,__array_interface__, plain list rejection, string rejection, and pandas ExtensionArray (Categorical + ArrowStringArray)Test plan
serialize()/tolist()works with ArrowStringArraynp.asarray()round-trip works on stored values