This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Argument Clinic NULL default falsely implies None acceptability
Type: behavior Stage:
Components: Build Versions: Python 3.4
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: larry, rmsr, vajrasky
Priority: normal Keywords:

Created on 2014-01-13 02:53 by rmsr, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (10)
msg207998 - (view) Author: Ryan Smith-Roberts (rmsr) * Date: 2014-01-13 02:53
When one specifies a default of NULL, the generated signature doc indicates a default of None. However, if the user actually supplies None, perhaps as a placeholder in a positional-only call, C code which only checks for NULL will fail inappropriately.

The solution may be to convert a None object to a null pointer in the wrapper.
msg207999 - (view) Author: Vajrasky Kok (vajrasky) * Date: 2014-01-13 03:20
Yes, this issue bothers me. Currently _sha1.sha1 constructor will use NULL (not None) value if used without parameters: _sha1.sha1()

_sha1.sha1(None) will throw error while _sha1.sha1() won't.

So for NULL (not None) default value, the generated signature _sha1.sha1(string=None) is kinda misleading. I am not sure what is the correct signature should be without changing behaviour.
msg208183 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-01-15 19:58
One mandate I've given myself for this project:

  When a function provides a signature, it must be 100% accurate.

A specific corollary of this:

  If you call a function, and for every optional parameter you
  explicitly pass it in with its default value from the signature,
  the result will be identical with calling the function and not
  providing that optional parameter.

So we can't lie here.

You're right that this is a general problem.  It's possible for a C function to accept a parameter that is
 * positional-or-keyword,
 * has a default value, and
 * the default value is not publishable as a Python value.
This is impossible in Python.  But Clinic only allows you to represent Python-compatible signatures.

In this *specific* case we can dodge the bullet:

    /*[clinic input]
    SHA1.SHA1
      string: object(c_default='NULL') = b''
msg208232 - (view) Author: Ryan Smith-Roberts (rmsr) * Date: 2014-01-16 04:01
I've realized this is basically insoluble without PEP 457, because any other solution involves changing behavior (None being silently accepted where it would previously raise an exception). If that's OK, then per-function defensive programming is probably the best idea (just emailed python-dev about this).

I didn't like the look of the ways I came up with for adding it to AC (inserting arbitrary crazycode between ParseTuple and _impl), so please close this 'wont fix' unless you really do want to do that.
msg208234 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-01-16 04:36
Why wouldn't my suggestion work?  _sha1.sha1(b'').hexdigest() == _sha1.sha1().hexdigest().
msg208235 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-01-16 04:46
Also: how would PEP 457 help?  PEP 457 only addresses extensions to support positional-only parameters, and the parameter in question (the "string" parameter to _sha1.sha1) is positional-or-keyword.
msg208236 - (view) Author: Ryan Smith-Roberts (rmsr) * Date: 2014-01-16 05:19
sha1 is Vajrasky's module. I have a much more complicated example (and Vajrasky and I just both posted on python-dev separately about this issue):

sockobj.sendmsg(buffers[, ancdata[, flags[, address]]])
->
sockobj.sendmsg(buffers, ancdata=None, flags=0, address=None)

Here ancdata wants an iterator and address a tuple, and the existing function expects NULL when these are absent. This is what we've been indirectly discussing via email as well.

Aaand I just realized that I should set py_default to []?
msg208237 - (view) Author: Ryan Smith-Roberts (rmsr) * Date: 2014-01-16 05:36
No, that still leaves address broken since neither None nor an empty tuple are acceptable.
msg208238 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2014-01-16 05:39
Definitely not [].  At the very least ().

I'd appreciate it if you'd stop abruptly changing the subject.  I thought we were talking about SHA1_new, but now you're talking about "address" and "sockobj.sendmsg".  If you have specific cases you'd like to discuss, post them and maybe we can find a workaround.  If you want to discuss the general problem, I guess now we want to have that discussion on python-dev.
msg208265 - (view) Author: Ryan Smith-Roberts (rmsr) * Date: 2014-01-16 09:26
After all our discussions I'm closing this with resolution "don't do that then".
History
Date User Action Args
2022-04-11 14:57:56adminsetgithub: 64431
2014-01-16 09:26:17rmsrsetstatus: open -> closed
resolution: wont fix
messages: + msg208265
2014-01-16 05:39:34larrysetmessages: + msg208238
2014-01-16 05:36:38rmsrsetmessages: + msg208237
2014-01-16 05:19:07rmsrsetmessages: + msg208236
2014-01-16 04:46:32larrysetmessages: + msg208235
2014-01-16 04:36:23larrysetmessages: + msg208234
2014-01-16 04:01:36rmsrsetmessages: + msg208232
2014-01-15 19:58:37larrysetmessages: + msg208183
2014-01-13 03:20:33vajraskysetnosy: + vajrasky
messages: + msg207999
2014-01-13 02:53:18rmsrcreate