From e4605501c348f36fdfbd2bba42cadd43121944b4 Mon Sep 17 00:00:00 2001 From: TechnoShip123 <75491816+TechnoShip123@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:30:34 -0500 Subject: [PATCH 01/17] DOC: Add examples for creating an index accessor --- pandas/core/accessor.py | 161 ++++++++++++++++++++++++++++------------ 1 file changed, 115 insertions(+), 46 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 99b5053ce250c..22a6295f0fb7f 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -13,7 +13,7 @@ ) import warnings -from pandas.util._decorators import doc +from pandas.util._decorators import doc, Appender from pandas.util._exceptions import find_stack_level @@ -255,51 +255,15 @@ def _register_accessor(name: str, cls): Notes ----- - When accessed, your accessor will be initialized with the pandas object - the user is interacting with. So the signature must be - - .. code-block:: python - - def __init__(self, pandas_object): # noqa: E999 - ... - - For consistency with pandas methods, you should raise an ``AttributeError`` - if the data passed to your accessor has an incorrect dtype. - - >>> pd.Series(["a", "b"]).dt - Traceback (most recent call last): - ... - AttributeError: Can only use .dt accessor with datetimelike values - - Examples - -------- - In your library code:: - - @pd.api.extensions.register_dataframe_accessor("geo") - class GeoAccessor: - def __init__(self, pandas_obj): - self._obj = pandas_obj - - @property - def center(self): - # return the geographic center point of this DataFrame - lat = self._obj.latitude - lon = self._obj.longitude - return (float(lon.mean()), float(lat.mean())) - - def plot(self): - # plot this array's data on a map, e.g., using Cartopy - pass - - Back in an interactive IPython session: - - .. code-block:: ipython - - In [1]: ds = pd.DataFrame({{"longitude": np.linspace(0, 10), - ...: "latitude": np.linspace(0, 20)}}) - In [2]: ds.geo.center - Out[2]: (5.0, 10.0) - In [3]: ds.geo.plot() # plots data on a map + This function allows you to register a custom-defined accessor class for {klass}. + The requirements for the accessor class are as follows: + + * Must contain an init method that: + * accepts a single {klass} object + * raises an {AttributeError} if the {klass} object does not have correctly matching inputs for the accessor + * Must contain a method for each access pattern. + * The methods should be able to take any argument signature. + * Accessible using the @property decorator if no additional arguments are needed. """ def decorator(accessor): @@ -318,6 +282,41 @@ def decorator(accessor): return decorator +_register_df_doc = """ +Examples +-------- +In your library code, an accessor that only accepts integers could have a class defined like this: +.. code-block:: python + + import pandas as pd + + @pd.api.extensions.register_dataframe_accessor("int_accessor") + class IntAccessor: + def __init__(self, pandas_obj): + if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): + raise AttributeError("All columns must contain integer values only") + self._obj = pandas_obj + + def sum(self): + return self._obj.sum() + + +Back in an interactive IPython session: +.. code-block:: ipython + >>> df = pd.DataFrame([[1, 2], ['x', 'y']]) + >>> df.int_accessor + Traceback (most recent call last): + ... + AttributeError: All columns must contain integer values only. Did you mean: '_accessors'? + >>> df = pd.DataFrame([[1, 2], [3, 4]]) + >>> df.int_accessor.sum() + 0 4 + 1 6 + dtype: int64 +""" + + +@Appender(_register_df_doc) @doc(_register_accessor, klass="DataFrame") def register_dataframe_accessor(name: str): from pandas import DataFrame @@ -325,6 +324,39 @@ def register_dataframe_accessor(name: str): return _register_accessor(name, DataFrame) +_series_doc = """ +Examples +-------- +In your library code, an accessor that only accepts integers could have a class defined like this: +.. code-block:: python + + import pandas as pd + + @pd.api.extensions.register_series_accessor("int_accessor") + class IntAccessor: + def __init__(self, pandas_obj): + if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): + raise AttributeError("All columns must contain integer values only") + self._obj = pandas_obj + + def sum(self): + return self._obj.sum() + + +Back in an interactive IPython session: +.. code-block:: ipython + >>> df = pd.Series([1, 2, 'x']) + >>> df.int_accessor + Traceback (most recent call last): + ... + AttributeError: The series must contain integer data only. Did you mean: '_accessors'? + >>> df = pd.Series([1, 2, 3]) + >>> df.int_accessor.sum + 6 +""" + + +@Appender(_series_doc) @doc(_register_accessor, klass="Series") def register_series_accessor(name: str): from pandas import Series @@ -332,6 +364,43 @@ def register_series_accessor(name: str): return _register_accessor(name, Series) +_index_doc = """ +Examples +-------- +In your library code, an accessor that only accepts integers could have a class defined like this: +.. code-block:: python + + import pandas as pd + + @pd.api.extensions.register_index_accessor("int_accessor") + class IntAccessor: + def __init__(self, pandas_obj): + if not all(isinstance(x, int) for x in pandas_obj): + raise AttributeError("The index must only be an integer value") + self._obj = pandas_obj + + def even(self): + return [x for x in self._obj if x % 2 == 0] + +Back in an interactive IPython session: +.. code-block:: ipython + >>> df = pd.DataFrame.from_dict({ + 'row1': {'1':1, '2':'a'}, + 'row2': {'1':2, '2':'b'} + },orient='index') + >>> df.index.int_accessor + Traceback (most recent call last): + ... + AttributeError: The index must only be an integer value. Did you mean: '_accessors'? + >>> df = pd.DataFrame({ + 'col1': [1, 2, 3, 4], + 'col2': ['a', 'b', 'c', 'd'] + }, index=[1, 2, 5, 8]) + >>> df.index.my_accessor.even() + [2,8] +""" + +@Appender(_index_doc) @doc(_register_accessor, klass="Index") def register_index_accessor(name: str): from pandas import Index From 87cc9dc20f4aceb3f7dcf7cc5a1c167d89faab11 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:44:13 +0000 Subject: [PATCH 02/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pandas/core/accessor.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 22a6295f0fb7f..a86c60d076a60 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -13,7 +13,10 @@ ) import warnings -from pandas.util._decorators import doc, Appender +from pandas.util._decorators import ( + Appender, + doc, +) from pandas.util._exceptions import find_stack_level @@ -340,7 +343,7 @@ def __init__(self, pandas_obj): self._obj = pandas_obj def sum(self): - return self._obj.sum() + return self._obj.sum() Back in an interactive IPython session: @@ -400,6 +403,7 @@ def even(self): [2,8] """ + @Appender(_index_doc) @doc(_register_accessor, klass="Index") def register_index_accessor(name: str): From 15311dbfed1dfbe078ef61014a980fb1ca9c4946 Mon Sep 17 00:00:00 2001 From: TechnoShip123 <75491816+TechnoShip123@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:51:45 -0500 Subject: [PATCH 03/17] Fix E501 lint errors --- pandas/core/accessor.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index a86c60d076a60..4d5066814b54b 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -263,10 +263,12 @@ def _register_accessor(name: str, cls): * Must contain an init method that: * accepts a single {klass} object - * raises an {AttributeError} if the {klass} object does not have correctly matching inputs for the accessor + * raises an {AttributeError} if the {klass} object does not have correctly + matching inputs for the accessor * Must contain a method for each access pattern. * The methods should be able to take any argument signature. - * Accessible using the @property decorator if no additional arguments are needed. + * Accessible using the @property decorator if no additional arguments are + needed. """ def decorator(accessor): @@ -288,7 +290,9 @@ def decorator(accessor): _register_df_doc = """ Examples -------- -In your library code, an accessor that only accepts integers could have a class defined like this: +In your library code, an accessor that only accepts integers could +have a class defined like this: + .. code-block:: python import pandas as pd @@ -310,7 +314,7 @@ def sum(self): >>> df.int_accessor Traceback (most recent call last): ... - AttributeError: All columns must contain integer values only. Did you mean: '_accessors'? + AttributeError: All columns must contain integer values only. >>> df = pd.DataFrame([[1, 2], [3, 4]]) >>> df.int_accessor.sum() 0 4 @@ -330,7 +334,9 @@ def register_dataframe_accessor(name: str): _series_doc = """ Examples -------- -In your library code, an accessor that only accepts integers could have a class defined like this: +In your library code, an accessor that only accepts integers could +have a class defined like this: + .. code-block:: python import pandas as pd @@ -352,7 +358,7 @@ def sum(self): >>> df.int_accessor Traceback (most recent call last): ... - AttributeError: The series must contain integer data only. Did you mean: '_accessors'? + AttributeError: The series must contain integer data only. >>> df = pd.Series([1, 2, 3]) >>> df.int_accessor.sum 6 @@ -370,7 +376,9 @@ def register_series_accessor(name: str): _index_doc = """ Examples -------- -In your library code, an accessor that only accepts integers could have a class defined like this: +In your library code, an accessor that only accepts integers could +have a class defined like this: + .. code-block:: python import pandas as pd @@ -394,7 +402,7 @@ def even(self): >>> df.index.int_accessor Traceback (most recent call last): ... - AttributeError: The index must only be an integer value. Did you mean: '_accessors'? + AttributeError: The index must only be an integer value. >>> df = pd.DataFrame({ 'col1': [1, 2, 3, 4], 'col2': ['a', 'b', 'c', 'd'] From 2c084dcc5f3b60b804b452a59372bc41cd51b671 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 16:55:16 +0000 Subject: [PATCH 04/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pandas/core/accessor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 4d5066814b54b..aa48d6e264cef 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -290,7 +290,7 @@ def decorator(accessor): _register_df_doc = """ Examples -------- -In your library code, an accessor that only accepts integers could +In your library code, an accessor that only accepts integers could have a class defined like this: .. code-block:: python @@ -334,7 +334,7 @@ def register_dataframe_accessor(name: str): _series_doc = """ Examples -------- -In your library code, an accessor that only accepts integers could +In your library code, an accessor that only accepts integers could have a class defined like this: .. code-block:: python @@ -376,7 +376,7 @@ def register_series_accessor(name: str): _index_doc = """ Examples -------- -In your library code, an accessor that only accepts integers could +In your library code, an accessor that only accepts integers could have a class defined like this: .. code-block:: python From f52734835178bddea7b95015c612446df234ce3d Mon Sep 17 00:00:00 2001 From: TechnoShip123 <75491816+TechnoShip123@users.noreply.github.com> Date: Sat, 16 Mar 2024 12:52:25 -0500 Subject: [PATCH 05/17] Fix failing CI builds for Docstring --- pandas/core/accessor.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index aa48d6e264cef..126f9ddb4fdc3 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -262,13 +262,19 @@ def _register_accessor(name: str, cls): The requirements for the accessor class are as follows: * Must contain an init method that: - * accepts a single {klass} object - * raises an {AttributeError} if the {klass} object does not have correctly + + * accepts a single {klass} object + + * raises an AttributeError if the {klass} object does not have correctly matching inputs for the accessor + * Must contain a method for each access pattern. - * The methods should be able to take any argument signature. - * Accessible using the @property decorator if no additional arguments are + + * The methods should be able to take any argument signature. + + * Accessible using the @property decorator if no additional arguments are needed. + """ def decorator(accessor): @@ -309,7 +315,9 @@ def sum(self): Back in an interactive IPython session: + .. code-block:: ipython + >>> df = pd.DataFrame([[1, 2], ['x', 'y']]) >>> df.int_accessor Traceback (most recent call last): @@ -353,7 +361,9 @@ def sum(self): Back in an interactive IPython session: + .. code-block:: ipython + >>> df = pd.Series([1, 2, 'x']) >>> df.int_accessor Traceback (most recent call last): @@ -394,7 +404,9 @@ def even(self): return [x for x in self._obj if x % 2 == 0] Back in an interactive IPython session: + .. code-block:: ipython + >>> df = pd.DataFrame.from_dict({ 'row1': {'1':1, '2':'a'}, 'row2': {'1':2, '2':'b'} From ed15adf1f06fe6519edab2248389b346f57b7298 Mon Sep 17 00:00:00 2001 From: TechnoShip123 <75491816+TechnoShip123@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:32:25 -0500 Subject: [PATCH 06/17] fix newline --- pandas/core/accessor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 126f9ddb4fdc3..0bc871e0c377a 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -313,7 +313,6 @@ def __init__(self, pandas_obj): def sum(self): return self._obj.sum() - Back in an interactive IPython session: .. code-block:: ipython @@ -359,7 +358,6 @@ def __init__(self, pandas_obj): def sum(self): return self._obj.sum() - Back in an interactive IPython session: .. code-block:: ipython From 7e45c99585e54354c4624b595f1ccf19d384b8e5 Mon Sep 17 00:00:00 2001 From: TechnoShip123 <75491816+TechnoShip123@users.noreply.github.com> Date: Sun, 17 Mar 2024 16:29:27 -0500 Subject: [PATCH 07/17] Remove redundant code-block directives --- pandas/core/accessor.py | 76 +++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 44 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 0bc871e0c377a..57711f2d272ba 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -301,8 +301,6 @@ def decorator(accessor): .. code-block:: python - import pandas as pd - @pd.api.extensions.register_dataframe_accessor("int_accessor") class IntAccessor: def __init__(self, pandas_obj): @@ -315,18 +313,16 @@ def sum(self): Back in an interactive IPython session: -.. code-block:: ipython - - >>> df = pd.DataFrame([[1, 2], ['x', 'y']]) - >>> df.int_accessor - Traceback (most recent call last): - ... - AttributeError: All columns must contain integer values only. - >>> df = pd.DataFrame([[1, 2], [3, 4]]) - >>> df.int_accessor.sum() - 0 4 - 1 6 - dtype: int64 +>>> df = pd.DataFrame([[1, 2], ['x', 'y']]) +>>> df.int_accessor +Traceback (most recent call last): +... +AttributeError: All columns must contain integer values only. +>>> df = pd.DataFrame([[1, 2], [3, 4]]) +>>> df.int_accessor.sum() +0 4 +1 6 +dtype: int64 """ @@ -346,8 +342,6 @@ def register_dataframe_accessor(name: str): .. code-block:: python - import pandas as pd - @pd.api.extensions.register_series_accessor("int_accessor") class IntAccessor: def __init__(self, pandas_obj): @@ -360,16 +354,14 @@ def sum(self): Back in an interactive IPython session: -.. code-block:: ipython - - >>> df = pd.Series([1, 2, 'x']) - >>> df.int_accessor - Traceback (most recent call last): - ... - AttributeError: The series must contain integer data only. - >>> df = pd.Series([1, 2, 3]) - >>> df.int_accessor.sum - 6 +>>> df = pd.Series([1, 2, 'x']) +>>> df.int_accessor +Traceback (most recent call last): +... +AttributeError: The series must contain integer data only. +>>> df = pd.Series([1, 2, 3]) +>>> df.int_accessor.sum +6 """ @@ -389,8 +381,6 @@ def register_series_accessor(name: str): .. code-block:: python - import pandas as pd - @pd.api.extensions.register_index_accessor("int_accessor") class IntAccessor: def __init__(self, pandas_obj): @@ -403,22 +393,20 @@ def even(self): Back in an interactive IPython session: -.. code-block:: ipython - - >>> df = pd.DataFrame.from_dict({ - 'row1': {'1':1, '2':'a'}, - 'row2': {'1':2, '2':'b'} - },orient='index') - >>> df.index.int_accessor - Traceback (most recent call last): - ... - AttributeError: The index must only be an integer value. - >>> df = pd.DataFrame({ - 'col1': [1, 2, 3, 4], - 'col2': ['a', 'b', 'c', 'd'] - }, index=[1, 2, 5, 8]) - >>> df.index.my_accessor.even() - [2,8] +>>> df = pd.DataFrame.from_dict({ + 'row1': {'1':1, '2':'a'}, + 'row2': {'1':2, '2':'b'} + },orient='index') +>>> df.index.int_accessor +Traceback (most recent call last): +... +AttributeError: The index must only be an integer value. +>>> df = pd.DataFrame({ + 'col1': [1, 2, 3, 4], + 'col2': ['a', 'b', 'c', 'd'] + }, index=[1, 2, 5, 8]) +>>> df.index.my_accessor.even() +[2,8] """ From 2c47a6f0e15416fd296e45601b31fb298f90b1cc Mon Sep 17 00:00:00 2001 From: TechnoShip123 <75491816+TechnoShip123@users.noreply.github.com> Date: Sun, 17 Mar 2024 16:47:46 -0500 Subject: [PATCH 08/17] Use variables for `Examples` content --- pandas/core/accessor.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 57711f2d272ba..6c767e043848c 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -234,7 +234,7 @@ def __get__(self, obj, cls): return accessor_obj -@doc(klass="", others="") +@doc(klass="", examples="", others="") def _register_accessor(name: str, cls): """ Register a custom accessor on {klass} objects. @@ -275,6 +275,9 @@ def _register_accessor(name: str, cls): * Accessible using the @property decorator if no additional arguments are needed. + Examples + -------- + {examples} """ def decorator(accessor): @@ -293,9 +296,7 @@ def decorator(accessor): return decorator -_register_df_doc = """ -Examples --------- +_register_df_examples = """ In your library code, an accessor that only accepts integers could have a class defined like this: @@ -326,17 +327,14 @@ def sum(self): """ -@Appender(_register_df_doc) -@doc(_register_accessor, klass="DataFrame") +@doc(_register_accessor, klass="DataFrame", examples=_register_df_examples) def register_dataframe_accessor(name: str): from pandas import DataFrame return _register_accessor(name, DataFrame) -_series_doc = """ -Examples --------- +_register_series_examples = """ In your library code, an accessor that only accepts integers could have a class defined like this: @@ -365,17 +363,14 @@ def sum(self): """ -@Appender(_series_doc) -@doc(_register_accessor, klass="Series") +@doc(_register_accessor, klass="Series", examples=_register_series_examples) def register_series_accessor(name: str): from pandas import Series return _register_accessor(name, Series) -_index_doc = """ -Examples --------- +_register_index_examples = """ In your library code, an accessor that only accepts integers could have a class defined like this: @@ -410,8 +405,7 @@ def even(self): """ -@Appender(_index_doc) -@doc(_register_accessor, klass="Index") +@doc(_register_accessor, klass="Index", examples=_register_index_examples) def register_index_accessor(name: str): from pandas import Index From 64866c6c23675e7239cc649353f8da94686c602e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 17 Mar 2024 21:51:08 +0000 Subject: [PATCH 09/17] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pandas/core/accessor.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 6c767e043848c..2aabb614623c5 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -13,10 +13,7 @@ ) import warnings -from pandas.util._decorators import ( - Appender, - doc, -) +from pandas.util._decorators import doc from pandas.util._exceptions import find_stack_level From 604bbb08b2029b2d1f87336c2186e8cd76b24931 Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:07:42 -0500 Subject: [PATCH 10/17] Fix docstring validation errors Co-authored-by: s1099 <46890315+s1099@users.noreply.github.com> --- pandas/core/accessor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 2aabb614623c5..468da5cdbf552 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -393,10 +393,9 @@ def even(self): Traceback (most recent call last): ... AttributeError: The index must only be an integer value. ->>> df = pd.DataFrame({ - 'col1': [1, 2, 3, 4], - 'col2': ['a', 'b', 'c', 'd'] - }, index=[1, 2, 5, 8]) +>>> df = pd.DataFrame( +... {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8] +... ) >>> df.index.my_accessor.even() [2,8] """ From c6fee4704325bbe75f94a0e11d71a6352d4f2a6e Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:07:49 -0500 Subject: [PATCH 11/17] Fix docstring validation errors Co-authored-by: s1099 <46890315+s1099@users.noreply.github.com> --- pandas/core/accessor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 468da5cdbf552..dffb5d084f05d 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -385,10 +385,9 @@ def even(self): Back in an interactive IPython session: ->>> df = pd.DataFrame.from_dict({ - 'row1': {'1':1, '2':'a'}, - 'row2': {'1':2, '2':'b'} - },orient='index') +>>> df = pd.DataFrame.from_dict( +... {"row1": {"1": 1, "2": "a"}, "row2": {"1": 2, "2": "b"}}, orient="index" +... ) >>> df.index.int_accessor Traceback (most recent call last): ... From 884575053ba1a752cd541a30741572bc0d133903 Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:49:48 -0500 Subject: [PATCH 12/17] Fix CI errors --- ci/code_checks.sh | 3 +++ pandas/core/accessor.py | 9 +++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 9c39fac13b230..91c91818407ac 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -598,6 +598,9 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.api.extensions.ExtensionArray.unique RT03,SA01" \ -i "pandas.api.extensions.ExtensionArray.view SA01" \ -i "pandas.api.extensions.register_extension_dtype SA01" \ + -i "pandas.api.extensions.register_index_accessor" \ + -i "pandas.api.extensions.register_series_accessor" \ + -i "pandas.api.extensions.register_dataframe_accessor" \ -i "pandas.api.indexers.BaseIndexer PR01,SA01" \ -i "pandas.api.indexers.FixedForwardWindowIndexer PR01,SA01" \ -i "pandas.api.indexers.VariableOffsetWindowIndexer PR01,SA01" \ diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index dffb5d084f05d..08c793f9c2c85 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -320,8 +320,7 @@ def sum(self): >>> df.int_accessor.sum() 0 4 1 6 -dtype: int64 -""" +dtype: int64""" @doc(_register_accessor, klass="DataFrame", examples=_register_df_examples) @@ -356,8 +355,7 @@ def sum(self): AttributeError: The series must contain integer data only. >>> df = pd.Series([1, 2, 3]) >>> df.int_accessor.sum -6 -""" +6""" @doc(_register_accessor, klass="Series", examples=_register_series_examples) @@ -396,8 +394,7 @@ def even(self): ... {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8] ... ) >>> df.index.my_accessor.even() -[2,8] -""" +[2,8]""" @doc(_register_accessor, klass="Index", examples=_register_index_examples) From 32dc509b66d432d2cece20b835316454919abbdd Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:12:41 -0500 Subject: [PATCH 13/17] Fix CI errors --- pandas/core/accessor.py | 77 +++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 45 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 08c793f9c2c85..c889ab37a1696 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -294,23 +294,19 @@ def decorator(accessor): _register_df_examples = """ -In your library code, an accessor that only accepts integers could +An accessor that only accepts integers could have a class defined like this: -.. code-block:: python - - @pd.api.extensions.register_dataframe_accessor("int_accessor") - class IntAccessor: - def __init__(self, pandas_obj): - if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): - raise AttributeError("All columns must contain integer values only") - self._obj = pandas_obj - - def sum(self): - return self._obj.sum() - -Back in an interactive IPython session: - +>>> @pd.api.extensions.register_dataframe_accessor("int_accessor") +... class IntAccessor: +... def __init__(self, pandas_obj): +... if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): +... raise AttributeError("All columns must contain integer values only") +... self._obj = pandas_obj +... +... def sum(self): +... return self._obj.sum() +... >>> df = pd.DataFrame([[1, 2], ['x', 'y']]) >>> df.int_accessor Traceback (most recent call last): @@ -331,23 +327,19 @@ def register_dataframe_accessor(name: str): _register_series_examples = """ -In your library code, an accessor that only accepts integers could +An accessor that only accepts integers could have a class defined like this: -.. code-block:: python - - @pd.api.extensions.register_series_accessor("int_accessor") - class IntAccessor: - def __init__(self, pandas_obj): - if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): - raise AttributeError("All columns must contain integer values only") - self._obj = pandas_obj - - def sum(self): - return self._obj.sum() - -Back in an interactive IPython session: - +>>> @pd.api.extensions.register_series_accessor("int_accessor") +... class IntAccessor: +... def __init__(self, pandas_obj): +... if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): +... raise AttributeError("All columns must contain integer values only") +... self._obj = pandas_obj +... +... def sum(self): +... return self._obj.sum() +... >>> df = pd.Series([1, 2, 'x']) >>> df.int_accessor Traceback (most recent call last): @@ -366,23 +358,18 @@ def register_series_accessor(name: str): _register_index_examples = """ -In your library code, an accessor that only accepts integers could +An accessor that only accepts integers could have a class defined like this: -.. code-block:: python - - @pd.api.extensions.register_index_accessor("int_accessor") - class IntAccessor: - def __init__(self, pandas_obj): - if not all(isinstance(x, int) for x in pandas_obj): - raise AttributeError("The index must only be an integer value") - self._obj = pandas_obj - - def even(self): - return [x for x in self._obj if x % 2 == 0] - -Back in an interactive IPython session: - +>>> @pd.api.extensions.register_index_accessor("int_accessor") +... class IntAccessor: +... def __init__(self, pandas_obj): +... if not all(isinstance(x, int) for x in pandas_obj): +... raise AttributeError("The index must only be an integer value") +... self._obj = pandas_obj +... +... def even(self): +... return [x for x in self._obj if x % 2 == 0] >>> df = pd.DataFrame.from_dict( ... {"row1": {"1": 1, "2": "a"}, "row2": {"1": 2, "2": "b"}}, orient="index" ... ) From 958428fc635b35e1fc59a48a45dabba06e557844 Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:28:52 -0500 Subject: [PATCH 14/17] Fix CI errors --- pandas/core/accessor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index c889ab37a1696..26e087196d67d 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -333,8 +333,8 @@ def register_dataframe_accessor(name: str): >>> @pd.api.extensions.register_series_accessor("int_accessor") ... class IntAccessor: ... def __init__(self, pandas_obj): -... if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns): -... raise AttributeError("All columns must contain integer values only") +... if not pandas_obj.dtype == 'int64': +... raise AttributeError("The series must contain integer data only") ... self._obj = pandas_obj ... ... def sum(self): @@ -346,7 +346,7 @@ def register_dataframe_accessor(name: str): ... AttributeError: The series must contain integer data only. >>> df = pd.Series([1, 2, 3]) ->>> df.int_accessor.sum +>>> df.int_accessor.sum() 6""" From 2ef33aaef316bfaa998095ed8776bcec4b4a2d8c Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:39:44 -0500 Subject: [PATCH 15/17] Fix CI errors --- pandas/core/accessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 26e087196d67d..1a8b69ad3866b 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -380,7 +380,7 @@ def register_series_accessor(name: str): >>> df = pd.DataFrame( ... {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8] ... ) ->>> df.index.my_accessor.even() +>>> df.index.int_accessor.even() [2,8]""" From a7e6e37159b787164d5673c883ed9ebdb7f140e9 Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Mon, 1 Apr 2024 18:51:08 -0500 Subject: [PATCH 16/17] Fix CI errors (again lol) --- pandas/core/accessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/accessor.py b/pandas/core/accessor.py index 1a8b69ad3866b..aa2bf2f527bd8 100644 --- a/pandas/core/accessor.py +++ b/pandas/core/accessor.py @@ -381,7 +381,7 @@ def register_series_accessor(name: str): ... {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8] ... ) >>> df.index.int_accessor.even() -[2,8]""" +[2, 8]""" @doc(_register_accessor, klass="Index", examples=_register_index_examples) From 67805c7d8f20ee7ba7253dcd6c41b011b7d39bb6 Mon Sep 17 00:00:00 2001 From: sjalkote <75491816+sjalkote@users.noreply.github.com> Date: Tue, 2 Apr 2024 17:49:39 -0500 Subject: [PATCH 17/17] Undo validation ignore for docstrings --- ci/code_checks.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 91c91818407ac..9c39fac13b230 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -598,9 +598,6 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.api.extensions.ExtensionArray.unique RT03,SA01" \ -i "pandas.api.extensions.ExtensionArray.view SA01" \ -i "pandas.api.extensions.register_extension_dtype SA01" \ - -i "pandas.api.extensions.register_index_accessor" \ - -i "pandas.api.extensions.register_series_accessor" \ - -i "pandas.api.extensions.register_dataframe_accessor" \ -i "pandas.api.indexers.BaseIndexer PR01,SA01" \ -i "pandas.api.indexers.FixedForwardWindowIndexer PR01,SA01" \ -i "pandas.api.indexers.VariableOffsetWindowIndexer PR01,SA01" \