{"record":{"id":"127ab38c76feb4e0","repo":"pandas-dev/pandas","slug":"from-scalars-should-only-raise-valueerror-or-type","errorCode":null,"errorMessage":"_from_scalars should only raise ValueError or TypeError. Consider overriding _from_scalars where appropriate.","messagePattern":"_from_scalars should only raise ValueError or TypeError\\. Consider overriding _from_scalars where appropriate\\.","errorType":"validation","errorClass":"null","httpStatus":null,"severity":"warning","filePath":"pandas/core/arrays/base.py","lineNumber":440,"sourceCode":"        scalars : sequence\n        dtype : ExtensionDtype\n\n        Raises\n        ------\n        TypeError or ValueError\n\n        Notes\n        -----\n        This is called in a try/except block when casting the result of a\n        pointwise operation in ExtensionArray._cast_pointwise_result.\n        \"\"\"\n        try:\n            return cls._from_sequence(scalars, dtype=dtype, copy=False)\n        except (ValueError, TypeError):\n            raise\n        except Exception:\n            warnings.warn(\n                \"_from_scalars should only raise ValueError or TypeError. \"\n                \"Consider overriding _from_scalars where appropriate.\",\n                stacklevel=find_stack_level(),\n            )\n            raise\n\n    def _cast_pointwise_result(self, values) -> ArrayLike:\n        \"\"\"\n        Construct an ExtensionArray after a pointwise operation.\n\n        Cast the result of a pointwise operation (e.g. Series.map) to an\n        array. This is not required to return an ExtensionArray of the same\n        type as self or of the same dtype. It can also return another\n        ExtensionArray of the same \"family\" if you implement multiple\n        ExtensionArrays/Dtypes that are interoperable (e.g. if you have float\n        array with units, this method can return an int array with units).\n\n        If converting to your own ExtensionArray is not possible, this method\n        falls back to returning an array with the default type inference.","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/base.py#L422-L458","documentation":"Emitted as a UserWarning by ExtensionArray._from_scalars when the underlying _from_sequence raises an exception that is neither ValueError nor TypeError. The base implementation wraps _from_sequence and re-raises, warning first because _from_scalars is a strict contract: subclass authors are expected to override it and raise only ValueError/TypeError so _cast_pointwise_result can fall back cleanly.","triggerScenarios":"Writing a custom ExtensionArray whose _from_sequence raises a non-ValueError/TypeError (e.g. NotImplementedError, KeyError, AssertionError) when given pointwise-operation scalars; running Series.map / elementwise ops that route through _cast_pointwise_result on such an array.","commonSituations":"Third-party/pandas-2 extension array implementations that haven't overridden _from_scalars; dtype coercion paths during groupby/apply/map that pass unexpected scalar shapes; hitting an internal assert inside _from_sequence during a pointwise cast.","solutions":["Override _from_scalars in your ExtensionArray subclass to validate scalars and raise only ValueError or TypeError.","Inspect the chained exception (the warning re-raises the original) to find which _from_sequence branch raised the non-conforming error and convert it.","Update/upgrade the third-party extension array package; newer versions typically override _from_scalars.","Filter the warning only as a last resort (warnings.filterwarnings) while reporting the upstream bug."],"exampleFix":"// before\nclass MyArray(ExtensionArray):\n    @classmethod\n    def _from_sequence(cls, scalars, dtype=None, copy=False):\n        raise KeyError('bad scalar')  # non-conforming -> warning\n\n// after\nclass MyArray(ExtensionArray):\n    @classmethod\n    def _from_scalars(cls, scalars, *, dtype):\n        try:\n            return cls._from_sequence(scalars, dtype=dtype, copy=False)\n        except KeyError as err:\n            raise ValueError(str(err)) from err","handlingStrategy":"try-catch","validationCode":"import warnings\nfrom pandas.core.arrays.base import ExtensionArray\n\ndef safe_from_scalars(cls, scalars, dtype):\n    with warnings.catch_warnings():\n        warnings.simplefilter('error', UserWarning)\n        try:\n            return cls._from_scalars(scalars, dtype=dtype)\n        except (ValueError, TypeError):\n            return None  # let _cast_pointwise_result fall back","typeGuard":"def from_scalars_conformant(cls) -> bool:\n    # base _from_scalars wraps _from_sequence; a conformant subclass overrides it\n    return '_from_scalars' in cls.__dict__","tryCatchPattern":"import warnings\nwith warnings.catch_warnings(record=True) as caught:\n    try:\n        result = arr._cast_pointwise_result(values)\n    except Exception:\n        result = None  # fall back to default type inference\nfor w in caught:\n    if '_from_scalars' in str(w.message):\n        # report upstream: subclass must override _from_scalars\n        ...","preventionTips":["Override _from_scalars in every custom ExtensionArray and raise only ValueError/TypeError.","Run your extension array against Series.map / pointwise op tests to surface this early.","Treat the warning as a build failure in CI (warnings.simplefilter('error'))."],"tags":["extensionarray","api-contract","subclass-author","casting","pointwise"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}