Skip to content

Commit

Permalink
Fix dataclasses __init__ from field with default and no-init (#5858)
Browse files Browse the repository at this point in the history
This should allow a field without a default argument afterwards
(because the field doesn't appear as an argument in `__init__`).

Also add a few notes on non-working tests from CPython.
  • Loading branch information
da-woods committed Dec 1, 2023
1 parent 6fbcbb5 commit 9b2d0a6
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Cython/Compiler/Dataclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ def generate_init_code(code, init, node, fields, kw_only):
annotation = ""
assignment = ''
if field.default is not MISSING or field.default_factory is not MISSING:
seen_default = True
if field.init.value:
seen_default = True
if field.default_factory is not MISSING:
ph_name = default_factory_placeholder
else:
Expand Down
8 changes: 6 additions & 2 deletions Tools/make_dataclass_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,17 @@
("TestKeywordArgs", "test_KW_ONLY_twice"),
("TestKeywordArgs", "test_defaults"),
# uses local variable in class definition
# Also: difficulty lining up correct repr string when converting tests
("TestCase", "test_default_factory"),
# Also: Mock unassignable to list - legitimate for Cython to raise an error
("TestCase", "test_default_factory_with_no_init"),
# Also: attributes not available on class itself, only instances
("TestCase", "test_field_default"),
("TestCase", "test_function_annotations"),
("TestDescriptors", "test_lookup_on_instance"),
# Also: Mock unassignable to int - legitimate for Cython to raise an error
("TestCase", "test_default_factory_not_called_if_value_given"),
# Also: cdef classes never don't have the attribute
("TestCase", "test_class_attrs"),
("TestCase", "test_hash_field_rules"),
("TestStringAnnotations",), # almost all the texts here use local variables
Expand All @@ -79,6 +84,7 @@
"test_class_var_frozen",
), # __annotations__ not present on cdef classes https://github.com/cython/cython/issues/4519
("TestCase", "test_dont_include_other_annotations"), # __annotations__
("TestCase", "test_class_marker"), # __annotations__
("TestDocString",), # don't think cython dataclasses currently set __doc__
# either cython.dataclasses.field or cython.dataclasses.dataclass called directly as functions
# (will probably never be supported)
Expand Down Expand Up @@ -162,8 +168,6 @@
("TestReplace", "test_initvar_with_default_value"), # needs investigating
# Maybe bugs?
# ==========
# non-default argument 'z' follows default argument in dataclass __init__ - this message looks right to me!
("TestCase", "test_class_marker"),
# cython.dataclasses.field parameter 'metadata' must be a literal value - possibly not something we can support?
("TestCase", "test_field_metadata_custom_mapping"),
(
Expand Down
11 changes: 11 additions & 0 deletions tests/run/pure_cdef_class_dataclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,14 @@ def __post_init__(self):
# and not initializing it will mess up repr
assert not hasattr(self, "neither")
self.neither = None


@cython.dataclasses.dataclass
class NonInitDefaultArgument:
"""
>>> NonInitDefaultArgument(1.0, "hello")
NonInitDefaultArgument(x=1.0, y=10, z='hello')
"""
x: float
y: int = cython.dataclasses.field(default=10, init=False)
z: str # This is allowed despite following a default argument, because the default argument isn't in init

0 comments on commit 9b2d0a6

Please sign in to comment.