From 77351fd50b2388a9e7b45bacc545c121d7328ad7 Mon Sep 17 00:00:00 2001 From: r0rshark Date: Mon, 13 May 2024 12:48:03 +0200 Subject: [PATCH 1/6] Document Remote Code Execution risk for Dataframe.query and computation.eval --- pandas/core/computation/eval.py | 2 ++ pandas/core/frame.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index c949cfd1bc657..0448b3fc5c3a7 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -193,6 +193,8 @@ def eval( corresponding bitwise operators. :class:`~pandas.Series` and :class:`~pandas.DataFrame` objects are supported and behave as they would with plain ol' Python evaluation. + This allows `eval` to run arbitrary code, which can make you vulnerable to code + injection if you pass user input to this function. Parameters ---------- diff --git a/pandas/core/frame.py b/pandas/core/frame.py index a4decab6e8a2b..623c08e149993 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4472,6 +4472,9 @@ def query( def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. + This function pass the `expr` parameter to :meth:`~pandas.DataFrame.eval`. + This allows `eval` to run arbitrary code, which can make you vulnerable to code + injection if you pass user input to this function. Parameters ---------- From b9424745ee2672476a203b92dd060985a91e9a70 Mon Sep 17 00:00:00 2001 From: r0rshark Date: Mon, 13 May 2024 19:45:26 +0200 Subject: [PATCH 2/6] fix docstring lint --- pandas/core/frame.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 623c08e149993..b34a0b4af0a8b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4472,6 +4472,7 @@ def query( def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. + This function pass the `expr` parameter to :meth:`~pandas.DataFrame.eval`. This allows `eval` to run arbitrary code, which can make you vulnerable to code injection if you pass user input to this function. From 79c603e7cf08d769dd9b27daa51cb98cb27dfd13 Mon Sep 17 00:00:00 2001 From: r0rshark Date: Mon, 13 May 2024 22:28:38 +0200 Subject: [PATCH 3/6] fixed trailing space --- pandas/core/frame.py | 282 ++++++++++++++++++++++++++++--------------- 1 file changed, 185 insertions(+), 97 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index b34a0b4af0a8b..8bf1e6a53491d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1243,7 +1243,8 @@ def to_string( min_rows: int | None = ..., max_colwidth: int | None = ..., encoding: str | None = ..., - ) -> str: ... + ) -> str: + ... @overload def to_string( @@ -1268,7 +1269,8 @@ def to_string( min_rows: int | None = ..., max_colwidth: int | None = ..., encoding: str | None = ..., - ) -> None: ... + ) -> None: + ... @Substitution( header_type="bool or list of str", @@ -1403,7 +1405,9 @@ def style(self) -> Styler: return Styler(self) - _shared_docs["items"] = r""" + _shared_docs[ + "items" + ] = r""" Iterate over (column name, Series) pairs. Iterates over the DataFrame columns, returning a tuple with @@ -1598,10 +1602,12 @@ def __len__(self) -> int: return len(self.index) @overload - def dot(self, other: Series) -> Series: ... + def dot(self, other: Series) -> Series: + ... @overload - def dot(self, other: DataFrame | Index | ArrayLike) -> DataFrame: ... + def dot(self, other: DataFrame | Index | ArrayLike) -> DataFrame: + ... def dot(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: """ @@ -1722,10 +1728,12 @@ def dot(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: raise TypeError(f"unsupported type: {type(other)}") @overload - def __matmul__(self, other: Series) -> Series: ... + def __matmul__(self, other: Series) -> Series: + ... @overload - def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: ... + def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: + ... def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: """ @@ -1952,7 +1960,8 @@ def to_dict( *, into: type[MutableMappingT] | MutableMappingT, index: bool = ..., - ) -> MutableMappingT: ... + ) -> MutableMappingT: + ... @overload def to_dict( @@ -1961,7 +1970,8 @@ def to_dict( *, into: type[MutableMappingT] | MutableMappingT, index: bool = ..., - ) -> list[MutableMappingT]: ... + ) -> list[MutableMappingT]: + ... @overload def to_dict( @@ -1970,7 +1980,8 @@ def to_dict( *, into: type[dict] = ..., index: bool = ..., - ) -> dict: ... + ) -> dict: + ... @overload def to_dict( @@ -1979,7 +1990,8 @@ def to_dict( *, into: type[dict] = ..., index: bool = ..., - ) -> list[dict]: ... + ) -> list[dict]: + ... # error: Incompatible default for argument "into" (default has type "type # [dict[Any, Any]]", argument has type "type[MutableMappingT] | MutableMappingT") @@ -2725,7 +2737,8 @@ def to_markdown( index: bool = ..., storage_options: StorageOptions | None = ..., **kwargs, - ) -> str: ... + ) -> str: + ... @overload def to_markdown( @@ -2736,7 +2749,8 @@ def to_markdown( index: bool = ..., storage_options: StorageOptions | None = ..., **kwargs, - ) -> None: ... + ) -> None: + ... @overload def to_markdown( @@ -2747,7 +2761,8 @@ def to_markdown( index: bool = ..., storage_options: StorageOptions | None = ..., **kwargs, - ) -> str | None: ... + ) -> str | None: + ... def to_markdown( self, @@ -2845,7 +2860,8 @@ def to_parquet( partition_cols: list[str] | None = ..., storage_options: StorageOptions = ..., **kwargs, - ) -> bytes: ... + ) -> bytes: + ... @overload def to_parquet( @@ -2858,7 +2874,8 @@ def to_parquet( partition_cols: list[str] | None = ..., storage_options: StorageOptions = ..., **kwargs, - ) -> None: ... + ) -> None: + ... @doc(storage_options=_shared_docs["storage_options"]) def to_parquet( @@ -2981,7 +2998,8 @@ def to_orc( engine: Literal["pyarrow"] = ..., index: bool | None = ..., engine_kwargs: dict[str, Any] | None = ..., - ) -> bytes: ... + ) -> bytes: + ... @overload def to_orc( @@ -2991,7 +3009,8 @@ def to_orc( engine: Literal["pyarrow"] = ..., index: bool | None = ..., engine_kwargs: dict[str, Any] | None = ..., - ) -> None: ... + ) -> None: + ... @overload def to_orc( @@ -3001,7 +3020,8 @@ def to_orc( engine: Literal["pyarrow"] = ..., index: bool | None = ..., engine_kwargs: dict[str, Any] | None = ..., - ) -> bytes | None: ... + ) -> bytes | None: + ... def to_orc( self, @@ -3121,7 +3141,8 @@ def to_html( table_id: str | None = ..., render_links: bool = ..., encoding: str | None = ..., - ) -> None: ... + ) -> None: + ... @overload def to_html( @@ -3150,7 +3171,8 @@ def to_html( table_id: str | None = ..., render_links: bool = ..., encoding: str | None = ..., - ) -> str: ... + ) -> str: + ... @Substitution( header_type="bool", @@ -3291,7 +3313,8 @@ def to_xml( stylesheet: FilePath | ReadBuffer[str] | ReadBuffer[bytes] | None = ..., compression: CompressionOptions = ..., storage_options: StorageOptions | None = ..., - ) -> str: ... + ) -> str: + ... @overload def to_xml( @@ -3313,7 +3336,8 @@ def to_xml( stylesheet: FilePath | ReadBuffer[str] | ReadBuffer[bytes] | None = ..., compression: CompressionOptions = ..., storage_options: StorageOptions | None = ..., - ) -> None: ... + ) -> None: + ... @doc( storage_options=_shared_docs["storage_options"], @@ -4457,22 +4481,21 @@ def _get_item(self, item: Hashable) -> Series: # Unsorted @overload - def query( - self, expr: str, *, inplace: Literal[False] = ..., **kwargs - ) -> DataFrame: ... + def query(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> DataFrame: + ... @overload - def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: ... + def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: + ... @overload - def query( - self, expr: str, *, inplace: bool = ..., **kwargs - ) -> DataFrame | None: ... + def query(self, expr: str, *, inplace: bool = ..., **kwargs) -> DataFrame | None: + ... def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. - + This function pass the `expr` parameter to :meth:`~pandas.DataFrame.eval`. This allows `eval` to run arbitrary code, which can make you vulnerable to code injection if you pass user input to this function. @@ -4632,10 +4655,12 @@ def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | No return result @overload - def eval(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> Any: ... + def eval(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> Any: + ... @overload - def eval(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: ... + def eval(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: + ... def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: """ @@ -5195,7 +5220,8 @@ def drop( level: Level = ..., inplace: Literal[True], errors: IgnoreRaise = ..., - ) -> None: ... + ) -> None: + ... @overload def drop( @@ -5208,7 +5234,8 @@ def drop( level: Level = ..., inplace: Literal[False] = ..., errors: IgnoreRaise = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def drop( @@ -5221,7 +5248,8 @@ def drop( level: Level = ..., inplace: bool = ..., errors: IgnoreRaise = ..., - ) -> DataFrame | None: ... + ) -> DataFrame | None: + ... def drop( self, @@ -5403,7 +5431,8 @@ def rename( inplace: Literal[True], level: Level = ..., errors: IgnoreRaise = ..., - ) -> None: ... + ) -> None: + ... @overload def rename( @@ -5417,7 +5446,8 @@ def rename( inplace: Literal[False] = ..., level: Level = ..., errors: IgnoreRaise = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def rename( @@ -5431,7 +5461,8 @@ def rename( inplace: bool = ..., level: Level = ..., errors: IgnoreRaise = ..., - ) -> DataFrame | None: ... + ) -> DataFrame | None: + ... def rename( self, @@ -5633,12 +5664,14 @@ def pop(self, item: Hashable) -> Series: @overload def _replace_columnwise( self, mapping: dict[Hashable, tuple[Any, Any]], inplace: Literal[True], regex - ) -> None: ... + ) -> None: + ... @overload def _replace_columnwise( self, mapping: dict[Hashable, tuple[Any, Any]], inplace: Literal[False], regex - ) -> Self: ... + ) -> Self: + ... def _replace_columnwise( self, mapping: dict[Hashable, tuple[Any, Any]], inplace: bool, regex @@ -5792,7 +5825,8 @@ def set_index( append: bool = ..., inplace: Literal[False] = ..., verify_integrity: bool = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def set_index( @@ -5803,7 +5837,8 @@ def set_index( append: bool = ..., inplace: Literal[True], verify_integrity: bool = ..., - ) -> None: ... + ) -> None: + ... def set_index( self, @@ -6023,7 +6058,8 @@ def reset_index( col_fill: Hashable = ..., allow_duplicates: bool | lib.NoDefault = ..., names: Hashable | Sequence[Hashable] | None = None, - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def reset_index( @@ -6036,7 +6072,8 @@ def reset_index( col_fill: Hashable = ..., allow_duplicates: bool | lib.NoDefault = ..., names: Hashable | Sequence[Hashable] | None = None, - ) -> None: ... + ) -> None: + ... @overload def reset_index( @@ -6049,7 +6086,8 @@ def reset_index( col_fill: Hashable = ..., allow_duplicates: bool | lib.NoDefault = ..., names: Hashable | Sequence[Hashable] | None = None, - ) -> DataFrame | None: ... + ) -> DataFrame | None: + ... def reset_index( self, @@ -6336,7 +6374,8 @@ def dropna( subset: IndexLabel = ..., inplace: Literal[False] = ..., ignore_index: bool = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def dropna( @@ -6348,7 +6387,8 @@ def dropna( subset: IndexLabel = ..., inplace: Literal[True], ignore_index: bool = ..., - ) -> None: ... + ) -> None: + ... def dropna( self, @@ -6521,7 +6561,8 @@ def drop_duplicates( keep: DropKeep = ..., inplace: Literal[True], ignore_index: bool = ..., - ) -> None: ... + ) -> None: + ... @overload def drop_duplicates( @@ -6531,7 +6572,8 @@ def drop_duplicates( keep: DropKeep = ..., inplace: Literal[False] = ..., ignore_index: bool = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def drop_duplicates( @@ -6541,7 +6583,8 @@ def drop_duplicates( keep: DropKeep = ..., inplace: bool = ..., ignore_index: bool = ..., - ) -> DataFrame | None: ... + ) -> DataFrame | None: + ... def drop_duplicates( self, @@ -6800,7 +6843,8 @@ def sort_values( na_position: NaPosition = ..., ignore_index: bool = ..., key: ValueKeyFunc = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def sort_values( @@ -6814,7 +6858,8 @@ def sort_values( na_position: str = ..., ignore_index: bool = ..., key: ValueKeyFunc = ..., - ) -> None: ... + ) -> None: + ... def sort_values( self, @@ -7094,7 +7139,8 @@ def sort_index( sort_remaining: bool = ..., ignore_index: bool = ..., key: IndexKeyFunc = ..., - ) -> None: ... + ) -> None: + ... @overload def sort_index( @@ -7109,7 +7155,8 @@ def sort_index( sort_remaining: bool = ..., ignore_index: bool = ..., key: IndexKeyFunc = ..., - ) -> DataFrame: ... + ) -> DataFrame: + ... @overload def sort_index( @@ -7124,7 +7171,8 @@ def sort_index( sort_remaining: bool = ..., ignore_index: bool = ..., key: IndexKeyFunc = ..., - ) -> DataFrame | None: ... + ) -> DataFrame | None: + ... def sort_index( self, @@ -9073,7 +9121,9 @@ def groupby( dropna=dropna, ) - _shared_docs["pivot"] = """ + _shared_docs[ + "pivot" + ] = """ Return reshaped DataFrame organized by given index / column values. Reshape data (produce a "pivot" table) based on column values. Uses @@ -9217,7 +9267,9 @@ def pivot( return pivot(self, index=index, columns=columns, values=values) - _shared_docs["pivot_table"] = """ + _shared_docs[ + "pivot_table" + ] = """ Create a spreadsheet-style pivot table as a DataFrame. The levels in the pivot table will be stored in MultiIndex objects @@ -11581,7 +11633,8 @@ def any( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def any( @@ -11591,7 +11644,8 @@ def any( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> bool: ... + ) -> bool: + ... @overload def any( @@ -11601,7 +11655,8 @@ def any( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series | bool: ... + ) -> Series | bool: + ... @doc(make_doc("any", ndim=1)) def any( @@ -11627,7 +11682,8 @@ def all( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def all( @@ -11637,7 +11693,8 @@ def all( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> bool: ... + ) -> bool: + ... @overload def all( @@ -11647,7 +11704,8 @@ def all( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series | bool: ... + ) -> Series | bool: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="all") @doc(make_doc("all", ndim=1)) @@ -11674,7 +11732,8 @@ def min( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def min( @@ -11684,7 +11743,8 @@ def min( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def min( @@ -11694,7 +11754,8 @@ def min( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="min") @doc(make_doc("min", ndim=2)) @@ -11721,7 +11782,8 @@ def max( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def max( @@ -11731,7 +11793,8 @@ def max( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def max( @@ -11741,7 +11804,8 @@ def max( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="max") @doc(make_doc("max", ndim=2)) @@ -11956,7 +12020,8 @@ def mean( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def mean( @@ -11966,7 +12031,8 @@ def mean( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def mean( @@ -11976,7 +12042,8 @@ def mean( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="mean") @doc(make_doc("mean", ndim=2)) @@ -12003,7 +12070,8 @@ def median( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def median( @@ -12013,7 +12081,8 @@ def median( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def median( @@ -12023,7 +12092,8 @@ def median( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="median") @doc(make_doc("median", ndim=2)) @@ -12051,7 +12121,8 @@ def sem( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def sem( @@ -12062,7 +12133,8 @@ def sem( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def sem( @@ -12073,7 +12145,8 @@ def sem( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="sem") def sem( @@ -12171,7 +12244,8 @@ def var( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def var( @@ -12182,7 +12256,8 @@ def var( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def var( @@ -12193,7 +12268,8 @@ def var( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="var") def var( @@ -12290,7 +12366,8 @@ def std( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def std( @@ -12301,7 +12378,8 @@ def std( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def std( @@ -12312,7 +12390,8 @@ def std( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="std") def std( @@ -12415,7 +12494,8 @@ def skew( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def skew( @@ -12425,7 +12505,8 @@ def skew( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def skew( @@ -12435,7 +12516,8 @@ def skew( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="skew") def skew( @@ -12535,7 +12617,8 @@ def kurt( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: ... + ) -> Series: + ... @overload def kurt( @@ -12545,7 +12628,8 @@ def kurt( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: ... + ) -> Any: + ... @overload def kurt( @@ -12555,7 +12639,8 @@ def kurt( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: ... + ) -> Series | Any: + ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="kurt") def kurt( @@ -12933,7 +13018,8 @@ def quantile( numeric_only: bool = ..., interpolation: QuantileInterpolation = ..., method: Literal["single", "table"] = ..., - ) -> Series: ... + ) -> Series: + ... @overload def quantile( @@ -12943,7 +13029,8 @@ def quantile( numeric_only: bool = ..., interpolation: QuantileInterpolation = ..., method: Literal["single", "table"] = ..., - ) -> Series | DataFrame: ... + ) -> Series | DataFrame: + ... @overload def quantile( @@ -12953,7 +13040,8 @@ def quantile( numeric_only: bool = ..., interpolation: QuantileInterpolation = ..., method: Literal["single", "table"] = ..., - ) -> Series | DataFrame: ... + ) -> Series | DataFrame: + ... def quantile( self, @@ -13611,9 +13699,9 @@ def values(self) -> np.ndarray: def _from_nested_dict( data: Mapping[HashableT, Mapping[HashableT2, T]], ) -> collections.defaultdict[HashableT2, dict[HashableT, T]]: - new_data: collections.defaultdict[HashableT2, dict[HashableT, T]] = ( - collections.defaultdict(dict) - ) + new_data: collections.defaultdict[ + HashableT2, dict[HashableT, T] + ] = collections.defaultdict(dict) for index, s in data.items(): for col, v in s.items(): new_data[col][index] = v From 44e103ee9a72b9787cf44406d5a8ea6babdd8f94 Mon Sep 17 00:00:00 2001 From: r0rshark Date: Mon, 13 May 2024 22:30:05 +0200 Subject: [PATCH 4/6] Revert "fixed trailing space" This reverts commit 79c603e7cf08d769dd9b27daa51cb98cb27dfd13. --- pandas/core/frame.py | 282 +++++++++++++++---------------------------- 1 file changed, 97 insertions(+), 185 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 8bf1e6a53491d..b34a0b4af0a8b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -1243,8 +1243,7 @@ def to_string( min_rows: int | None = ..., max_colwidth: int | None = ..., encoding: str | None = ..., - ) -> str: - ... + ) -> str: ... @overload def to_string( @@ -1269,8 +1268,7 @@ def to_string( min_rows: int | None = ..., max_colwidth: int | None = ..., encoding: str | None = ..., - ) -> None: - ... + ) -> None: ... @Substitution( header_type="bool or list of str", @@ -1405,9 +1403,7 @@ def style(self) -> Styler: return Styler(self) - _shared_docs[ - "items" - ] = r""" + _shared_docs["items"] = r""" Iterate over (column name, Series) pairs. Iterates over the DataFrame columns, returning a tuple with @@ -1602,12 +1598,10 @@ def __len__(self) -> int: return len(self.index) @overload - def dot(self, other: Series) -> Series: - ... + def dot(self, other: Series) -> Series: ... @overload - def dot(self, other: DataFrame | Index | ArrayLike) -> DataFrame: - ... + def dot(self, other: DataFrame | Index | ArrayLike) -> DataFrame: ... def dot(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: """ @@ -1728,12 +1722,10 @@ def dot(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: raise TypeError(f"unsupported type: {type(other)}") @overload - def __matmul__(self, other: Series) -> Series: - ... + def __matmul__(self, other: Series) -> Series: ... @overload - def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: - ... + def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: ... def __matmul__(self, other: AnyArrayLike | DataFrame) -> DataFrame | Series: """ @@ -1960,8 +1952,7 @@ def to_dict( *, into: type[MutableMappingT] | MutableMappingT, index: bool = ..., - ) -> MutableMappingT: - ... + ) -> MutableMappingT: ... @overload def to_dict( @@ -1970,8 +1961,7 @@ def to_dict( *, into: type[MutableMappingT] | MutableMappingT, index: bool = ..., - ) -> list[MutableMappingT]: - ... + ) -> list[MutableMappingT]: ... @overload def to_dict( @@ -1980,8 +1970,7 @@ def to_dict( *, into: type[dict] = ..., index: bool = ..., - ) -> dict: - ... + ) -> dict: ... @overload def to_dict( @@ -1990,8 +1979,7 @@ def to_dict( *, into: type[dict] = ..., index: bool = ..., - ) -> list[dict]: - ... + ) -> list[dict]: ... # error: Incompatible default for argument "into" (default has type "type # [dict[Any, Any]]", argument has type "type[MutableMappingT] | MutableMappingT") @@ -2737,8 +2725,7 @@ def to_markdown( index: bool = ..., storage_options: StorageOptions | None = ..., **kwargs, - ) -> str: - ... + ) -> str: ... @overload def to_markdown( @@ -2749,8 +2736,7 @@ def to_markdown( index: bool = ..., storage_options: StorageOptions | None = ..., **kwargs, - ) -> None: - ... + ) -> None: ... @overload def to_markdown( @@ -2761,8 +2747,7 @@ def to_markdown( index: bool = ..., storage_options: StorageOptions | None = ..., **kwargs, - ) -> str | None: - ... + ) -> str | None: ... def to_markdown( self, @@ -2860,8 +2845,7 @@ def to_parquet( partition_cols: list[str] | None = ..., storage_options: StorageOptions = ..., **kwargs, - ) -> bytes: - ... + ) -> bytes: ... @overload def to_parquet( @@ -2874,8 +2858,7 @@ def to_parquet( partition_cols: list[str] | None = ..., storage_options: StorageOptions = ..., **kwargs, - ) -> None: - ... + ) -> None: ... @doc(storage_options=_shared_docs["storage_options"]) def to_parquet( @@ -2998,8 +2981,7 @@ def to_orc( engine: Literal["pyarrow"] = ..., index: bool | None = ..., engine_kwargs: dict[str, Any] | None = ..., - ) -> bytes: - ... + ) -> bytes: ... @overload def to_orc( @@ -3009,8 +2991,7 @@ def to_orc( engine: Literal["pyarrow"] = ..., index: bool | None = ..., engine_kwargs: dict[str, Any] | None = ..., - ) -> None: - ... + ) -> None: ... @overload def to_orc( @@ -3020,8 +3001,7 @@ def to_orc( engine: Literal["pyarrow"] = ..., index: bool | None = ..., engine_kwargs: dict[str, Any] | None = ..., - ) -> bytes | None: - ... + ) -> bytes | None: ... def to_orc( self, @@ -3141,8 +3121,7 @@ def to_html( table_id: str | None = ..., render_links: bool = ..., encoding: str | None = ..., - ) -> None: - ... + ) -> None: ... @overload def to_html( @@ -3171,8 +3150,7 @@ def to_html( table_id: str | None = ..., render_links: bool = ..., encoding: str | None = ..., - ) -> str: - ... + ) -> str: ... @Substitution( header_type="bool", @@ -3313,8 +3291,7 @@ def to_xml( stylesheet: FilePath | ReadBuffer[str] | ReadBuffer[bytes] | None = ..., compression: CompressionOptions = ..., storage_options: StorageOptions | None = ..., - ) -> str: - ... + ) -> str: ... @overload def to_xml( @@ -3336,8 +3313,7 @@ def to_xml( stylesheet: FilePath | ReadBuffer[str] | ReadBuffer[bytes] | None = ..., compression: CompressionOptions = ..., storage_options: StorageOptions | None = ..., - ) -> None: - ... + ) -> None: ... @doc( storage_options=_shared_docs["storage_options"], @@ -4481,21 +4457,22 @@ def _get_item(self, item: Hashable) -> Series: # Unsorted @overload - def query(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> DataFrame: - ... + def query( + self, expr: str, *, inplace: Literal[False] = ..., **kwargs + ) -> DataFrame: ... @overload - def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: - ... + def query(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: ... @overload - def query(self, expr: str, *, inplace: bool = ..., **kwargs) -> DataFrame | None: - ... + def query( + self, expr: str, *, inplace: bool = ..., **kwargs + ) -> DataFrame | None: ... def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. - + This function pass the `expr` parameter to :meth:`~pandas.DataFrame.eval`. This allows `eval` to run arbitrary code, which can make you vulnerable to code injection if you pass user input to this function. @@ -4655,12 +4632,10 @@ def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | No return result @overload - def eval(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> Any: - ... + def eval(self, expr: str, *, inplace: Literal[False] = ..., **kwargs) -> Any: ... @overload - def eval(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: - ... + def eval(self, expr: str, *, inplace: Literal[True], **kwargs) -> None: ... def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None: """ @@ -5220,8 +5195,7 @@ def drop( level: Level = ..., inplace: Literal[True], errors: IgnoreRaise = ..., - ) -> None: - ... + ) -> None: ... @overload def drop( @@ -5234,8 +5208,7 @@ def drop( level: Level = ..., inplace: Literal[False] = ..., errors: IgnoreRaise = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def drop( @@ -5248,8 +5221,7 @@ def drop( level: Level = ..., inplace: bool = ..., errors: IgnoreRaise = ..., - ) -> DataFrame | None: - ... + ) -> DataFrame | None: ... def drop( self, @@ -5431,8 +5403,7 @@ def rename( inplace: Literal[True], level: Level = ..., errors: IgnoreRaise = ..., - ) -> None: - ... + ) -> None: ... @overload def rename( @@ -5446,8 +5417,7 @@ def rename( inplace: Literal[False] = ..., level: Level = ..., errors: IgnoreRaise = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def rename( @@ -5461,8 +5431,7 @@ def rename( inplace: bool = ..., level: Level = ..., errors: IgnoreRaise = ..., - ) -> DataFrame | None: - ... + ) -> DataFrame | None: ... def rename( self, @@ -5664,14 +5633,12 @@ def pop(self, item: Hashable) -> Series: @overload def _replace_columnwise( self, mapping: dict[Hashable, tuple[Any, Any]], inplace: Literal[True], regex - ) -> None: - ... + ) -> None: ... @overload def _replace_columnwise( self, mapping: dict[Hashable, tuple[Any, Any]], inplace: Literal[False], regex - ) -> Self: - ... + ) -> Self: ... def _replace_columnwise( self, mapping: dict[Hashable, tuple[Any, Any]], inplace: bool, regex @@ -5825,8 +5792,7 @@ def set_index( append: bool = ..., inplace: Literal[False] = ..., verify_integrity: bool = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def set_index( @@ -5837,8 +5803,7 @@ def set_index( append: bool = ..., inplace: Literal[True], verify_integrity: bool = ..., - ) -> None: - ... + ) -> None: ... def set_index( self, @@ -6058,8 +6023,7 @@ def reset_index( col_fill: Hashable = ..., allow_duplicates: bool | lib.NoDefault = ..., names: Hashable | Sequence[Hashable] | None = None, - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def reset_index( @@ -6072,8 +6036,7 @@ def reset_index( col_fill: Hashable = ..., allow_duplicates: bool | lib.NoDefault = ..., names: Hashable | Sequence[Hashable] | None = None, - ) -> None: - ... + ) -> None: ... @overload def reset_index( @@ -6086,8 +6049,7 @@ def reset_index( col_fill: Hashable = ..., allow_duplicates: bool | lib.NoDefault = ..., names: Hashable | Sequence[Hashable] | None = None, - ) -> DataFrame | None: - ... + ) -> DataFrame | None: ... def reset_index( self, @@ -6374,8 +6336,7 @@ def dropna( subset: IndexLabel = ..., inplace: Literal[False] = ..., ignore_index: bool = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def dropna( @@ -6387,8 +6348,7 @@ def dropna( subset: IndexLabel = ..., inplace: Literal[True], ignore_index: bool = ..., - ) -> None: - ... + ) -> None: ... def dropna( self, @@ -6561,8 +6521,7 @@ def drop_duplicates( keep: DropKeep = ..., inplace: Literal[True], ignore_index: bool = ..., - ) -> None: - ... + ) -> None: ... @overload def drop_duplicates( @@ -6572,8 +6531,7 @@ def drop_duplicates( keep: DropKeep = ..., inplace: Literal[False] = ..., ignore_index: bool = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def drop_duplicates( @@ -6583,8 +6541,7 @@ def drop_duplicates( keep: DropKeep = ..., inplace: bool = ..., ignore_index: bool = ..., - ) -> DataFrame | None: - ... + ) -> DataFrame | None: ... def drop_duplicates( self, @@ -6843,8 +6800,7 @@ def sort_values( na_position: NaPosition = ..., ignore_index: bool = ..., key: ValueKeyFunc = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def sort_values( @@ -6858,8 +6814,7 @@ def sort_values( na_position: str = ..., ignore_index: bool = ..., key: ValueKeyFunc = ..., - ) -> None: - ... + ) -> None: ... def sort_values( self, @@ -7139,8 +7094,7 @@ def sort_index( sort_remaining: bool = ..., ignore_index: bool = ..., key: IndexKeyFunc = ..., - ) -> None: - ... + ) -> None: ... @overload def sort_index( @@ -7155,8 +7109,7 @@ def sort_index( sort_remaining: bool = ..., ignore_index: bool = ..., key: IndexKeyFunc = ..., - ) -> DataFrame: - ... + ) -> DataFrame: ... @overload def sort_index( @@ -7171,8 +7124,7 @@ def sort_index( sort_remaining: bool = ..., ignore_index: bool = ..., key: IndexKeyFunc = ..., - ) -> DataFrame | None: - ... + ) -> DataFrame | None: ... def sort_index( self, @@ -9121,9 +9073,7 @@ def groupby( dropna=dropna, ) - _shared_docs[ - "pivot" - ] = """ + _shared_docs["pivot"] = """ Return reshaped DataFrame organized by given index / column values. Reshape data (produce a "pivot" table) based on column values. Uses @@ -9267,9 +9217,7 @@ def pivot( return pivot(self, index=index, columns=columns, values=values) - _shared_docs[ - "pivot_table" - ] = """ + _shared_docs["pivot_table"] = """ Create a spreadsheet-style pivot table as a DataFrame. The levels in the pivot table will be stored in MultiIndex objects @@ -11633,8 +11581,7 @@ def any( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def any( @@ -11644,8 +11591,7 @@ def any( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> bool: - ... + ) -> bool: ... @overload def any( @@ -11655,8 +11601,7 @@ def any( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series | bool: - ... + ) -> Series | bool: ... @doc(make_doc("any", ndim=1)) def any( @@ -11682,8 +11627,7 @@ def all( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def all( @@ -11693,8 +11637,7 @@ def all( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> bool: - ... + ) -> bool: ... @overload def all( @@ -11704,8 +11647,7 @@ def all( bool_only: bool = ..., skipna: bool = ..., **kwargs, - ) -> Series | bool: - ... + ) -> Series | bool: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="all") @doc(make_doc("all", ndim=1)) @@ -11732,8 +11674,7 @@ def min( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def min( @@ -11743,8 +11684,7 @@ def min( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def min( @@ -11754,8 +11694,7 @@ def min( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="min") @doc(make_doc("min", ndim=2)) @@ -11782,8 +11721,7 @@ def max( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def max( @@ -11793,8 +11731,7 @@ def max( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def max( @@ -11804,8 +11741,7 @@ def max( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="max") @doc(make_doc("max", ndim=2)) @@ -12020,8 +11956,7 @@ def mean( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def mean( @@ -12031,8 +11966,7 @@ def mean( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def mean( @@ -12042,8 +11976,7 @@ def mean( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="mean") @doc(make_doc("mean", ndim=2)) @@ -12070,8 +12003,7 @@ def median( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def median( @@ -12081,8 +12013,7 @@ def median( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def median( @@ -12092,8 +12023,7 @@ def median( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="median") @doc(make_doc("median", ndim=2)) @@ -12121,8 +12051,7 @@ def sem( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def sem( @@ -12133,8 +12062,7 @@ def sem( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def sem( @@ -12145,8 +12073,7 @@ def sem( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="sem") def sem( @@ -12244,8 +12171,7 @@ def var( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def var( @@ -12256,8 +12182,7 @@ def var( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def var( @@ -12268,8 +12193,7 @@ def var( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="var") def var( @@ -12366,8 +12290,7 @@ def std( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def std( @@ -12378,8 +12301,7 @@ def std( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def std( @@ -12390,8 +12312,7 @@ def std( ddof: int = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="std") def std( @@ -12494,8 +12415,7 @@ def skew( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def skew( @@ -12505,8 +12425,7 @@ def skew( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def skew( @@ -12516,8 +12435,7 @@ def skew( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="skew") def skew( @@ -12617,8 +12535,7 @@ def kurt( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series: - ... + ) -> Series: ... @overload def kurt( @@ -12628,8 +12545,7 @@ def kurt( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Any: - ... + ) -> Any: ... @overload def kurt( @@ -12639,8 +12555,7 @@ def kurt( skipna: bool = ..., numeric_only: bool = ..., **kwargs, - ) -> Series | Any: - ... + ) -> Series | Any: ... @deprecate_nonkeyword_arguments(version="3.0", allowed_args=["self"], name="kurt") def kurt( @@ -13018,8 +12933,7 @@ def quantile( numeric_only: bool = ..., interpolation: QuantileInterpolation = ..., method: Literal["single", "table"] = ..., - ) -> Series: - ... + ) -> Series: ... @overload def quantile( @@ -13029,8 +12943,7 @@ def quantile( numeric_only: bool = ..., interpolation: QuantileInterpolation = ..., method: Literal["single", "table"] = ..., - ) -> Series | DataFrame: - ... + ) -> Series | DataFrame: ... @overload def quantile( @@ -13040,8 +12953,7 @@ def quantile( numeric_only: bool = ..., interpolation: QuantileInterpolation = ..., method: Literal["single", "table"] = ..., - ) -> Series | DataFrame: - ... + ) -> Series | DataFrame: ... def quantile( self, @@ -13699,9 +13611,9 @@ def values(self) -> np.ndarray: def _from_nested_dict( data: Mapping[HashableT, Mapping[HashableT2, T]], ) -> collections.defaultdict[HashableT2, dict[HashableT, T]]: - new_data: collections.defaultdict[ - HashableT2, dict[HashableT, T] - ] = collections.defaultdict(dict) + new_data: collections.defaultdict[HashableT2, dict[HashableT, T]] = ( + collections.defaultdict(dict) + ) for index, s in data.items(): for col, v in s.items(): new_data[col][index] = v From d18aac862cbf459bd2a617cf398277c8ff429365 Mon Sep 17 00:00:00 2001 From: r0rshark Date: Mon, 13 May 2024 22:31:26 +0200 Subject: [PATCH 5/6] fixed trailing space --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index b34a0b4af0a8b..6cb7e8df77a15 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4472,7 +4472,7 @@ def query( def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | None: """ Query the columns of a DataFrame with a boolean expression. - + This function pass the `expr` parameter to :meth:`~pandas.DataFrame.eval`. This allows `eval` to run arbitrary code, which can make you vulnerable to code injection if you pass user input to this function. From 837d5b89b80d5ccc1fea05906bee43138b494ba4 Mon Sep 17 00:00:00 2001 From: r0rshark Date: Wed, 22 May 2024 21:32:21 +0200 Subject: [PATCH 6/6] Addressed feedback --- pandas/core/computation/eval.py | 2 +- pandas/core/frame.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py index 0448b3fc5c3a7..fee08c6199eef 100644 --- a/pandas/core/computation/eval.py +++ b/pandas/core/computation/eval.py @@ -193,7 +193,7 @@ def eval( corresponding bitwise operators. :class:`~pandas.Series` and :class:`~pandas.DataFrame` objects are supported and behave as they would with plain ol' Python evaluation. - This allows `eval` to run arbitrary code, which can make you vulnerable to code + `eval` can run arbitrary code which can make you vulnerable to code injection if you pass user input to this function. Parameters diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 6cb7e8df77a15..b32e9ea4b3bd6 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4473,8 +4473,7 @@ def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | No """ Query the columns of a DataFrame with a boolean expression. - This function pass the `expr` parameter to :meth:`~pandas.DataFrame.eval`. - This allows `eval` to run arbitrary code, which can make you vulnerable to code + This method can run arbitrary code which can make you vulnerable to code injection if you pass user input to this function. Parameters