<div dir="ltr">OK, I get it, I think.<div><br></div><div>I presume it is really the object identity which matters, not the syntax, so:</div><div><br></div><div>y = NoDefault</div><div>f(x=y)</div><div><br></div><div>would be equally an error.</div><div><br></div><div>Would this also apply if we provide or capture the keyword arguments using ** ?</div><div><br></div><div>I.e.</div><div>f(**{"x": NoDict})</div><div><br></div><div>(lambda **kw: kw)(x=NoDict)</div><div><br></div><div>In that case I see a problem with this idiom:</div><div><br></div><div>newdict = dict(**olddict)</div><div><br></div><div>This would now start throwing errors in case any of the values of olddict was NoDefault.</div><div><br></div><div>Stephan</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2017-03-02 13:08 GMT+01:00 M.-A. Lemburg <span dir="ltr"><<a href="mailto:mal@egenix.com" target="_blank">mal@egenix.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On <a href="tel:02.03.2017%2012" value="+31203201712">02.03.2017 12</a>:31, Stephan Houben wrote:<br>
> I am not sure if I fully understand the proposal then.<br>
><br>
> NoDefault would be special syntax so that this would be disallowed:<br>
><br>
> f(NoDefault)<br>
><br>
> but this would be allowed:<br>
> def f(x=NoDefault):<br>
> ...<br>
><br>
> and also this:<br>
><br>
> x is NoDefault<br>
><br>
> So this would seem to require an exhaustive list of syntactic contexts<br>
> in which NoDefault is allowed. I mean, can I do:<br>
><br>
> x = NoDefault<br>
><br>
> ?<br>
><br>
> I observe that I can always get to the underlying NoDefault object in this<br>
> way:<br>
><br>
> (lambda x=NoDefault:x)()<br>
><br>
> So what happens if I do:<br>
><br>
> f((lambda x=NoDefault:x)())<br>
><br>
> ?<br>
<br>
</span>Sorry for the confusion. NoDefault would be usable just like<br>
any other singleton.<br>
<br>
There would only be one case where it would cause an exception,<br>
namely when you declare a parameter as having NoDefault as value.<br>
This would trigger special logic in the argument parsing code to<br>
disallow using that parameter as keyword parameter.<br>
<br>
Example:<br>
<br>
def f(x=NoDefault):<br>
# x is an optional positional parameter<br>
if x is NoDefault:<br>
# x was not passed in as parameter<br>
...<br>
else:<br>
# x was provided as parameter<br>
...<br>
<br>
These would all work fine:<br>
<br>
f()<br>
f(1)<br>
f(None)<br>
<br>
This would trigger an exception in the argument parsing code:<br>
<br>
f(x=NoDefault)<br>
<br>
e.g. TypeError('x is a positional only parameter')<br>
<br>
This would not trigger an exception:<br>
<br>
f(NoDefault)<br>
<br>
since x is not being used as keyword parameter and the<br>
function f may want to pass the optional positional parameter<br>
down to other functions with optional positional paramters<br>
as well.<br>
<br>
Is this clearer now ?<br>
<br>
Note: The name of the singleton could be something else<br>
as well, e.g. NoKeywordParameter :-)<br>
<div class="HOEnZb"><div class="h5"><br>
> Stephan<br>
><br>
><br>
> 2017-03-02 12:15 GMT+01:00 M.-A. Lemburg <<a href="mailto:mal@egenix.com">mal@egenix.com</a>>:<br>
><br>
>> On <a href="tel:02.03.2017%2011" value="+31203201711">02.03.2017 11</a>:22, Stephan Houben wrote:<br>
>>> In cases like this I would recommend creating the sentinel yourself:<br>
>>><br>
>>> NoDefault = object()<br>
>>><br>
>>> def get(store, key, default=NoDefault):<br>
>>> if default is NoDefault:<br>
>>> # do something<br>
>>><br>
>>> You can arrange to not export NoDefault so that the client code cannot<br>
>> even<br>
>>> access<br>
>>> the sentinel value.<br>
>><br>
>> Yes, I know... I've been using the mxTools NotGiven since 1998.<br>
>><br>
>>> This is strictly preferable over having yet another global<br>
>>> value meaning "no value", since that just moves the goal posts:<br>
>>> clients will complain they cannot pass in a default=NoDefault and get<br>
>> back<br>
>>> NoDefault.<br>
>><br>
>> Not really. NoDefault would mean: no value provided, not that<br>
>> you don't want a value. As a result, passing NoDefault would<br>
>> not be allowed, since then you'd be providing a value :-)<br>
>><br>
>>> Stephan<br>
>>><br>
>>><br>
>>> 2017-03-02 11:04 GMT+01:00 M.-A. Lemburg <<a href="mailto:mal@egenix.com">mal@egenix.com</a>>:<br>
>>><br>
>>>> On <a href="tel:02.03.2017%2010" value="+31203201710">02.03.2017 10</a>:06, Serhiy Storchaka wrote:<br>
>>>>> On 02.03.17 10:36, M.-A. Lemburg wrote:<br>
>>>>>> Why a new syntax ? Can't we just have a pre-defined sentinel<br>
>>>>>> singleton NoDefault and use that throughout the code (and also<br>
>>>>>> special case it in argument parsing/handling)?<br>
>>>>>><br>
>>>>>> def get(store, key, default=NoDefault):<br>
>>>>>> if store.exists(key):<br>
>>>>>> return store.retrieve(key)<br>
>>>>>> ...<br>
>>>>><br>
>>>>> This means adding a new syntax. NoDefault should be a keyword (we can<br>
>>>>> reuse existing keyword couldn't be used in expression), and it should<br>
>> be<br>
>>>>> accepted only in the specific context of declaring function parameter.<br>
>>>><br>
>>>> This is not new syntax, nor is it a keyword. It's only a<br>
>>>> new singleton and it is well usable outside of function<br>
>>>> declarations as well, e.g. for class attributes which are<br>
>>>> not yet initialized (and which can accept None as value).<br>
>>>><br>
>>>> The only special casing would be in function call<br>
>>>> parameter parsing to signal errors when the parameter<br>
>>>> is used as keyword parameter.<br>
>>>><br>
>>>> --<br>
>>>> Marc-Andre Lemburg<br>
>>>> eGenix.com<br>
>>>><br>
>>>> Professional Python Services directly from the Experts (#1, Mar 02 2017)<br>
>>>>>>> Python Projects, Coaching and Consulting ... <a href="http://www.egenix.com/" rel="noreferrer" target="_blank">http://www.egenix.com/</a><br>
>>>>>>> Python Database Interfaces ... <a href="http://products.egenix.com/" rel="noreferrer" target="_blank">http://products.egenix.com/</a><br>
>>>>>>> Plone/Zope Database Interfaces ... <a href="http://zope.egenix.com/" rel="noreferrer" target="_blank">http://zope.egenix.com/</a><br>
>>>> ______________________________<wbr>______________________________<br>
>> ____________<br>
>>>><br>
>>>> ::: We implement business ideas - efficiently in both time and costs :::<br>
>>>><br>
>>>> eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48<br>
>>>> D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg<br>
>>>> Registered at Amtsgericht Duesseldorf: HRB 46611<br>
>>>> <a href="http://www.egenix.com/company/contact/" rel="noreferrer" target="_blank">http://www.egenix.com/company/<wbr>contact/</a><br>
>>>> <a href="http://www.malemburg.com/" rel="noreferrer" target="_blank">http://www.malemburg.com/</a><br>
>>>><br>
>>>> ______________________________<wbr>_________________<br>
>>>> Python-ideas mailing list<br>
>>>> <a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
>>>> <a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
>>>> Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/<wbr>codeofconduct/</a><br>
>>>><br>
>>><br>
>>><br>
>>><br>
>>> ______________________________<wbr>_________________<br>
>>> Python-ideas mailing list<br>
>>> <a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
>>> <a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/python-ideas</a><br>
>>> Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/<wbr>codeofconduct/</a><br>
>>><br>
>><br>
>> --<br>
>> Marc-Andre Lemburg<br>
>> eGenix.com<br>
>><br>
>> Professional Python Services directly from the Experts (#1, Mar 02 2017)<br>
>>>>> Python Projects, Coaching and Consulting ... <a href="http://www.egenix.com/" rel="noreferrer" target="_blank">http://www.egenix.com/</a><br>
>>>>> Python Database Interfaces ... <a href="http://products.egenix.com/" rel="noreferrer" target="_blank">http://products.egenix.com/</a><br>
>>>>> Plone/Zope Database Interfaces ... <a href="http://zope.egenix.com/" rel="noreferrer" target="_blank">http://zope.egenix.com/</a><br>
>> ______________________________<wbr>______________________________<wbr>____________<br>
>><br>
>> ::: We implement business ideas - efficiently in both time and costs :::<br>
>><br>
>> eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48<br>
>> D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg<br>
>> Registered at Amtsgericht Duesseldorf: HRB 46611<br>
>> <a href="http://www.egenix.com/company/contact/" rel="noreferrer" target="_blank">http://www.egenix.com/company/<wbr>contact/</a><br>
>> <a href="http://www.malemburg.com/" rel="noreferrer" target="_blank">http://www.malemburg.com/</a><br>
>><br>
>><br>
><br>
<br>
--<br>
Marc-Andre Lemburg<br>
eGenix.com<br>
<br>
Professional Python Services directly from the Experts (#1, Mar 02 2017)<br>
>>> Python Projects, Coaching and Consulting ... <a href="http://www.egenix.com/" rel="noreferrer" target="_blank">http://www.egenix.com/</a><br>
>>> Python Database Interfaces ... <a href="http://products.egenix.com/" rel="noreferrer" target="_blank">http://products.egenix.com/</a><br>
>>> Plone/Zope Database Interfaces ... <a href="http://zope.egenix.com/" rel="noreferrer" target="_blank">http://zope.egenix.com/</a><br>
______________________________<wbr>______________________________<wbr>____________<br>
<br>
::: We implement business ideas - efficiently in both time and costs :::<br>
<br>
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48<br>
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg<br>
Registered at Amtsgericht Duesseldorf: HRB 46611<br>
<a href="http://www.egenix.com/company/contact/" rel="noreferrer" target="_blank">http://www.egenix.com/company/<wbr>contact/</a><br>
<a href="http://www.malemburg.com/" rel="noreferrer" target="_blank">http://www.malemburg.com/</a><br>
<br>
</div></div></blockquote></div><br></div>