Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Improve UX for mocking dataclasses that are problematic to instantiate #124176

Open
Assignees
sobolevn
@ncoghlan

Description

@ncoghlan

Feature or enhancement

Proposal:

Passinginstance=True tocreate_autospec misses fields without default values, even when the given spec is adataclass object:

>>>fromdataclassesimportdataclass>>>@dataclass...classExample:...a:int...b:int=0...defsum_fields(self):...returnself.a+self.b...>>>fromunittest.mockimportcreate_autospec>>>mock_instance=create_autospec(Example(1))>>>mock_instance_from_class=create_autospec(Example,instance=True)>>>set(dir(mock_instance))-set(dir(mock_instance_from_class)){'a'}

This is despite dataclass definitions making their field information readily available for introspection on the class object (without requiring instantiation):

>>>fromdataclassesimportfields>>> [(field.name,field.type)forfieldinfields(Example)][('a',<class'int'>), ('b',<class'int'>)]

A similar problem occurs if the dataclass uses__post_init__ to set attributes that are not otherwise set:

>>>fromdataclassesimportdataclass,field>>>@dataclass...classPostInitExample:...a:int=field(init=False)...b:int=field(init=False)...def__post_init__(self):...self.a=self.b=1...>>>mock_post_init_class=create_autospec(Example)>>>mock_post_init_class=create_autospec(PostInitExample)>>>mock_post_init_instance=create_autospec(PostInitExample())>>>set(dir(mock_post_init_instance))-set(dir(mock_post_init_class())){'b','a'}

While for most dataclasses it is straightforward to instantiate a specific instance and derive the mock autospec from that, this may not be desirable (or even feasible) if the dataclass requires references to real external resources to create a real instance.

There are various potential workarounds available for this functional gap, but they're all relatively clumsy, and come with their own problems (like not being able to usespec_set=True if the missing fields are added manually, or not handling defined methods properly if setting an explicit list of fields instead of usingautospec, or still not adding the fields only defined in__post_init__ if instantiating a class mock).

By contrast, ifcreate_autospec were to be made explicitly aware of data classes, it could do a pass overdataclasses.fields(spec) and use the type information to fill in any missing fields that don't have class level default values set.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

Previously filed here, but closed on the basis ofcreate_autospec covering the use case:#80761

This is only true if the dataclass can be readily instantiated, hence this feature request.

There is also some previous discussion (and assorted attempted workarounds with various flaws) on this Stack Overflow question:https://stackoverflow.com/questions/51640505/how-to-use-spec-when-mocking-data-classes-in-python

Linked PRs

Metadata

Metadata

Assignees

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp