From 5e04aa2e1abd0b043681e6ee953cbe935d9d187b Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 12:33:54 -0400 Subject: [PATCH 01/34] - implemented type-coercion for dataclasses - added a is_dataclass_inst function to detect dataclasses --- pandas/core/dtypes/common.py | 1 + pandas/core/dtypes/inference.py | 31 +++++++++++++++++++++++++++++++ pandas/core/frame.py | 7 ++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index f75493be2dab1..374be23acf0ec 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -46,6 +46,7 @@ is_scalar, is_sequence, is_string_like, + is_dataclass_instance, ) from pandas._typing import ArrayLike diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 461b5cc6232cd..9e6e7ca1bb274 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -2,6 +2,7 @@ from collections import abc from numbers import Number +import dataclasses import re from typing import Pattern @@ -450,3 +451,33 @@ def is_sequence(obj): return not isinstance(obj, (str, bytes)) except (TypeError, AttributeError): return False + +def is_dataclass_instance(item) -> bool: + """ + Checks if the object is a data-class instance + + Parameters + ---------- + item : the object to check + + Returns + -------- + is_dataclass_instance : bool + True if the item is an instance of a data-class, will return false if you pass the data class itself + + Examples + -------- + >>> @dataclass + >>> class Point: + >>> x: int + >>> y: int + + >>> is_dataclass_instance(Point) + False + >>> is_dataclass_instance(Point(0,2)) + True + + """ + return dataclasses.is_dataclass(item) and not isinstance(item, type) + + \ No newline at end of file diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 603a615c1f8cb..9fa957c3eea2d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -16,6 +16,8 @@ import sys from textwrap import dedent from typing import FrozenSet, List, Optional, Set, Tuple, Type, Union +import dataclasses + import warnings import numpy as np @@ -71,6 +73,7 @@ is_scalar, is_sequence, needs_i8_conversion, + is_dataclass_instance, ) from pandas.core.dtypes.generic import ( ABCDataFrame, @@ -437,10 +440,12 @@ def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): # For data is list-like, or Iterable (will consume into list) elif isinstance(data, abc.Iterable) and not isinstance(data, (str, bytes)): + if is_dataclass_instance(data[0]): + data = map(dataclasses.asdict, data) if not isinstance(data, abc.Sequence): data = list(data) if len(data) > 0: - if is_list_like(data[0]) and getattr(data[0], "ndim", 1) == 1: + if (is_list_like(data[0]) and getattr(data[0], "ndim", 1) == 1): if is_named_tuple(data[0]) and columns is None: columns = data[0]._fields arrays, columns = to_arrays(data, columns, dtype=dtype) From e0a089f909629a737a1e0ef75bbd56fcdd2339a2 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 12:48:25 -0400 Subject: [PATCH 02/34] added unit tests --- pandas/tests/frame/test_constructors.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index ebffeeaa3063e..2736eaa0c0f7b 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1335,6 +1335,22 @@ def test_constructor_list_of_namedtuples(self): expected = DataFrame({"y": [1, 2], "z": [3, 4]}) result = DataFrame(tuples, columns=["y", "z"]) tm.assert_frame_equal(result, expected) + + def test_constructor_dataclasses(self): + from dataclasses import dataclass + + @dataclass + class Point: + x: int + y: int + + datas = [Point(0,3), Point(1,3)] + expected = DataFrame({ + "x": [0,1], + "y": [3,3], + }) + result = DataFrame(datas) + tm.assert_frame_equal(result, expected) def test_constructor_list_of_dict_order(self): # GH10056 From 7de46ca74d5239e9c341f71f7013da5ec018c97a Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 12:49:07 -0400 Subject: [PATCH 03/34] added github issue to unit test --- pandas/tests/frame/test_constructors.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 2736eaa0c0f7b..49a12d51b9730 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1337,6 +1337,7 @@ def test_constructor_list_of_namedtuples(self): tm.assert_frame_equal(result, expected) def test_constructor_dataclasses(self): + # GH21910 from dataclasses import dataclass @dataclass From 05f3f280845c1bbfb00cd6802e3a19e5406f35c2 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 12:59:21 -0400 Subject: [PATCH 04/34] pep8 compliance --- pandas/core/dtypes/inference.py | 11 ++++++----- pandas/tests/frame/test_constructors.py | 10 +++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 9e6e7ca1bb274..f7a6b516e5cac 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -452,18 +452,20 @@ def is_sequence(obj): except (TypeError, AttributeError): return False + def is_dataclass_instance(item) -> bool: """ Checks if the object is a data-class instance - + Parameters ---------- item : the object to check - + Returns -------- - is_dataclass_instance : bool - True if the item is an instance of a data-class, will return false if you pass the data class itself + is_dataclass_instance : bool + True if the item is an instance of a data-class, + will return false if you pass the data class itself Examples -------- @@ -480,4 +482,3 @@ def is_dataclass_instance(item) -> bool: """ return dataclasses.is_dataclass(item) and not isinstance(item, type) - \ No newline at end of file diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 49a12d51b9730..7907d943e0657 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1335,7 +1335,7 @@ def test_constructor_list_of_namedtuples(self): expected = DataFrame({"y": [1, 2], "z": [3, 4]}) result = DataFrame(tuples, columns=["y", "z"]) tm.assert_frame_equal(result, expected) - + def test_constructor_dataclasses(self): # GH21910 from dataclasses import dataclass @@ -1344,11 +1344,11 @@ def test_constructor_dataclasses(self): class Point: x: int y: int - - datas = [Point(0,3), Point(1,3)] + + datas = [Point(0, 3), Point(1, 3)] expected = DataFrame({ - "x": [0,1], - "y": [3,3], + "x": [0,1], + "y": [3,3], }) result = DataFrame(datas) tm.assert_frame_equal(result, expected) From 3ec492d2bbbf85bddebe4ee4d82a30b09ca9e9a7 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 19:38:42 -0400 Subject: [PATCH 05/34] masking functions for lower versions of python --- pandas/core/dtypes/inference.py | 9 ++++++--- pandas/core/frame.py | 4 ++-- pandas/core/internals/construction.py | 3 +++ pandas/tests/frame/test_constructors.py | 5 ++++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index f7a6b516e5cac..a3e981ae7f115 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -2,7 +2,6 @@ from collections import abc from numbers import Number -import dataclasses import re from typing import Pattern @@ -453,7 +452,7 @@ def is_sequence(obj): return False -def is_dataclass_instance(item) -> bool: +def is_dataclass_instance(item): """ Checks if the object is a data-class instance @@ -480,5 +479,9 @@ def is_dataclass_instance(item) -> bool: True """ - return dataclasses.is_dataclass(item) and not isinstance(item, type) + try: + from dataclasses import is_dataclass + return is_dataclass(item) and not isinstance(item, type) + except ImportError: + return False diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 9fa957c3eea2d..40d26b440a6d6 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -16,7 +16,6 @@ import sys from textwrap import dedent from typing import FrozenSet, List, Optional, Set, Tuple, Type, Union -import dataclasses import warnings @@ -110,6 +109,7 @@ reorder_arrays, sanitize_index, to_arrays, + _dataclasses_to_dicts, ) from pandas.core.series import Series @@ -441,7 +441,7 @@ def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): # For data is list-like, or Iterable (will consume into list) elif isinstance(data, abc.Iterable) and not isinstance(data, (str, bytes)): if is_dataclass_instance(data[0]): - data = map(dataclasses.asdict, data) + data = _dataclasses_to_dicts(data) if not isinstance(data, abc.Sequence): data = list(data) if len(data) > 0: diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 3126b9d9d3e2e..150abbb3ef83c 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -421,6 +421,9 @@ def _get_axes(N, K, index, columns): columns = ensure_index(columns) return index, columns +def _dataclasses_to_dicts(data): + from dataclasses import asdict + return map(asdict, data) # --------------------------------------------------------------------- # Conversion of Inputs to Arrays diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 7907d943e0657..f0713d883f68d 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1338,7 +1338,10 @@ def test_constructor_list_of_namedtuples(self): def test_constructor_dataclasses(self): # GH21910 - from dataclasses import dataclass + try: + from dataclasses import dataclass + except ImportError: + return; @dataclass class Point: From 6c605e027e31610e27e047c630d688814acdc735 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 21:10:21 -0400 Subject: [PATCH 06/34] ran black pandas --- pandas/core/dtypes/inference.py | 2 +- pandas/core/frame.py | 2 +- pandas/core/internals/construction.py | 3 +++ pandas/tests/frame/test_constructors.py | 7 ++----- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index a3e981ae7f115..25623a552bd19 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -481,7 +481,7 @@ def is_dataclass_instance(item): """ try: from dataclasses import is_dataclass + return is_dataclass(item) and not isinstance(item, type) except ImportError: return False - diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 40d26b440a6d6..49bc356b9c465 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -445,7 +445,7 @@ def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): if not isinstance(data, abc.Sequence): data = list(data) if len(data) > 0: - if (is_list_like(data[0]) and getattr(data[0], "ndim", 1) == 1): + if is_list_like(data[0]) and getattr(data[0], "ndim", 1) == 1: if is_named_tuple(data[0]) and columns is None: columns = data[0]._fields arrays, columns = to_arrays(data, columns, dtype=dtype) diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 150abbb3ef83c..e738789e3aad5 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -421,10 +421,13 @@ def _get_axes(N, K, index, columns): columns = ensure_index(columns) return index, columns + def _dataclasses_to_dicts(data): from dataclasses import asdict + return map(asdict, data) + # --------------------------------------------------------------------- # Conversion of Inputs to Arrays diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index f0713d883f68d..9ae0c886102d6 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1341,7 +1341,7 @@ def test_constructor_dataclasses(self): try: from dataclasses import dataclass except ImportError: - return; + return @dataclass class Point: @@ -1349,10 +1349,7 @@ class Point: y: int datas = [Point(0, 3), Point(1, 3)] - expected = DataFrame({ - "x": [0,1], - "y": [3,3], - }) + expected = DataFrame({"x": [0, 1], "y": [3, 3]}) result = DataFrame(datas) tm.assert_frame_equal(result, expected) From 107cdc4c9ef74ba014904e0628bed15ac0afc375 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 18 Aug 2019 21:54:14 -0400 Subject: [PATCH 07/34] corrected index issue --- pandas/core/frame.py | 4 ++-- pandas/core/internals/construction.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 49bc356b9c465..e58bfcfe1a943 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -440,11 +440,11 @@ def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): # For data is list-like, or Iterable (will consume into list) elif isinstance(data, abc.Iterable) and not isinstance(data, (str, bytes)): - if is_dataclass_instance(data[0]): - data = _dataclasses_to_dicts(data) if not isinstance(data, abc.Sequence): data = list(data) if len(data) > 0: + if is_dataclass_instance(data[0]): + data = _dataclasses_to_dicts(data) if is_list_like(data[0]) and getattr(data[0], "ndim", 1) == 1: if is_named_tuple(data[0]) and columns is None: columns = data[0]._fields diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index e738789e3aad5..ddf03a089a769 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -425,7 +425,7 @@ def _get_axes(N, K, index, columns): def _dataclasses_to_dicts(data): from dataclasses import asdict - return map(asdict, data) + return list(map(asdict, data)) # --------------------------------------------------------------------- From 116813789a3258bf18761549247893c8702e754f Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Mon, 19 Aug 2019 07:42:11 -0400 Subject: [PATCH 08/34] removed py3.7 specific syntax using make_dataclass in tests --- pandas/tests/frame/test_constructors.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 9ae0c886102d6..ee24b1cdac18d 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1339,14 +1339,10 @@ def test_constructor_list_of_namedtuples(self): def test_constructor_dataclasses(self): # GH21910 try: - from dataclasses import dataclass + from dataclasses import make_dataclass except ImportError: return - - @dataclass - class Point: - x: int - y: int + Point = make_dataclass("Point", [("x", int), ("y", int)]) datas = [Point(0, 3), Point(1, 3)] expected = DataFrame({"x": [0, 1], "y": [3, 3]}) From 863b33a895710f9cea56feaeeda26ca495a9d197 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Mon, 19 Aug 2019 16:54:01 -0400 Subject: [PATCH 09/34] corrected pytest requirements --- pandas/tests/frame/test_constructors.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index ee24b1cdac18d..440afb5ac4cd5 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1336,12 +1336,11 @@ def test_constructor_list_of_namedtuples(self): result = DataFrame(tuples, columns=["y", "z"]) tm.assert_frame_equal(result, expected) - def test_constructor_dataclasses(self): + @pytest.mark.skipif(not compat.PY36, reason="Requires Python >= 3.6") + def test_constructor_list_of_dataclasses(self): # GH21910 - try: - from dataclasses import make_dataclass - except ImportError: - return + from dataclasses import make_dataclass + Point = make_dataclass("Point", [("x", int), ("y", int)]) datas = [Point(0, 3), Point(1, 3)] From 2177165c7a34d70f48855b8d008ec73359f804bb Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Mon, 19 Aug 2019 20:07:48 -0400 Subject: [PATCH 10/34] corrected unit tests --- pandas/tests/frame/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 440afb5ac4cd5..bf0b3f9f7c0ad 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1336,7 +1336,7 @@ def test_constructor_list_of_namedtuples(self): result = DataFrame(tuples, columns=["y", "z"]) tm.assert_frame_equal(result, expected) - @pytest.mark.skipif(not compat.PY36, reason="Requires Python >= 3.6") + @pytest.mark.skipif(not PY36, reason="Requires Python >= 3.6") def test_constructor_list_of_dataclasses(self): # GH21910 from dataclasses import make_dataclass From 65640edc0cbe2181b62fef67e1e29af00623c077 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Mon, 19 Aug 2019 20:41:55 -0400 Subject: [PATCH 11/34] dataclasses require py37 not py36 --- pandas/tests/frame/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index bf0b3f9f7c0ad..4506c6eba63e1 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1336,7 +1336,7 @@ def test_constructor_list_of_namedtuples(self): result = DataFrame(tuples, columns=["y", "z"]) tm.assert_frame_equal(result, expected) - @pytest.mark.skipif(not PY36, reason="Requires Python >= 3.6") + @pytest.mark.skipif(not PY37, reason="Requires Python >= 3.7") def test_constructor_list_of_dataclasses(self): # GH21910 from dataclasses import make_dataclass From afc5c3eaf8972e068264077f7285df26f3f9137b Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Mon, 19 Aug 2019 20:54:52 -0400 Subject: [PATCH 12/34] added additional unit tests for more specific cases --- pandas/tests/frame/test_constructors.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 4506c6eba63e1..0d97aa0048d1d 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -8,7 +8,7 @@ import numpy.ma.mrecords as mrecords import pytest -from pandas.compat import PY36, is_platform_little_endian +from pandas.compat import PY36, PY37, is_platform_little_endian from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike from pandas.core.dtypes.common import is_integer_dtype @@ -1348,6 +1348,22 @@ def test_constructor_list_of_dataclasses(self): result = DataFrame(datas) tm.assert_frame_equal(result, expected) + # varying types + Point = make_dataclass("Point", [("x", int), ("y", int)]) + HLine = make_dataclass("HLine", [("x0", int), ("x1", int), ("y", int)]) + + datas = [Point(0, 3), HLine(1, 3, 3)] + + expected = DataFrame( + {"x": [0, np.nan], "y": [3, 3], "x0": [np.nan, 1], "x1": [np.nan, 3]} + ) + result = DataFrame(datas) + tm.assert_frame_equal(result, expected) + + # expect TypeError + with pytest.raises(TypeError): + DataFrame([Point(0, 0), {"x": 1, "y": 0}]) + def test_constructor_list_of_dict_order(self): # GH10056 data = [ From ca792bc6fdaed29a8d7b797dcc2191b8f5f72fad Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Tue, 20 Aug 2019 07:39:23 -0400 Subject: [PATCH 13/34] removed white space --- pandas/core/dtypes/inference.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 25623a552bd19..3fe2b09baf939 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -481,7 +481,6 @@ def is_dataclass_instance(item): """ try: from dataclasses import is_dataclass - return is_dataclass(item) and not isinstance(item, type) except ImportError: return False From 80cfc51a832f66314c89848286f57c87f2192c1b Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Tue, 20 Aug 2019 09:37:57 -0400 Subject: [PATCH 14/34] docs --- doc/source/getting_started/dsintro.rst | 21 +++++++++++++++++++++ pandas/core/dtypes/inference.py | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 9e18951fe3f4c..c95533e49f58f 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -397,6 +397,27 @@ The result will be a DataFrame with the same index as the input Series, and with one column whose name is the original name of the Series (only if no other column name provided). +From a list of dataclasses +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +dataclasses as introduced in `PEP557 `, +can be passed into the DataFrame constructor. +Passing a list of dataclasses is equivilent to passing a list of dictionaries. However, +it is imperative that all values in the list are dataclasses otherwise expect a TypeError. + +.. ipython:: python + + from dataclasses import make_dataclass + + Point = make_dataclass("Point", [("x", int), ("y", int)]) + HLine = make_dataclass("HLine", [("x0", int), ("x1", int), ("y", int)]) + + data = [Point(0,0), HLine(0,3,10), Point(2,3)] + df = pd.DataFrame(data) + +.. _basics.dataframe.from_list_dataclasses: + + **Missing data** Much more will be said on this topic in the :ref:`Missing data ` diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 3fe2b09baf939..95b7d58090842 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -462,8 +462,8 @@ def is_dataclass_instance(item): Returns -------- - is_dataclass_instance : bool - True if the item is an instance of a data-class, + is_dataclass_instance : bool + True if the item is an instance of a data-class, will return false if you pass the data class itself Examples From 2866e5e2d58dfa026fae4e0f2033a045c5d78413 Mon Sep 17 00:00:00 2001 From: Ari Sosnovsky Date: Tue, 20 Aug 2019 10:24:09 -0400 Subject: [PATCH 15/34] Update doc/source/getting_started/dsintro.rst Co-Authored-By: Tom Augspurger --- doc/source/getting_started/dsintro.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index c95533e49f58f..6bc0ab237cd9a 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -400,6 +400,7 @@ column name provided). From a list of dataclasses ~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. versionadded:: 1.0.0 dataclasses as introduced in `PEP557 `, can be passed into the DataFrame constructor. Passing a list of dataclasses is equivilent to passing a list of dictionaries. However, From 03638961192e4546ae9a8b9571ab4bcb12cac7a0 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Wed, 21 Aug 2019 09:19:47 -0400 Subject: [PATCH 16/34] updated docs --- doc/source/getting_started/dsintro.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index c95533e49f58f..4dcf1adf70b67 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -397,13 +397,17 @@ The result will be a DataFrame with the same index as the input Series, and with one column whose name is the original name of the Series (only if no other column name provided). +.. _basics.dataframe.from_list_dataclasses: + From a list of dataclasses ~~~~~~~~~~~~~~~~~~~~~~~~~~ dataclasses as introduced in `PEP557 `, can be passed into the DataFrame constructor. -Passing a list of dataclasses is equivilent to passing a list of dictionaries. However, -it is imperative that all values in the list are dataclasses otherwise expect a TypeError. +Passing a list of dataclasses is equivilent to passing a list of dictionaries. + +Please be aware, that that all values in the list should be dataclasses, mixing +types in the list would result in a TypeError. .. ipython:: python @@ -415,7 +419,6 @@ it is imperative that all values in the list are dataclasses otherwise expect a data = [Point(0,0), HLine(0,3,10), Point(2,3)] df = pd.DataFrame(data) -.. _basics.dataframe.from_list_dataclasses: **Missing data** From 9248f1625c7bd2939e388d6c94f90b87efb898ae Mon Sep 17 00:00:00 2001 From: Ari Sosnovsky Date: Wed, 21 Aug 2019 09:20:20 -0400 Subject: [PATCH 17/34] Update doc/source/getting_started/dsintro.rst Co-Authored-By: Joris Van den Bossche --- doc/source/getting_started/dsintro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 6bc0ab237cd9a..2b9f15e49ce51 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -401,7 +401,7 @@ From a list of dataclasses ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.0.0 -dataclasses as introduced in `PEP557 `, +Data Classes as introduced in `PEP557 `__, can be passed into the DataFrame constructor. Passing a list of dataclasses is equivilent to passing a list of dictionaries. However, it is imperative that all values in the list are dataclasses otherwise expect a TypeError. From c2702f952472746fcf8c12f78a44030405e3b1e3 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Wed, 21 Aug 2019 09:22:18 -0400 Subject: [PATCH 18/34] updated doc/source/getting_started/dsintro.rst --- doc/source/getting_started/dsintro.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 2c6e24606d316..97790847d9220 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -403,6 +403,7 @@ From a list of dataclasses ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.0.0 + Data Classes as introduced in `PEP557 `__, can be passed into the DataFrame constructor. Passing a list of dataclasses is equivilent to passing a list of dictionaries. @@ -415,9 +416,8 @@ types in the list would result in a TypeError. from dataclasses import make_dataclass Point = make_dataclass("Point", [("x", int), ("y", int)]) - HLine = make_dataclass("HLine", [("x0", int), ("x1", int), ("y", int)]) - data = [Point(0,0), HLine(0,3,10), Point(2,3)] + data = [Point(0,0), Point(0,3), Point(2,3)] df = pd.DataFrame(data) From ea76809654ccd111342ed5d65aa87cc71e9174e5 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Wed, 21 Aug 2019 12:16:16 -0400 Subject: [PATCH 19/34] ran linters --- doc/source/getting_started/dsintro.rst | 8 +++----- pandas/core/dtypes/inference.py | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 97790847d9220..cf555dedefbaf 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -406,9 +406,9 @@ From a list of dataclasses Data Classes as introduced in `PEP557 `__, can be passed into the DataFrame constructor. -Passing a list of dataclasses is equivilent to passing a list of dictionaries. +Passing a list of dataclasses is equivilent to passing a list of dictionaries. -Please be aware, that that all values in the list should be dataclasses, mixing +Please be aware, that that all values in the list should be dataclasses, mixing types in the list would result in a TypeError. .. ipython:: python @@ -416,12 +416,10 @@ types in the list would result in a TypeError. from dataclasses import make_dataclass Point = make_dataclass("Point", [("x", int), ("y", int)]) - + data = [Point(0,0), Point(0,3), Point(2,3)] df = pd.DataFrame(data) - - **Missing data** Much more will be said on this topic in the :ref:`Missing data ` diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 95b7d58090842..3f8f350cef0fc 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -481,6 +481,7 @@ def is_dataclass_instance(item): """ try: from dataclasses import is_dataclass + return is_dataclass(item) and not isinstance(item, type) except ImportError: return False From dfa8f5264b1dbf76fe64912b9a674fb40264846b Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Wed, 21 Aug 2019 13:19:54 -0400 Subject: [PATCH 20/34] ran isort --- doc/source/getting_started/dsintro.rst | 2 +- pandas/core/dtypes/common.py | 2 +- pandas/core/frame.py | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index cf555dedefbaf..51d346b7a5ddb 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -417,7 +417,7 @@ types in the list would result in a TypeError. Point = make_dataclass("Point", [("x", int), ("y", int)]) - data = [Point(0,0), Point(0,3), Point(2,3)] + data = [Point(0, 0), Point(0, 3), Point(2, 3)] df = pd.DataFrame(data) **Missing data** diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 374be23acf0ec..bcfde1ee78553 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -29,6 +29,7 @@ is_array_like, is_bool, is_complex, + is_dataclass_instance, is_decimal, is_dict_like, is_file_like, @@ -46,7 +47,6 @@ is_scalar, is_sequence, is_string_like, - is_dataclass_instance, ) from pandas._typing import ArrayLike diff --git a/pandas/core/frame.py b/pandas/core/frame.py index e58bfcfe1a943..cd2e726e983e7 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -16,7 +16,6 @@ import sys from textwrap import dedent from typing import FrozenSet, List, Optional, Set, Tuple, Type, Union - import warnings import numpy as np @@ -54,6 +53,7 @@ ensure_platform_int, infer_dtype_from_object, is_bool_dtype, + is_dataclass_instance, is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, @@ -72,7 +72,6 @@ is_scalar, is_sequence, needs_i8_conversion, - is_dataclass_instance, ) from pandas.core.dtypes.generic import ( ABCDataFrame, @@ -101,6 +100,7 @@ from pandas.core.indexing import check_bool_indexer, convert_to_index_sliceable from pandas.core.internals import BlockManager from pandas.core.internals.construction import ( + _dataclasses_to_dicts, arrays_to_mgr, get_names_from_index, init_dict, @@ -109,7 +109,6 @@ reorder_arrays, sanitize_index, to_arrays, - _dataclasses_to_dicts, ) from pandas.core.series import Series From 36954cda4a7498ebc362843f6bfb3eb9047af748 Mon Sep 17 00:00:00 2001 From: Ari Sosnovsky Date: Tue, 27 Aug 2019 17:40:55 -0400 Subject: [PATCH 21/34] Update dsintro.rst --- doc/source/getting_started/dsintro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 51d346b7a5ddb..4fb5e2c36c492 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -418,7 +418,7 @@ types in the list would result in a TypeError. Point = make_dataclass("Point", [("x", int), ("y", int)]) data = [Point(0, 0), Point(0, 3), Point(2, 3)] - df = pd.DataFrame(data) + pd.DataFrame(data) **Missing data** From 804f45e050e64e25d5decdcaf3263b45de2d31be Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Thu, 29 Aug 2019 13:34:38 -0400 Subject: [PATCH 22/34] correcting doc --- pandas/core/dtypes/inference.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 3f8f350cef0fc..b3ed49e1ac6f9 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -458,7 +458,7 @@ def is_dataclass_instance(item): Parameters ---------- - item : the object to check + item : object Returns -------- @@ -470,8 +470,8 @@ def is_dataclass_instance(item): -------- >>> @dataclass >>> class Point: - >>> x: int - >>> y: int + ... x: int + ... y: int >>> is_dataclass_instance(Point) False From e0362905efaf22d4d7cbd1e10e9e9234e1af46df Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Thu, 29 Aug 2019 17:57:26 -0400 Subject: [PATCH 23/34] not overriding the data variable under documentation --- doc/source/getting_started/dsintro.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index 4fb5e2c36c492..0b4071573bed0 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -417,8 +417,7 @@ types in the list would result in a TypeError. Point = make_dataclass("Point", [("x", int), ("y", int)]) - data = [Point(0, 0), Point(0, 3), Point(2, 3)] - pd.DataFrame(data) + pd.DataFrame([Point(0, 0), Point(0, 3), Point(2, 3)]) **Missing data** From 40bada698595e8686c72f4d125d72fa271d6f6ed Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Fri, 6 Sep 2019 23:49:03 -0400 Subject: [PATCH 24/34] split up unit tests --- pandas/tests/frame/test_constructors.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 0d97aa0048d1d..e451555009e91 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1348,6 +1348,11 @@ def test_constructor_list_of_dataclasses(self): result = DataFrame(datas) tm.assert_frame_equal(result, expected) + @pytest.mark.skipif(not PY37, reason="Requires Python >= 3.7") + def test_constructor_list_of_dataclasses_with_varying_types(self): + # GH21910 + from dataclasses import make_dataclass + # varying types Point = make_dataclass("Point", [("x", int), ("y", int)]) HLine = make_dataclass("HLine", [("x0", int), ("x1", int), ("y", int)]) @@ -1360,6 +1365,11 @@ def test_constructor_list_of_dataclasses(self): result = DataFrame(datas) tm.assert_frame_equal(result, expected) + @pytest.mark.skipif(not PY37, reason="Requires Python >= 3.7") + def test_constructor_list_of_dataclasses_error_thrown(self): + # GH21910 + from dataclasses import make_dataclass + # expect TypeError with pytest.raises(TypeError): DataFrame([Point(0, 0), {"x": 1, "y": 0}]) From e0ee75383f81fe2af34772c553d8a0ad978e81b7 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sat, 14 Sep 2019 22:47:04 -0400 Subject: [PATCH 25/34] brought Point back --- pandas/tests/frame/test_constructors.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index e451555009e91..2b065c42addd3 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1369,6 +1369,7 @@ def test_constructor_list_of_dataclasses_with_varying_types(self): def test_constructor_list_of_dataclasses_error_thrown(self): # GH21910 from dataclasses import make_dataclass + Point = make_dataclass("Point", [("x", int), ("y", int)]) # expect TypeError with pytest.raises(TypeError): From 84ddc9f3973bd0714d7756547744ae53c73e0b09 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sat, 7 Dec 2019 15:52:40 -0500 Subject: [PATCH 26/34] added space for formating pass --- pandas/tests/frame/test_constructors.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 2b065c42addd3..1281ef72c0871 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -1369,6 +1369,7 @@ def test_constructor_list_of_dataclasses_with_varying_types(self): def test_constructor_list_of_dataclasses_error_thrown(self): # GH21910 from dataclasses import make_dataclass + Point = make_dataclass("Point", [("x", int), ("y", int)]) # expect TypeError From 5aa8fbb2f08c5817dfd3287b9b6f47e5aa252906 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sat, 7 Dec 2019 18:15:15 -0500 Subject: [PATCH 27/34] finishing merge --- pandas/core/frame.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index be1507f2aa6d7..e9de95fc6329b 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -63,12 +63,9 @@ ensure_platform_int, infer_dtype_from_object, is_bool_dtype, - is_dataclass_instance, is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, - is_dtype_equal, - is_extension_array_dtype, is_float_dtype, is_hashable, is_integer, From 7ff986a77680c5b04c8ebe1d9d00192e7de56f1b Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 5 Jan 2020 16:35:17 -0500 Subject: [PATCH 28/34] fixing missing import --- pandas/core/frame.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index c94f13b8f203e..1256bd7a206de 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -71,6 +71,7 @@ ensure_platform_int, infer_dtype_from_object, is_bool_dtype, + is_dataclass_instance, is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, From 5e8b579ebc04fb8f37cc5f56a75e3bddb3ff97b8 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sun, 5 Jan 2020 17:07:37 -0500 Subject: [PATCH 29/34] corrected isort --- pandas/core/frame.py | 3 ++- pandas/tests/frame/test_constructors.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 01fa261adfc06..3cf3a40db1669 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -73,9 +73,10 @@ infer_dtype_from_object, is_bool_dtype, is_dataclass_instance, - is_datetime64_any_dtype, is_datetime64tz_dtype, is_dict_like, + is_dtype_equal, + is_extension_array_dtype, is_float_dtype, is_hashable, is_integer, diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 8e8492eb217e8..f059668588404 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -8,7 +8,8 @@ import numpy.ma.mrecords as mrecords import pytest -from pandas.compat import PY36, PY37, is_platform_little_endian +from pandas.compat import PY37, is_platform_little_endian + from pandas.core.dtypes.common import is_integer_dtype import pandas as pd From ce8fc1f745fd3d38ba3fe4045e24bc487478dc49 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Mon, 6 Jan 2020 20:34:01 -0500 Subject: [PATCH 30/34] - renamed is_dataclass_instance to is_dataclass - renamed _dataclasses_to_dicts to dataclasses_to_dicts - added docs to dataclasses_to_dicts --- pandas/core/dtypes/common.py | 2 +- pandas/core/dtypes/inference.py | 8 ++++---- pandas/core/frame.py | 9 ++++----- pandas/core/internals/construction.py | 24 +++++++++++++++++++++++- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 210c736a4d632..4f287a563775b 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -28,7 +28,7 @@ is_array_like, is_bool, is_complex, - is_dataclass_instance, + is_dataclass, is_decimal, is_dict_like, is_file_like, diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index bb08c90435391..1929014104982 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -424,7 +424,7 @@ def is_sequence(obj) -> bool: return False -def is_dataclass_instance(item): +def is_dataclass(item): """ Checks if the object is a data-class instance @@ -434,7 +434,7 @@ def is_dataclass_instance(item): Returns -------- - is_dataclass_instance : bool + is_dataclass : bool True if the item is an instance of a data-class, will return false if you pass the data class itself @@ -445,9 +445,9 @@ def is_dataclass_instance(item): ... x: int ... y: int - >>> is_dataclass_instance(Point) + >>> is_dataclass(Point) False - >>> is_dataclass_instance(Point(0,2)) + >>> is_dataclass(Point(0,2)) True """ diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 3cf3a40db1669..5a849914e3d30 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -72,8 +72,7 @@ ensure_platform_int, infer_dtype_from_object, is_bool_dtype, - is_dataclass_instance, - is_datetime64tz_dtype, + is_dataclass, is_dict_like, is_dtype_equal, is_extension_array_dtype, @@ -112,7 +111,7 @@ from pandas.core.indexing import check_bool_indexer, convert_to_index_sliceable from pandas.core.internals import BlockManager from pandas.core.internals.construction import ( - _dataclasses_to_dicts, + dataclasses_to_dicts, arrays_to_mgr, get_names_from_index, init_dict, @@ -467,8 +466,8 @@ def __init__( if not isinstance(data, (abc.Sequence, ExtensionArray)): data = list(data) if len(data) > 0: - if is_dataclass_instance(data[0]): - data = _dataclasses_to_dicts(data) + if is_dataclass(data[0]): + data = dataclasses_to_dicts(data) if is_list_like(data[0]) and getattr(data[0], "ndim", 1) == 1: if is_named_tuple(data[0]) and columns is None: columns = data[0]._fields diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index e5295533f37bc..1d3a1fafcf06c 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -430,7 +430,29 @@ def _get_axes(N, K, index, columns): return index, columns -def _dataclasses_to_dicts(data): +def dataclasses_to_dicts(data): + """ Converts a list of dataclass instances to a list of dictionaries + + Parameters + ---------- + data : List[Type[dataclass]] + + + Returns + -------- + list_dict : List[dict] + + Examples + -------- + >>> @dataclass + >>> class Point: + ... x: int + ... y: int + + >>> dataclasses_to_dicts([Point(1,2), Point(2,3)]) + [{"x":1,"y":2},{"x":2,"y":3}] + + """ from dataclasses import asdict return list(map(asdict, data)) From 1dcfde94f5d58adeb82efd4b3c120c9bf8a6ff17 Mon Sep 17 00:00:00 2001 From: Ariel Sosnovsky Date: Sat, 11 Jan 2020 19:19:35 -0500 Subject: [PATCH 31/34] ran isort and linters --- pandas/core/frame.py | 2 +- pandas/core/internals/construction.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 5a849914e3d30..f3ef9ae2f64d6 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -111,8 +111,8 @@ from pandas.core.indexing import check_bool_indexer, convert_to_index_sliceable from pandas.core.internals import BlockManager from pandas.core.internals.construction import ( - dataclasses_to_dicts, arrays_to_mgr, + dataclasses_to_dicts, get_names_from_index, init_dict, init_ndarray, diff --git a/pandas/core/internals/construction.py b/pandas/core/internals/construction.py index 1d3a1fafcf06c..26bfec3c85ff8 100644 --- a/pandas/core/internals/construction.py +++ b/pandas/core/internals/construction.py @@ -436,7 +436,6 @@ def dataclasses_to_dicts(data): Parameters ---------- data : List[Type[dataclass]] - Returns -------- From 2ab3aeace99f4c7a61536852447751aba6d9d9d4 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Sat, 14 Mar 2020 15:50:48 -0400 Subject: [PATCH 32/34] Update doc/source/getting_started/dsintro.rst Co-Authored-By: William Ayd --- doc/source/getting_started/dsintro.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/getting_started/dsintro.rst b/doc/source/getting_started/dsintro.rst index acdf55236fe15..dbf1c2f877ae2 100644 --- a/doc/source/getting_started/dsintro.rst +++ b/doc/source/getting_started/dsintro.rst @@ -402,7 +402,7 @@ column name provided). From a list of dataclasses ~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 1.0.0 +.. versionadded:: 1.1.0 Data Classes as introduced in `PEP557 `__, can be passed into the DataFrame constructor. From 7d53f14efa05d4ff869255799103f24f50cc4408 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sat, 14 Mar 2020 15:34:18 -0700 Subject: [PATCH 33/34] doctest fix --- pandas/core/dtypes/inference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 7667dde1401a1..83e82eb71c926 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -405,7 +405,7 @@ def is_dataclass(item): Examples -------- >>> @dataclass - >>> class Point: + ... class Point: ... x: int ... y: int From f8fa453c87863d674959bba4fccc238b7b320cff Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Sat, 14 Mar 2020 16:02:50 -0700 Subject: [PATCH 34/34] doc fixup --- pandas/core/dtypes/inference.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/dtypes/inference.py b/pandas/core/dtypes/inference.py index 83e82eb71c926..d1607b5ede6c3 100644 --- a/pandas/core/dtypes/inference.py +++ b/pandas/core/dtypes/inference.py @@ -404,6 +404,7 @@ def is_dataclass(item): Examples -------- + >>> from dataclasses import dataclass >>> @dataclass ... class Point: ... x: int