From 7a5cafa4d2f606ec6cd793578c55110e80195f82 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Sat, 6 Jan 2018 14:53:20 -0500 Subject: [PATCH 1/3] bpo-32279: Add additional params to make_dataclass(), pass through to dataclass(). --- Lib/dataclasses.py | 10 +++++++--- Lib/test/test_dataclasses.py | 7 +++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index b4786bf502e8c6a..9688a4940c102b8 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -705,7 +705,8 @@ def _astuple_inner(obj, tuple_factory): return deepcopy(obj) -def make_dataclass(cls_name, fields, *, bases=(), namespace=None): +def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, + repr=True, eq=True, order=False, hash=None, frozen=False): """Return a new dynamically created dataclass. The dataclass name will be 'cls_name'. 'fields' is an interable @@ -722,6 +723,9 @@ class C(Base): b: int = field(init=False) For the bases and namespace paremeters, see the builtin type() function. + + The parameters init, repr, eq, order, hash, and frozen are passed to + dataclass(). """ if namespace is None: @@ -737,8 +741,8 @@ class C(Base): name, tp, spec = item namespace[name] = spec cls = type(cls_name, bases, namespace) - return dataclass(cls) - + return dataclass(cls, init=init, repr=repr, eq=eq, order=order, + hash=hash, frozen=frozen) def replace(obj, **changes): """Return a new object replacing specified fields with new values. diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index fca384d8c3c06c7..2be464e241f8f6d 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2033,6 +2033,13 @@ def test_helper_make_dataclass_class_var(self): self.assertEqual(C.y, 10) self.assertEqual(C.z, 20) + def test_helper_make_dataclass_other_params(self): + C = make_dataclass('C', + [('x', int), + ('y', ClassVar[int], 10), + ('z', ClassVar[int], field(default=20)), + ], + init=False) class TestDocString(unittest.TestCase): def assertDocStrEqual(self, a, b): From 37a8453aeae87a7166718532b7809599e1a57f21 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Sat, 6 Jan 2018 16:46:27 -0500 Subject: [PATCH 2/3] bpo-32279: More tests. --- Lib/test/test_dataclasses.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index e7c8c0d87dd9582..69819ea4507848b 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2040,6 +2040,15 @@ def test_helper_make_dataclass_other_params(self): ('z', ClassVar[int], field(default=20)), ], init=False) + # Make sure we have a repr, but no init. + self.assertNotIn('__init__', vars(C)) + self.assertIn('__repr__', vars(C)) + + # Make sure random other params don't work. + with self.assertRaisesRegex(TypeError, 'unexpected keyword argument'): + C = make_dataclass('C', + [], + xxinit=False) def test_helper_make_dataclass_no_types(self): C = make_dataclass('Point', ['x', 'y', 'z']) From 6826ff1365ac4028fce4154fb17143d94be43728 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Sat, 6 Jan 2018 16:50:18 -0500 Subject: [PATCH 3/3] Add blurb. --- .../next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst diff --git a/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst b/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst new file mode 100644 index 000000000000000..b7ef8c80f5a4ef3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst @@ -0,0 +1,2 @@ +Add params to dataclasses.make_dataclasses(): init, repr, eq, order, hash, +and frozen. Pass them through to dataclass().