msg169547 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-08-31 15:57 |
From docs@python.org:
"""
In a number of places we find documentation with optional leading arguments where the meta-notation (square brackets) are in the wrong place. For example, for range, the standard doc heading says
range([start], stop [, step]) # The comma after start should be inside the square bracket, not outside.
The same error occurs with docs for print, and for slice, for random.randrange and for random.seed, etc, etc. This seems a consistent bug whenever a function or method takes an optional first argument, and it looks like it might have been put there by some tool that generates the docs.
I use Python 3 - perhaps there was once a time when one had to supply the comma if one omitted the first argument? In Python 3 it gives errors if one follows the documentation carefully and uses the comma.
""""
(or see http://mail.python.org/pipermail/docs/2012-August/010051.html )
|
msg169549 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-08-31 16:11 |
Do we know that this is easy? It might be a Sphinx issue, in which case it might not be as trivial as fixing typos.
I ask because the reST file looks correct (for range() for example):
.. function:: range([start,] stop[, step])
|
msg169550 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-08-31 16:15 |
I thought that was just a matter of finding the wrong commas and fixing them, but if they are correct in the source, then the situation might be a bit more complicated.
Does this happen only with "unusual" signatures like range([start], stop [, step])?
FWIW this could be replaced with:
range(stop)
range(start, stop [, step])
|
msg169553 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-08-31 16:21 |
This is what my search for ",] " gave me (though the OP's print and random.seed do not show up in this list):
library/curses.rst
380:.. function:: newwin([nlines, ncols,] begin_y, begin_x)
659:.. method:: window.addch([y, x,] ch[, attr])
673:.. method:: window.addnstr([y, x,] str, n[, attr])
679:.. method:: window.addstr([y, x,] str[, attr])
766:.. method:: window.chgat([y, x, ] [num,] attr)
815:.. method:: window.derwin([nlines, ncols,] begin_y, begin_x)
909:.. method:: window.hline([y, x,] ch, n)
943:.. method:: window.insch([y, x,] ch[, attr])
964:.. method:: window.insnstr([y, x,] str, n [, attr])
1156:.. method:: window.subpad([nlines, ncols,] begin_y, begin_x)
1162:.. method:: window.subwin([nlines, ncols,] begin_y, begin_x)
1219:.. method:: window.vline([y, x,] ch, n)
library/functions.rst
1064:.. function:: range([start,] stop[, step])
1129:.. function:: slice([start,] stop[, step])
library/itertools.rst
55::func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G``
404:.. function:: islice(iterable, [start,] stop [, step])
library/random.rst
96:.. function:: randrange([start,] stop[, step])
library/syslog.rst
20:.. function:: syslog([priority,] message)
library/tkinter.tix.rst
507:.. method:: tixCommand.tix_configure([cnf,] **kw)
|
msg169555 - (view) |
Author: Andrew Svetlov (asvetlov) * |
Date: 2012-08-31 16:32 |
Yes, it looks like Sphinx problem.
About having tho signatures for single function/method.
Does Sphinx support it for *.. function::*?
Pointing to anchor for first signature with adding second one somewhere in paragraph text doesn't look good.
|
msg169557 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-08-31 16:45 |
> Does Sphinx support it for *.. function::*?
I'm pretty sure it does for methods, so I don't see why it shouldn't work for functions.
|
msg169559 - (view) |
Author: Andrew Svetlov (asvetlov) * |
Date: 2012-08-31 16:48 |
No, methods for *curses* are also corrupted.
|
msg169561 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-08-31 16:49 |
> This is what my search for ",] " gave me
It would be fine with me to use a double signature for these.
Georg, do you have any opinion?
(The double signature might be easier to understand, but the original issue should probably be fixed in Sphinx, even if we decide to stop using this kind of signature.)
|
msg169562 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-08-31 16:51 |
> No, methods for *curses* are also corrupted.
I meant the double signature support.
|
msg169563 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-08-31 16:57 |
> It would be fine with me to use a double signature for these.
Just an FYI that more than two signatures would be needed for cases like this:
766:.. method:: window.chgat([y, x, ] [num,] attr)
|
msg169565 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-08-31 16:59 |
> 766:.. method:: window.chgat([y, x, ] [num,] attr)
What's this even supposed to mean?
See also #14783.
|
msg169566 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-08-31 17:04 |
> What's this even supposed to mean?
I started wondering the same thing after I posted. :)
I guess my point/question is: are there any cases where more than two signatures would be needed to account for all of the possibilities?
|
msg169568 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-08-31 17:11 |
I think/hope that all the APIs we have in the stdlib are sane enough to have no more than 2-3 signatures (I'm not counting optional args (at the end) here). If that's not the case we should still be able to add as many signature as we need (I don't know if Sphinx has some limit about it though).
|
msg169647 - (view) |
Author: Georg Brandl (georg.brandl) * |
Date: 2012-09-01 17:07 |
+1 for multiple signatures.
|
msg169649 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-01 17:30 |
> (The double signature might be easier to understand, but the original issue should probably be fixed in Sphinx, even if we decide to stop using this kind of signature.)
I filed an issue for this in the Sphinx tracker here:
https://bitbucket.org/birkenfeld/sphinx/issue/1001/comma-after-leading-optional-argument-in
|
msg169652 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-01 17:37 |
I will prepare a patch (multiple signatures, for the Python fix).
|
msg169696 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-02 13:42 |
Something to be aware of that may or may not affect the patch I'm preparing:
One reason that Sphinx seems able to render some of the more complicated function signatures is that it has logic to bail and print the parameter list verbatim from the reST file whenever its record-keeping logic becomes internally inconsistent:
except IndexError:
# if there are too few or too many elements on the stack, just give up
# and treat the whole argument list as one argument, discarding the
# already partially populated paramlist node
https://bitbucket.org/birkenfeld/sphinx/src/1f3a2749df39/sphinx/domains/python.py#cl-74
This seems to come into play, for example, when rendering--
sorted(iterable[, key][, reverse])
http://docs.python.org/dev/library/functions.html#sorted
|
msg169697 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-02 13:47 |
Here are a couple functions that may need a fix different from multiple signatures:
print([object, ...], *, sep=' ', end='\n', file=sys.stdout, flush=False)
http://docs.python.org/dev/library/functions.html#print
class argparse.ArgumentParser([description][, epilog][, prog][, usage][, add_help][, argument_default][, parents][, prefix_chars][, conflict_handler][, formatter_class])
http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser
|
msg169709 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-02 16:36 |
FWIW, I submitted a patch for the Sphinx issue I created:
https://bitbucket.org/birkenfeld/sphinx/issue/1001
Ironically, that patch was probably easier than this patch will be.
|
msg169726 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-02 22:33 |
Attaching a proposed patch for the default branch. Also, here are several comments and questions.
> I think/hope that all the APIs we have in the stdlib are sane enough to have no more than 2-3 signatures
I found this one in the curses module with four:
window.chgat(attr)
window.chgat(num, attr)
window.chgat(y, x, attr)
window.chgat(y, x, num, attr)
Do we like how these look? Is the bare star notation too obscure?
inspect.Signature.replace(*[, parameters][, return_annotation])
inspect.Parameter.replace(*[, name][, kind][, default][, annotation])
I was curious what the preferred way to display the following is, since I don't think any comma/bracket placement will work:
ArgumentParser([description][, epilog][, prog][, usage][, add_help][, argument_default][, parents][, prefix_chars][, conflict_handler][, formatter_class])
(unless perhaps we use the construction "ArgumentParser(*[, description][, epilog]....")
I'm not sure how we want to handle this one using multiple signatures:
multiprocessing.Process([group[, target[, name[, args[, kwargs]]]]], *, daemon=None)
I put my preferred rendering in the patch, but Sphinx re-renders it in its own way.
I also noticed these more unusual signatures:
urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=True)
http.client.HTTPSConnection(host, port=None, key_file=None, cert_file=None[, strict[, timeout[, source_address]]], *, context=None, check_hostname=None)
By the way, is the * really necessary in these examples?
|
msg169828 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-09-04 13:10 |
> Do we like how these look? Is the bare star notation too obscure?
>
> inspect.Signature.replace(*[, parameters][, return_annotation])
> inspect.Parameter.replace(*[, name][, kind][, default][, annotation])
Note that if possible, it's better to avoid using the [] and put the default values. However, in these cases the default value seems to be a _void placeholder.
The star notation is OK, since it's valid Python.
> I was curious what the preferred way to display the following is,
> since I don't think any comma/bracket placement will work:
>
> ArgumentParser([description][, epilog][, prog][, usage][, add_help][, argument_default][, parents][, prefix_chars][, conflict_handler][, formatter_class])
If the default values are known you could use them, otherwise this signature looks OK to me.
> (unless perhaps we use the construction "ArgumentParser(*[,
> description][, epilog]....")
This is OK too, as long as all the arguments (including 'description') are keyword-only.
> I'm not sure how we want to handle this one using multiple signatures:
>
> multiprocessing.Process([group[, target[, name[, args[, kwargs]]]]], *, daemon=None)
This is OK too.
> I also noticed these more unusual signatures:
>
> urllib.request.urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=True)
> http.client.HTTPSConnection(host, port=None, key_file=None, cert_file=None[, strict[, timeout[, source_address]]], *, context=None, check_hostname=None)
Here the args between [] probably have a placeholder default, or are obtained from somewhere else (e.g. from socket.getdefaulttimeout()). These signature, albeit a bit weird, are understandable IMHO, so, unless you find a better way to write them, I would leave them as they are.
> By the way, is the * really necessary in these examples?
If the args on the right of the * are keyword-only and the one on the left aren't, then yes.
|
msg169832 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-04 13:35 |
Thanks for responding to all of those questions, Ezio. I will update the patch based on your responses. (Likely most of it will remain the same.)
> Note that if possible, it's better to avoid using the [] and put the default
> values. However, in these cases the default value seems to be a _void
> placeholder.
Yes, the defaults are "private" in those cases (and in I think pretty much all cases in the patch in which []'s rather than a default value are used to display keyword arguments).
> > I was curious what the preferred way to display the following is,
> > since I don't think any comma/bracket placement will work:
> >
> > ArgumentParser([description][, epilog][, prog][, usage][, add_help][, argument_default][, parents][, prefix_chars][, conflict_handler][, formatter_class])
> If the default values are known you could use them, otherwise this signature looks OK to me.
The comma not being inside the first bracket is what I was concerned about here (which was the issue raised in the original comment). Using an initial * which you are okay with will address this. (And yes, they are all keyword arguments. In fact, the order of the arguments in the docs does not even match the order in the code.)
> > By the way, is the * really necessary in these examples?
> If the args on the right of the * are keyword-only and the one on the left aren't, then yes.
Okay. I think what threw me is that I don't think we're consistently using the * throughout our docs to denote the beginning of keyword-only arguments. The ArgumentParser constructor above is just one example. So I wasn't sure if this notation was preferred or discouraged.
|
msg169836 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-09-04 16:26 |
> So I wasn't sure if this notation was preferred or discouraged.
We are moving toward using the same signatures that we have in the Python code, but that doesn't always work (e.g. when the meaning of values changes depending on the number of args, when there's some trick with *args/**kwargs involved, when there are default placeholders, etc.).
The single * is not so common (yet), and it might be difficult to understand for new users, that's why I said it's OK to leave it out in cases where all the args are keyword args and the [] are used.
|
msg169844 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-04 23:17 |
Attaching an updated patch after doing another pass at the code and in light of Ezio's comments.
Let me know if and when you'd like me to prepare separate patches for 2.7 and 3.2.
|
msg169851 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-05 00:46 |
> We are moving toward using the same signatures that we have in the Python code.... The single * is not so common (yet),
I created issue 15865 to add the single * to the documentation where appropriate.
|
msg170471 - (view) |
Author: Roundup Robot (python-dev) |
Date: 2012-09-14 04:00 |
New changeset b01eb870f84f by Ezio Melotti in branch '3.2':
#15831: document multiple signatures on different lines. Patch by Chris Jerdonek.
http://hg.python.org/cpython/rev/b01eb870f84f
New changeset 0ed61ee823d8 by Ezio Melotti in branch 'default':
#15831: merge with 3.2
http://hg.python.org/cpython/rev/0ed61ee823d8
New changeset 2291aff20a05 by Ezio Melotti in branch '2.7':
#15831: document multiple signatures on different lines. Patch by Chris Jerdonek.
http://hg.python.org/cpython/rev/2291aff20a05
|
msg170472 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-09-14 04:03 |
Fixed, thanks for the patch!
|
msg170493 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-14 17:18 |
Thanks, Ezio!
By the way, I didn't do a thorough check, but I noticed this difference in the 2.7 application of the patch. The *key* argument for max() needs to be marked keyword-only. This difference doesn't exist for the min() function. Or are we not using the "bare *" notation in the 2.7 docs? If not, the min() docs need to be changed instead (and possibly in several other places).
Default branch:
-.. function:: max(iterable[, args...], *[, key])
+.. function:: max(iterable, *[, key])
+ max(arg1, arg2, *args[, key])
2.7 branch:
-.. function:: max(iterable[, args...][key])
+.. function:: max(iterable[, key])
+ max(arg1, arg2, *args[, key])
|
msg170495 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-14 17:33 |
Someone pointed out that keyword-only arguments were introduced only in 3.0, but I'm not sure whether that means we can't use them as a notational device in the 2.7 docs.
|
msg170499 - (view) |
Author: Chris Jerdonek (chris.jerdonek) * |
Date: 2012-09-15 01:10 |
Since the bare * notation wasn't added until 3.0, my guess is that we want to remove the * below (from the 2.7 application of the patch) rather than adding it back in the max() function I pasted above:
-.. function:: min(iterable[, args...][key])
+.. function:: min(iterable, *[, key])
+ min(arg1, arg2, *args[, key])
|
msg170500 - (view) |
Author: Roundup Robot (python-dev) |
Date: 2012-09-15 01:46 |
New changeset 881acdf9133f by Ezio Melotti in branch '2.7':
#15831: avoid using 3.x syntax for keyword-only args.
http://hg.python.org/cpython/rev/881acdf9133f
|
msg170501 - (view) |
Author: Ezio Melotti (ezio.melotti) * |
Date: 2012-09-15 01:47 |
The * is not supposed to be used on 2.7, but I missed that.
Thanks for noticing!
|