8000 ENH: Show full PEP 457 argument lists for ufuncs by eric-wieser · Pull Request #9026 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Show full PEP 457 argument lists for ufuncs #9026

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 9, 2017

Conversation

eric-wieser
Copy link
Member
@eric-wieser eric-wieser commented Apr 29, 2017

Describes the full argument lists of ufunc.__call__ using PEP 457 syntax.

Before:

add(x1, x2, [out])
frexp(x, [out1, out2,])

After:

add(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True, signature, extobj)
frexp(x[, out1, out2], /[, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])

In future, this could be hooked up to __text_signature__ (#8734) to make inspect.signature work on ufuncs (right now, this requires monkey-patching inspect).

This needs to be checked for compatibility against sphinx/numpydoc, which might choke on this signature format Done and working!

@eric-wieser
Copy link
Member Author
eric-wieser commented Apr 29, 2017

If we want to make inspect.signature work, we'd:

  • Add a trivial __text_signature__ attribute that contains what we calculate here
  • Monkey-patch as inspect._NonUserDefinedCallables += (np.ufunc,)

It's worth noting that inspect.signature does not support the square bracket syntax suggested by PEP457

@eric-wieser eric-wieser changed the title ENH: Show full argument lists for ufuncs ENH: Show full PEP 457 argument lists for ufuncs Apr 29, 2017
@eric-wieser eric-wieser force-pushed the ufunc_docstrings branch 2 times, most recently from 44c1506 to a01b003 Compare May 1, 2017 09:58
@mhvk
Copy link
Contributor
mhvk commented May 1, 2017

I now looked in a bit more detail, and this looks all good. It might make sense to have it in 1.13 still, but perhaps @charris should decide on that.

@charris
Copy link
Member
charris commented May 1, 2017

@mhvk If you think it is good, put it in. The 1.13.0 milestone is for things I think need to be in 1.13, and some of those I'll probably push off again to 1.14.

@eric-wieser
Copy link
Member Author

Note that if we do put this in, the arguments still wont be described on the individual ufunc pages - so somehow, we should probably link back to the ufunc docs

@mhvk
Copy link
Contributor
mhvk commented May 1, 2017

@eric-wieser - you mean that these changes are visible in, say, ipython, but won't be seen by sphinx?

@eric-wieser
Copy link
Member Author
eric-wieser commented May 1, 2017

I mean that the top of the sphinx page will list all the arguments, but nowhere on the page will a description of the arguments be given.

Having said that, I haven't actually tested that sphinx supports this syntax...

IPython seems to show the new longer argument lists, which was my main aim here

@eric-wieser
Copy link
Member Author

Having said that, I haven't actually tested that sphinx supports this syntax...

And havehad difficulty in the past on windows getting numpy to build docs from the source, rather than the installed version

@mhvk
Copy link
Contributor
mhvk commented May 1, 2017

Ah, yes, so the general description has to be adapted too. In that case, my suggestion would be to merge this with 1.14 as a milestone, and raise a new issue to also adjust the overall documentation.

@eric-wieser
Copy link
Member Author

In that case, my suggestion would be to merge this with 1.14 as a milestone

Huh? Do you mean wait until 1.13 is branched, and then merge? Or set the milestone to 1.14 yet merge it into 1.13?

@eric-wieser
Copy link
Member Author

Ah, yes, so the general description has to be adapted too.

Done. All this needs is someone with a working doc build setup to check that the pages for np.add and np.fr 8000 exp look right under sphinx.

Alternate array object(s) in which to put the result; if provided, it
must have a same shape that the inputs broadcast to.
where : array_like, optional
Values of True indicate to calculate the ufunc at that position, values
Copy link
Member Author
@eric-wieser eric-wieser May 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a bonus, this now means that where is documented everywhere.

We could add the others here, but the explanations are more complicated, and they'd risk diverging from ufuncs.kwargs

def add_newdoc(place, name, doc):
doc = textwrap.dedent(doc).strip()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dedenting here makes substituting $PARAMS do the right thing

where : array_like, optional
Values of True indicate to calculate the ufunc at that position, values
of False indicate to leave the value in the output alone.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it clearer that there are other arguments, I'd put this as part of the parameter list:

**kwargs
    For other keyword-only ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@mhvk
Copy link
Contributor
mhvk commented May 2, 2017

For reasons slightly beyond me, I have similar problems with the sphinx build using the system installation of numpy despite being in a virtual environment in which I have installed the PR. So, I cannot immediate check that things work there.

Inside ipython, things look good, except I think one might as well adjust the class docstring as well...

@eric-wieser eric-wieser force-pushed the ufunc_docstrings branch 2 times, most recently from d21b48c to d0e2800 Compare May 2, 2017 10:31
@eric-wieser
Copy link
Member Author

I think one might as well adjust the class docstring as well...

Done

@eric-wieser
Copy link
Member Author
eric-wieser commented May 3, 2017
8000

For reasons slightly beyond me, I have similar problems with the sphinx build using the system installation of numpy despite being in a virtual environment in which I have installed the PR.

The solution I found is to use runtests.py --shell, and then building the docs from there.

The signature works just fine, but the link doesn't work:

image

image

Oddly, sphinx seems to move the square brackets around, but it doesn't seem to matter

@pv
Copy link
Member
pv commented May 3, 2017 via email

@eric-wieser
Copy link
Member Author
eric-wieser commented May 3, 2017

@pv: I'm running into #9046 here, which means those screenshots do not match my source. There's also some caching within sphinx that is making this hard to iterate on

@eric-wieser
Copy link
Member Author

Ok, after doing a truly clean build, this now works:

image

@charris charris added this to the 1.14.0 release milestone May 5, 2017
@eric-wieser eric-wieser mentioned this pull request May 6, 2017
3 tasks
@eric-wieser
Copy link
Member Author
eric-wieser commented May 7, 2017

Arguments for putting this in 1.13: We're now allowing people to intercept all the ufunc arguments in __array_ufunc__, so it'd be handy to give people a reminder of what they are, without having to resort to the online docs

@mhvk
Copy link
Contributor
mhvk commented May 7, 2017

I think you ended up making the full change, right? If so, I think 1.13 is indeed appropriate.

@eric-wieser
Copy link
Member Author
eric-wieser commented May 7, 2017

@mhvk: Yep, this is complete and tested. although the later of this and #9063 to be merged will require changes

Copy link
Contributor
@mhvk mhvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had another look and found a few small things to change, but overall, this looks great!

@@ -5421,40 +5421,19 @@ def luf(lamdaexpr, *args, **kwargs):
"""
Functions that operate element by element on whole arrays.

To see the documentation for a specific ufunc, use np.info(). For
example, np.info(np.sin). Because ufuncs are written in C
To see the documentation for a specific ufunc, use `np.info`. For
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be double ticks to, or does it link correctly? (I ask since in astropy this would require ~numpy.info; if the link does work, maybe pre-pend :func:)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to check this. I think you're probably right there.

Copy link
Member Author
@eric-wieser eric-wieser May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page never gets generated anyway in the html docs, so this is kinda irrelevant

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to info for simplicity, in case this does get linked in future

def add_newdoc(place, name, doc):
doc = textwrap.dedent(doc).strip()
doc = doc.replace('$PARAMS', _params_text)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit odd to have this shell-like contruct. Why not just call it {PARAMS} in the strings, and here do

doc = doc.format(PARAMS=_params_text)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latex in the docstrings was my concern here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, that seems fair enough. Just leave as is, then.

@@ -3067,6 +3083,7 @@ def add_newdoc(place, name, doc):
----------
x1 : array_like
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well change this to x

Copy link
Member Author
@eric-wieser eric-wieser May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, since right now it doesn't actually match the injected signature

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@mhvk
Copy link
Contributor
mhvk commented May 7, 2017

I think after #9063 makes most sense, but I'm changing the milestone so this won't be forgotten!

@mhvk mhvk modified the milestones: 1.13.0 release, 1.14.0 release May 7, 2017
@eric-wieser
Copy link
Member Author
eric-wieser commented May 8, 2017

@mhvk: Rebased to include the modifications to the divmod docstring from #9063

out : array_like
An array to store the output. Must be the same shape as the
output would have.
*x : array_like
Copy link
Member
@charris charris May 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each of the * need escaping like so \\* for sphinx. If you make it a raw string you can use a single \.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file never actually reaches sphinx anyway, but I was under the impression that this worked correctly due to the transformation that the Parameters section undergoes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had to fix other uses before as the docs didn't render correctly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this doesn't even get rendered, so no danger of it getting rendered incorrectly!

Since the only place this is ever seen is in the terminal, I'd argue it's better without backslashes.

I'd also argue that to keep the terminal tidy, the fix should go in the numpy sphinx extension, not here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that having numpydoc escape the *'s when generating the sphinx input would be nice, but it doesn't at this time. If this never showed up in the documentation, that would not be a problem, but I assume you would like it to eventually show up.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I assume you would like it to eventually show up.

Not really - AFAICT, the sole purposed of this page is to redirect the user to np.info or the ufunc docs. if ufunc.__doc__ is made visible in the web docs, then IMO, it should be the contents of ufuncs.rst.

This docstring aside - I was pretty sure that **kwargs was parsed correctly in the other docstring modified by this changeset - does the issue only exist for single asterisks?

where : array_like, optional
Values of True indicate to calculate the ufunc at that position, values
of False indicate to leave the value in the output alone.
**kwargs :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know if this needs something after the : or not, but might be safer to put a placeholder there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That : should probably be removed, but again - no HTML docs are generated from this page

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Irrelevant given that there are documents generated, but yes, with the : removed it works fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, anyway

The distinction between unary and binary is not too helpful, and ignores the fact that trinary ufuncs can exist.

Also add a link to the ufunc docs
@charris
Copy link
Member
charris commented May 9, 2017

This docstring aside - I was pretty sure that **kwargs was parsed correctly in the other docstring modified by this changeset

Not sure. The * gets translated as emphasis IIRC. Grepping the source, the two versions I see are \\*\\*kwargs or just plain kwargs without the asterisks. The latter seems like a viable workaround as long as it comes with an optional arguments explanation or some such. The same variations hold for args. I suspect a fix for numpydocs would not be too difficult if one finds where the parameters are parsed out.

@eric-wieser
Copy link
Member Author
eric-wieser commented May 9, 2017

Ok, see the screenshot in the above comment - the ** is definitely handled correctly.

@mhvk
Copy link
Contributor
mhvk commented May 9, 2017

**kwargs works fine -- see also http://docs.astropy.org/en/latest/api/astropy.coordinates.SkyCoord.html#astropy.coordinates.SkyCoord (astropy uses the numpy setup with some additions)

@eric-wieser
Copy link
Member Author

@mhvk: Do you have an example of *args working too, to save me the trouble of a local build?

@eric-wieser
Copy link
Member Author
eric-wieser commented May 9, 2017

@charris: tested with unescaped * in the arglist, and it works just fine (sphinx 1.5.6):

image

Is this then good to merge?

@charris
Copy link
Member
charris commented May 9, 2017

Looks like the escape problem has been fixed, good to know. Now we can clean up the other cases ;)

@charris charris merged commit beb4ae2 into numpy:master May 9, 2017
@charris
Copy link
Member
charris commented May 9, 2017

Thanks Eric.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0