-
-
Notifications
You must be signed in to change notification settings - Fork 512
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
Return types from numpydocs and compiled objects return types from docstrings #868
Conversation
I forgot to add the testing file to this PR. Is there a way to make a complied object to test the compiled object type return? |
@davidhalter, could you take a look at this one please? We're maintaining a big patch in Spyder to make this work, and we would really like to drop it in favor of using an upstream release. |
Seriously I'm sorry. I just don't have the time to review this. There were some other priorities (including real life) that made it hard to review this. It's really the next thing on my list once I have time. I'll try ASAP. |
Thanks for the answer, and good to know this one is high in your TODO list. |
Sorry again for taking so long. I finally had time to review #796 and have tried to reach the author. If we don't get that working in the next few weeks, we'll just merge this one. I hope this is OK for you. |
Thanks David, that's fine for us. |
@bcolsen, could you update this PR in the meantime? It has some conflicts with master. |
@ccordoba12, yeah I'll try a rebase on the dev branch. |
Well that was more difficult than I thought it would be. There were some breaking changes in docstrings.py, but I fixed it. |
@davidhalter, now that the original author of #796 has confirmed that he doesn't have time to update his work, I think we can proceed with this one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I have finally reviewed this one. I stopped at one point, I will probably continue in a second iteration.
My general view is that the quality of this patch is not good enough. There are certain hacks and they are not even documented. I don't have a problem if you don't know how to work with the Jedi internals, but there's also a lot of small things that got changed along the lines. There's no need for changing anything except the numpy stuff. I'm not even against some of those changes in general, but please do it in a separate pull request, it was reaaaaally annoying to review this one and it's also why it took me so long to finally look at it. Small pull requests usually take me 2 days...
There's 3 more things that I haven't mentioned in the comments:
- Document how multiple returns in the documentation behaves and how a tuple behaves. It's very unclear from https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt how this whole thing works.
- Please include numpydocs in tox.ini as a dependency so it automatically gets tested. Also add a comment there.
- I want more tests. Simple tests like described in the comments, but I want those cases with multiple returns, yields and whatever tested.
A lot of things here need changing before I merge this. I would even think that it's probably easier to restart from zero and just copy the few good parts.
test/test_evaluate/test_docstring.py
Outdated
@@ -150,3 +152,68 @@ def foobar(x, y): | |||
assert 'capitalize' in names | |||
assert 'numerator' in names | |||
assert 'append' in names |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please try to use pytest tests for these tests. Just write them as functions and use pytest.skipif. I'm trying to get rid of those classes, because they don't make sense with pytest.
test/test_evaluate/test_docstring.py
Outdated
evaluator = script._evaluator | ||
types = docstrings.find_return_types(evaluator, func) | ||
assert len(types) == 1 | ||
assert types[0].base.obj is builtins.int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above: Also use the Jedi API directly here.
test/test_evaluate/test_docstring.py
Outdated
y_base_objs = set([t.base.obj for t in y_type_list]) | ||
x_base_objs = set([t.base.obj for t in x_type_list]) | ||
assert x_base_objs == set([builtins.int, builtins.str, builtins.list]) | ||
assert y_base_objs == set([builtins.int, builtins.str]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is way too much code. It will just make refactoring harder. Please test the jedi api directly by using jedi.Script (as in the test above).
jedi/evaluate/compiled/__init__.py
Outdated
if self.type != 'funcdef': | ||
return | ||
|
||
types = set([]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please undo this. Defining a set is not necessary. In Python 3 we would just yield from and in 2 we have to work around with
for type_ in docstrings.infer_return_types(self):
yield type
jedi/evaluate/docstrings.py
Outdated
Search `docstr` (in numpydoc format) for type(-s) of `param_str`. | ||
""" | ||
doc = NumpyDocString(docstr) | ||
returns = doc._parsed_data['Returns'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized again that we're using a non-public API here. Can we please have a try/except around it and catch both key error and
try:
# This is a non-public API. If it ever changes we should be prepared and return gracefully.
returns = doc._parsed_data['Returns']
returns += doc._parsed_data['Yields']
except (KeyError, AttributeError):
return []
Please also change this for the param version of this function.
jedi/evaluate/docstrings.py
Outdated
p_type = p_name | ||
p_name = '' | ||
|
||
m = re.match('([^,]+(,[^,]+)*?)$', p_type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WTF does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing I think. I removed it and it still works.
It seems to be copied from the exiting numpydocs params function:
m = re.match('([^,]+(,[^,]+)*?)(,[ ]*optional)?$', p_type)
which seems like a complicated way of removing the , optional
from the parameter type string.
jedi/evaluate/docstrings.py
Outdated
# python2 does not support literal set evals | ||
# workaround this by using lists instead | ||
p_type = p_type.replace('{', '[').replace('}', ']') | ||
types = set(type(x).__name__ for x in literal_eval(p_type)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jedi has it's own ways of parsing stuff. No need for this. I'm not sure what this does anyway, but I'm pretty sure that it's not the way how you should do things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Numpydoc allows types to be a set of literals like:
order : {'C', 'F', 'A'}
It works like this:
>>> from ast import literal_eval
>>> set(type(x).__name__ for x in literal_eval("['x', [], 2.3]"))
{'float', 'list', 'str'}
This code in already in docstrings.py:
https://github.com/davidhalter/jedi/blob/dev/jedi/evaluate/docstrings.py#L60
All this being said I'm sure that there is already a way to do this in jedi
@davidhalter Thank you for looking into this. I have read your comments and did more research into what this code is doing since I have been mostly porting it over up until now. I have already started to simplify the code and write my own tests. |
Let me know when you're ready! |
It's ready. I reduced and rewrote the code using The I made a bit of a mess in tox.ini it seems that numpydocs doesn't support py2.6 or py3.3 although the next version of jedi might drop those versions as well. I also can't seem to make a test for yields. Jedi returns a generator object. |
Using it without control over the input leads to various possible exceptions. Refs #868.
@bcolson Good work! Thanks. I think it's pretty cool that we have this now within Jedi. I made one minor change: literal_eval should not be used. It leads to potential exceptions. I instead used jedi's parser (parso) to parse it and work with it. I hope that's fine. This also gets rid of the set literals hack (even though I think that was not needed in the first place, because they are not supported in 2.6 but are in 2.7. However since numpydocs doesn't work in 2.6 you can just ignore 2.6.).
Hmm if you're still interested, that might be true, but you can just use |
Thanks for the review! It is cool to be completing Numpy now. The parser code for the literal is much better than trusting
Of course, I wasn't thinking right about that one. The tests work either way but I'll give it a shot with |
In this PR I have updated the docstrings.py from @Erotemic in PR: #796 so that it merges against the changes that have been made to the current dev branch since the original commits. I have also removed the google docstrings from this PR as I don't have the experience necessary to test these docstrings. However, It should be quite simple for @Erotemic to add this functionality as an addition PR. With this split there are less code changes, hopefully making this PR easier to merge.
This pull request solves issue #372 for numpy complied objects.
Numpy functions such as numpy.array return an numpy.ndarray object resulting in completions like this:
I have not yet written a test since I need to import numpydocs and numpy to do such.
A standard python library with complied objects and sphinx documentation would be a better test.