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 <[email protected]> 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/[email protected]/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 <[email protected]> wrote:
>
>> I should mention another idea that showed up on python-ideas, at
>>
>> https://mail.python.org/archives/list/[email protected]/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 -- [email protected]
> To unsubscribe send an email to
> [email protected]https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/IFE35VNDZH5YUNXY23I53QBDCUFB7GRQ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
> --
> Eric V. Smith
>
> _______________________________________________
> Python-ideas mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/4N2NOOXZBP5HF66N3OXD7CZ3HCGD3SLV/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/CZV6IHHMIUJ3EOSWJAKGEX7ILM5UUMZF/
Code of Conduct: http://python.org/psf/codeofconduct/