<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"Préformaté HTML Car";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
span.m6221197184479899755m-2120009416634021233m5794696588590256974m-8919627327275795576hoenzb
{mso-style-name:m_6221197184479899755m_-2120009416634021233m_5794696588590256974m_-8919627327275795576hoenzb;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
span.PrformatHTMLCar
{mso-style-name:"Préformaté HTML Car";
mso-style-priority:99;
mso-style-link:"Préformaté HTML";
font-family:"Courier New";
mso-fareast-language:FR;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="FR" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">George<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">For what’s worth if it can help for your need – I know that this is not part of the dataclasses PEP – inheritance now works with @autoclass
(https://smarie.github.io/python-autoclass/ ), as demonstrated below.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Note that unfortunately for mutable default field values you still have to perform self-assignment. But that’s the same problem that
you have with ‘standard’ python. <o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-bottom:12.0pt;background:white"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy"># with an unmutable default value<o:p></o:p></span></b></p>
<p class="MsoNormal" style="margin-bottom:12.0pt;background:white"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">from
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">autoclass
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">import
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">autoclass<br>
<br>
<br>
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#0000B2">@autoclass<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">class
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">Foo:<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">def
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#B200B2">__init__</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">,
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:gray">some_default: str =
<b>'unmutable_default'</b></span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">):<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">pass<br>
<br>
<br>
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#0000B2">@autoclass<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">class
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">Bar(Foo):<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">def
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#B200B2">__init__</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">,
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:gray">other_field: int</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">, some_default:
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">str
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">=
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:teal">'unmutable_default'</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">):<br>
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">super</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(Bar,
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">).</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#B200B2">__init__</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#660099">some_default</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">=some_default)<br>
<br>
<br>
a = Bar(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:blue">2</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">)<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">assert
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">a.other_field ==
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:blue">2<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">assert
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">a.some_default ==
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:teal">'unmutable_default'<br>
<br>
<o:p></o:p></span></b></p>
<p class="MsoNormal" style="margin-bottom:12.0pt;background:white"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:teal"><br>
# with a mutable default value<br>
<br>
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#0000B2">@autoclass<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">class
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">Foo:<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">def
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#B200B2">__init__</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">,
some_default: </span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">str
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">=
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">None</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">):<br>
# you have to assign, you can not delegate to @autoclass for this :(<br>
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">.some_default = some_default
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">or
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">[</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:teal">'mutable_default'</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">]<br>
<br>
<br>
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#0000B2">@autoclass<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">class
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">Bar(Foo):<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">def
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#B200B2">__init__</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">,
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:gray">other_field: int</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">, some_default:
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">str
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">=
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">None</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">):<br>
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">super</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(Bar,
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#94558D">self</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">).</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#B200B2">__init__</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:#660099">some_default</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">=some_default)<br>
<br>
<br>
a = Bar(</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:blue">2</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">)<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">assert
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">a.other_field ==
</span><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:blue">2<br>
</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:navy">assert
</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">a.some_default == [</span><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:teal">'mutable_default'</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Courier New";color:black">]<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">By the way is there any plan or idea to allow users to provide “default values factories (generators)” directly in the function signature,
when their default value is mutable ? That could be a great improvement of the python language. I could not find anything googling around… let me know if I should create a dedicated thread to discuss this.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Kind regards<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:10.0pt;font-family:"Arial",sans-serif">Sylvain
</span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">De :</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Python-ideas [mailto:python-ideas-bounces+sylvain.marie=schneider-electric.com@python.org]
<b>De la part de</b> Guido van Rossum<br>
<b>Envoyé :</b> lundi 29 janvier 2018 20:44<br>
<b>À :</b> George Leslie-Waksman <waksman@gmail.com><br>
<b>Cc :</b> Eric V. Smith <eric@trueblade.com>; python-ideas <python-ideas@python.org><br>
<b>Objet :</b> Re: [Python-ideas] Dataclasses, keyword args, and inheritance<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt">That's fair. Let me then qualify my statement with "in the initial release". The initial release has enough functionality to deal with without considering your rather esoteric use case. (And I consider it esoteric
because attrs has apparently never seen the need to solve it either.) We can reconsider for 3.8.<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Mon, Jan 29, 2018 at 11:38 AM, George Leslie-Waksman <<a href="mailto:waksman@gmail.com" target="_blank">waksman@gmail.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<div>
<p class="MsoNormal">Given I started this thread from a perspective of this is a feature that I would like because I need it, it feels a little dismissive to take attrs not having the feature to mean "there's no reason to try to implement this."<o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Mon, Jan 29, 2018 at 11:05 AM Guido van Rossum <<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal">I think that settles it -- there's no reason to try to implement this.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Mon, Jan 29, 2018 at 10:51 AM, George Leslie-Waksman <<a href="mailto:waksman@gmail.com" target="_blank">waksman@gmail.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal">attrs' seems to also not allow mandatory attributes to follow optional one:<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">In [14]: @attr.s</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> ...: class Baz:</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> ...: a = attr.ib(default=attr.Factory(list))</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> ...: b = attr.ib()</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> ...:</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">---------------------------------------------------------------------------</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">ValueError Traceback (most recent call last)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""><ipython-input-14-2c63f3f229a5> in <module>()</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">----> 1 @attr.s</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 2 class Baz:</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 3 a = attr.ib(default=attr.Factory(list))</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 4 b = attr.ib()</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 5</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">/Users/waksman/.pyenv/versions/3.6.1/envs/temp/lib/python3.6/site-packages/attr/_make.py in attrs(maybe_cls, these, repr_ns, repr, cmp, hash, init, slots, frozen, str, auto_attribs)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 700 return wrap</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 701 else:</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">--> 702 return wrap(maybe_cls)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 703</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 704</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">/Users/waksman/.pyenv/versions/3.6.1/envs/temp/lib/python3.6/site-packages/attr/_make.py in wrap(cls)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 669 raise TypeError("attrs only works with new-style classes.")</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 670</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">--> 671 builder = _ClassBuilder(cls, these, slots, frozen, auto_attribs)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 672</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 673 if repr is True:</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">/Users/waksman/.pyenv/versions/3.6.1/envs/temp/lib/python3.6/site-packages/attr/_make.py in __init__(self, cls, these, slots, frozen, auto_attribs)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 369</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 370 def __init__(self, cls, these, slots, frozen, auto_attribs):</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">--> 371 attrs, super_attrs = _transform_attrs(cls, these, auto_attribs)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 372</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 373 self._cls = cls</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">/Users/waksman/.pyenv/versions/3.6.1/envs/temp/lib/python3.6/site-packages/attr/_make.py in _transform_attrs(cls, these, auto_attribs)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 335 "No mandatory attributes allowed after an attribute with a "</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 336 "default value or factory. Attribute in question: {a!r}"</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">--> 337 .format(a=a)</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 338 )</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New""> 339 elif had_default is False and \</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-family:"Courier New"">ValueError: No mandatory attributes allowed after an attribute with a default value or factory. Attribute in question: Attribute(name='b', default=NOTHING, validator=None, repr=True, cmp=True, hash=None,
init=True, metadata=mappingproxy({}), type=None, converter=None)</span><o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Fri, Jan 26, 2018 at 1:44 PM Guido van Rossum <<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal">What does attrs' solution for this problem look like?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Fri, Jan 26, 2018 at 11:11 AM, George Leslie-Waksman <<a href="mailto:waksman@gmail.com" target="_blank">waksman@gmail.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<p class="MsoNormal">Even if we could inherit the setting, I would think that we would still want to require the code be explicit. It seems worse to implicitly require keyword only arguments for a class without giving any indication in the code.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">As it stands, the current implementation does not allow a later subclass to be declared without `keyword_only=True` so we could handle this case by adding a note to the `TypeError` message about considering the keyword_only flag.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">How do I got about putting together a proposal to get this into 3.8?<span style="color:#888888"><br>
<br>
<span class="m6221197184479899755m-2120009416634021233m5794696588590256974m-8919627327275795576hoenzb">--George</span></span><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Thu, Jan 25, 2018 at 5:12 AM Eric V. Smith <<a href="mailto:eric@trueblade.com" target="_blank">eric@trueblade.com</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt">I'm not completely opposed to this feature. But there are some cases to<br>
consider. Here's the first one that occurs to me: note that due to the<br>
way dataclasses work, it would need to be used everywhere down an<br>
inheritance hierarchy. That is, if an intermediate base class required<br>
it, all class derived from that intermediate base would need to specify<br>
it, too. That's because each class just makes decisions based on its<br>
fields and its base classes' fields, and not on any flags attached to<br>
the base class. As it's currently implemented, a class doesn't remember<br>
any of the decorator's arguments, so there's no way to look for this<br>
information, anyway.<br>
<br>
I think there are enough issues here that it's not going to make it in<br>
to 3.7. It would require getting a firm proposal together, selling the<br>
idea on python-dev, and completing the implementation before Monday. But<br>
if you want to try, I'd participate in the discussion.<br>
<br>
Taking Ivan's suggestion one step further, a way to do this currently is<br>
to pass init=False and then write another decorator that adds the<br>
kw-only __init__. So the usage would be:<br>
<br>
@dataclass<br>
class Foo:<br>
some_default: dict = field(default_factory=dict)<br>
<br>
@kw_only_init<br>
@dataclass(init=False)<br>
class Bar(Foo):<br>
other_field: int<br>
<br>
kw_only_init(cls) would look at fields(cls) and construct the __init__.<br>
It would be a hassle to re-implement dataclasses's _init_fn function,<br>
but it could be made to work (in reality, of course, you'd just copy it<br>
and hack it up to do what you want). You'd also need to use some private<br>
knowledge of InitVars if you wanted to support them (the stock<br>
fields(cls) doesn't return them).<br>
<br>
For 3.8 we can consider changing dataclasses's APIs if we want to add this.<br>
<br>
Eric.<br>
<br>
On 1/25/2018 1:38 AM, George Leslie-Waksman wrote:<br>
> It may be possible but it makes for pretty leaky abstractions and it's<br>
> unclear what that custom __init__ should look like. How am I supposed to<br>
> know what the replacement for default_factory is?<br>
><br>
> Moreover, suppose I want one base class with an optional argument and a<br>
> half dozen subclasses each with their own required argument. At that<br>
> point, I have to write the same __init__ function a half dozen times.<br>
><br>
> It feels rather burdensome for the user when an additional flag (say<br>
> "kw_only=True") and a modification to:<br>
> <a href="https://github.com/python/cpython/blob/master/Lib/dataclasses.py#L294" target="_blank">
https://github.com/python/cpython/blob/master/Lib/dataclasses.py#L294</a> that<br>
> inserted `['*']` after `[self_name]` if the flag is specified could<br>
> ameliorate this entire issue.<br>
><br>
> On Wed, Jan 24, 2018 at 3:22 PM Ivan Levkivskyi <<a href="mailto:levkivskyi@gmail.com" target="_blank">levkivskyi@gmail.com</a><br>
> <mailto:<a href="mailto:levkivskyi@gmail.com" target="_blank">levkivskyi@gmail.com</a>>> wrote:<br>
><br>
> It is possible to pass init=False to the decorator on the subclass<br>
> (and supply your own custom __init__, if necessary):<br>
><br>
> @dataclass<br>
> class Foo:<br>
> some_default: dict = field(default_factory=dict)<br>
><br>
> @dataclass(init=False) # This works<br>
> class Bar(Foo):<br>
> other_field: int<br>
><br>
> --<br>
> Ivan<br>
><br>
><br>
><br>
> On 23 January 2018 at 03:33, George Leslie-Waksman<br>
> <<a href="mailto:waksman@gmail.com" target="_blank">waksman@gmail.com</a> <mailto:<a href="mailto:waksman@gmail.com" target="_blank">waksman@gmail.com</a>>> wrote:<br>
><br>
> The proposed implementation of dataclasses prevents defining<br>
> fields with defaults before fields without defaults. This can<br>
> create limitations on logical grouping of fields and on inheritance.<br>
><br>
> Take, for example, the case:<br>
><br>
> @dataclass<br>
> class Foo:<br>
> some_default: dict = field(default_factory=dict)<br>
><br>
> @dataclass<br>
> class Bar(Foo):<br>
> other_field: int<br>
><br>
> this results in the error:<br>
><br>
> 5 @dataclass<br>
> ----> 6 class Bar(Foo):<br>
> 7 other_field: int<br>
> 8<br>
><br>
> ~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py<br>
> in dataclass(_cls, init, repr, eq, order, hash, frozen)<br>
> 751<br>
> 752 # We're called as @dataclass, with a class.<br>
> --> 753 return wrap(_cls)<br>
> 754<br>
> 755<br>
><br>
> ~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py<br>
> in wrap(cls)<br>
> 743<br>
> 744 def wrap(cls):<br>
> --> 745 return _process_class(cls, repr, eq, order,<br>
> hash, init, frozen)<br>
> 746<br>
> 747 # See if we're being called as @dataclass or<br>
> @dataclass().<br>
><br>
> ~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py<br>
> in _process_class(cls, repr, eq, order, hash, init, frozen)<br>
> 675 # in __init__. Use<br>
> "self" if possible.<br>
> 676 '__dataclass_self__' if<br>
> 'self' in fields<br>
> --> 677 else 'self',<br>
> 678 ))<br>
> 679 if repr:<br>
><br>
> ~/.pyenv/versions/3.6.2/envs/clover_pipeline/lib/python3.6/site-packages/dataclasses.py<br>
> in _init_fn(fields, frozen, has_post_init, self_name)<br>
> 422 seen_default = True<br>
> 423 elif seen_default:<br>
> --> 424 raise TypeError(f'non-default argument<br>
> {<a href="http://f.name" target="_blank">f.name</a> <<a href="http://f.name" target="_blank">http://f.name</a>>!r} '<br>
> 425 'follows default argument')<br>
> 426<br>
><br>
> TypeError: non-default argument 'other_field' follows default<br>
> argument<br>
><br>
> I understand that this is a limitation of positional arguments<br>
> because the effective __init__ signature is:<br>
><br>
> def __init__(self, some_default: dict = <something>,<br>
> other_field: int):<br>
><br>
> However, keyword only arguments allow an entirely reasonable<br>
> solution to this problem:<br>
><br>
> def __init__(self, *, some_default: dict = <something>,<br>
> other_field: int):<br>
><br>
> And have the added benefit of making the fields in the __init__<br>
> call entirely explicit.<br>
><br>
> So, I propose the addition of a keyword_only flag to the<br>
> @dataclass decorator that renders the __init__ method using<br>
> keyword only arguments:<br>
><br>
> @dataclass(keyword_only=True)<br>
> class Bar(Foo):<br>
> other_field: int<br>
><br>
> --George Leslie-Waksman<br>
><br>
> _______________________________________________<br>
> Python-ideas mailing list<br>
> <a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a> <mailto:<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a>><br>
> <a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
> Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">
http://python.org/psf/codeofconduct/</a><br>
><br>
><br>
><br>
><br>
> _______________________________________________<br>
> Python-ideas mailing list<br>
> <a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
> <a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">
https://mail.python.org/mailman/listinfo/python-ideas</a><br>
> Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">
http://python.org/psf/codeofconduct/</a><br>
><o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><o:p></o:p></p>
</blockquote>
</div>
<p class="MsoNormal"><br>
<br clear="all">
<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">-- <o:p></o:p></p>
<div>
<p class="MsoNormal">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)<o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><br>
<br clear="all">
<br>
-- <o:p></o:p></p>
<div>
<p class="MsoNormal">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)<o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><br>
<br clear="all">
<br>
-- <o:p></o:p></p>
<div>
<p class="MsoNormal">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><br>
______________________________________________________________________<br>
This email has been scanned by the Symantec Email Security.cloud service.<br>
______________________________________________________________________<o:p></o:p></p>
</div>
</body>
</html>