Thanks Eric.

That's a really good summary of the ideas thrown around up to this point in
the other thread. I'm not overly fussed about the precise syntax we use,
though I do have a preference for using an extra level of scope to mark
fields as pos/kw only, either with context managers or with nested classes
like Matt Woznisky suggested (because I think this makes it more explicit
and and less surprising to someone seeing it for the first time). But
that's not a hill I'd even remotely consider dying on.

As long as we get:
1) positional-only and keyword-only arguments for dataclasses
2) in an inheritance-friendly way that allows subclasses to also specify
their own respective normal/positional/kw fields

I'll be happy.

As I understand it your proposal would allow for the following, right?

import dataclasses


@dataclasses.dataclass
class Parent:
    pos = dataclasses.POS_ARG
    a: int

    normal = dataclasses.NORMAL_ARG
    c: bool = False

    kw = dataclasses.KW_ARG
    e: list


@dataclasses.dataclass
class Child(Parent):
    pos = dataclasses.POS_ARG
    b: float = 3.14

    normal = dataclasses.NORMAL_ARG
    d: dict = dataclasses.field(default_factory=dict)

    kw = dataclasses.KW_ARG
    f: set = dataclasses.field(default_factory=set)


Producing an __init__ like:

def __init__(self, a: int, b: float = 3.14,
             /, c: bool = False, d: dict = None,
             *, e: list, f: set = None):

That is to say, you can specify these special values *once per class* in
the inheritance hierarchy (not just once overall) and the fields in each
category get added on at the end of that category (normal/pos/wk) compared
to the parent's __init__ signature.

If so, I'm happy with this.


PS:

I do think there will be some confusion around unexpected behaviour when
someone who has seen this many times:

@dataclasses.dataclass
class Example:
    _ = dataclasses.KW_ARG
    a: str


tries this and is confused as to why it doesn't work as expected:

@dataclasses.dataclass
class Example:
    _ = dataclasses.POS_ARG
    a: str
    _ = dataclasses.KW_ARG
    b: int

Basically, the requirement that the names these special values are assigned
to must be unique is an unfortunate side-effect of the fact that Python
doesn't bind free-floating objects to locals in some way, the way it does
with for type hints into __annotations__ which would allow the much cleaner:

@dataclasses.dataclass
class Example:
    dataclasses.POS_ARG
    a: str
    dataclasses.KW_ARG
    b: int

Come to think of it, this would make certain declarative constructs like
those found in SQLAlchemy much cleaner as well, but that's a proposal for a
different thread :p

On Sat, Mar 13, 2021 at 9:50 AM Eric V. Smith <e...@trueblade.com> wrote:

> Sorry, Matt: I meant to credit you by name, but forgot to during my final
> edit.
>
> I still don't like the verbosity and the look of 'with' statements or
> classes. Or the fact that some of the fields are indented relative to
> others.
>
> And should also mention that Ethan Furman suggested using '*' and '/' as
> the "type", in
> https://mail.python.org/archives/list/python-ideas@python.org/message/BIAVX4O6JRPQY7S3XG2IX6BSBZLAR2NS/
> , although the interaction with typing (specifically get_type_hints) might
> be an issue:
>
>     class Hmm:
>         #
>         this: int
>         that: float
>         #
>         pos: '/'
>         #
>         these: str
>         those: str
>         #
>         key: '*'
>         #
>         some: list
>
> Anyway, Matt's and Ethan's proposal are on the other thread. I'd like to
> keep this thread focused on my proposal of dataclasses.KW_ONLY and
> .POS_ONLY. Not that saying "I'd like focus this thread" has ever worked in
> the history of python-ideas.
>
> Eric
> On 3/13/2021 2:40 AM, Matt Wozniski wrote:
>
> On Fri, Mar 12, 2021, 11:55 PM Eric V. Smith <e...@trueblade.com> wrote:
>
>> I should mention another idea that showed up on python-ideas, at
>>
>> https://mail.python.org/archives/list/python-ideas@python.org/message/WBL4X46QG2HY5ZQWYVX4MXG5LK7QXBWB/
>> . It would allow you to specify the flag via code like:
>>
>> @dataclasses.dataclass
>> class Parent:
>>      with dataclasses.positional():
>>          a: int
>>      c: bool = False
>>      with dataclasses.keyword():
>>          e: list
>>
>> I'm not crazy about it, and it looks like it would require stack
>> inspection to get it to work, but I mention it here for completeness.
>
>
> I think stack inspection could be avoided if we did something like:
>
> ```
> @dataclasses.dataclass
> class Parent:
>      class pos(dataclasses.PositionalOnly):
>          a: int
>      c: bool = False
>      class kw(dataclasses.KeywordOnly):
>          e: list
> ```
>
> Like your proposal, the names for the two inner classes can be anything,
> but they must be unique. The metaclass would check if a field in the new
> class's namespace was a subclass of PositionalOnly or KeywordOnly, and if
> so recurse into its annotations to collect more fields.
>
> This still seems hacky, but it seems to read reasonably nicely, and
> behaves obviously in the presence of subclassing.
>
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to 
> python-ideas-leave@python.orghttps://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-ideas@python.org/message/IFE35VNDZH5YUNXY23I53QBDCUFB7GRQ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
> --
> Eric V. Smith
>
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/4N2NOOXZBP5HF66N3OXD7CZ3HCGD3SLV/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/CZV6IHHMIUJ3EOSWJAKGEX7ILM5UUMZF/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to