Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Lib/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,16 @@ def __repr__(self):

class _InitVarMeta(type):
def __getitem__(self, params):
return self
return InitVar(params)

class InitVar(metaclass=_InitVarMeta):
pass
__slots__ = ('type', )

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably have a nicer __repr__ here.

Currently you get:

>>> from dataclasses import InitVar
>>> InitVar[int]
<dataclasses.InitVar object at 0x00A041C0>

I'd suggest something like:

    def __repr__(self):
        return f'dataclasses.InitVar[{self.type}]'

for starters, although typing.ClassVar does something more sophisticated in place of {self.type}. Maybe someday when we import typing from dataclasses we can switch to using their helper function. It's probably worth adding a comment to that effect, too.

@hackaugusto hackaugusto Sep 15, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using f'dataclasses.InitVar[{self.type}]' would look like:

>>> from dataclasses import InitVar
>>> InitVar[int]
dataclasses.InitVar[<class 'int'>]

So I added f'dataclasses.InitVar[{self.type.__name__}]' instead. Should I write a test for this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's what gives you the equivalent of:

>>> import typing
>>> typing.ClassVar[int]
typing.ClassVar[int]

Then I'm all for it.

Yes, we'll need tests for this. Nothing complex, InitVar[int] should be good enough.

@hackaugusto hackaugusto Oct 7, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, I added a really simple test:

self.assertEqual(InitVar[int].type, int)

Would you like tests using __repr__ and @dataclass?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for taking forever to get back to you on this.

Could you test the repr of an InitVar? Something like (untested) repr(InitVar[int]) == 'dataclasses.InitVar[int]'?

I promise I'll commit this as soon as you add this change.


def __init__(self, type):
self.type = type

def __repr__(self):
return f'dataclasses.InitVar[{self.type.__name__}]'


# Instances of Field are only ever created from within this module,
Expand Down Expand Up @@ -586,7 +592,8 @@ def _is_classvar(a_type, typing):
def _is_initvar(a_type, dataclasses):
# The module we're checking against is the module we're
# currently in (dataclasses.py).
return a_type is dataclasses.InitVar
return (a_type is dataclasses.InitVar
or type(a_type) is dataclasses.InitVar)


def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,12 @@ def __post_init__(self, init_param):
c = C(init_param=10)
self.assertEqual(c.x, 20)

def test_init_var_preserve_type(self):
self.assertEqual(InitVar[int].type, int)

# Make sure the repr is correct.
self.assertEqual(repr(InitVar[int]), 'dataclasses.InitVar[int]')

def test_init_var_inheritance(self):
# Note that this deliberately tests that a dataclass need not
# have a __post_init__ function if it has an InitVar field.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dataclasses.InitVar: Exposes the type used to create the init var.