-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Get argument infos from method descriptors #1368
Conversation
for more information, see https://pre-commit.ci
def _find_dot_so_files(path: Path) -> Iterator[Path]: | ||
for entry in path.iterdir(): | ||
if entry.suffix in importlib.machinery.EXTENSION_SUFFIXES: | ||
yield entry | ||
|
||
def _import_module(path: Path, module_full_name: str) -> types.ModuleType: | ||
spec = importlib.util.spec_from_file_location(module_full_name, path) | ||
if spec is None: | ||
raise RuntimeError( | ||
f"Cannot find spec for module {module_full_name} at {path}" | ||
) | ||
py_mod = importlib.util.module_from_spec(spec) | ||
loader = spec.loader | ||
assert isinstance(loader, importlib.abc.Loader), loader | ||
loader.exec_module(py_mod) | ||
return py_mod |
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.
There is probably a utility in astroid to do this...
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 assume it's OK to include these private helpers, it's only going to be used in the tests. And I didn't see anything the does such imports in astroid, but maybe I did not look at the right place.
@@ -790,5 +797,53 @@ def test_parse_module_with_invalid_type_comments_does_not_crash(): | |||
assert isinstance(node, nodes.Module) | |||
|
|||
|
|||
def test_c_module_text_signature(): |
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 think this test cannot pass on pypy, since they do not support CPython extensions natively.
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.
We should be able to tell pytest to skip it right?
Although I must confess I don't know if this is actually true. Did you find any documentation about this?
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.
We should be able to tell pytest to skip it right?
Yes we can
Although I must confess I don't know if this is actually true. Did you find any documentation about this?
Yes I've read that from pypy's documentation, but I can't find the link now. But here's what the pypy wiki says: "There is a compatibility layer for CPython C API extensions called CPyExt, but it is incomplete and experimental.". So I'm positive that, by default, pypy has no support for c-modules built for cpython.
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.
Let's skip then!
# set node's arguments to None to notice that we have no information, not | ||
# and empty argument list |
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.
To still be inline with this, I should set None
to args if we get a ValueError
calling signature.signature()
.
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.
Yes! Let's do that!
for more information, see https://pre-commit.ci
Also it seems that the python 3.10 tests are consistently failling the following three tests:
I'll looks into that, but I'de like to hear opinions in favour of such features before I spend too much time on it and at the end it does not fit in your agenda.. Thanks. Still Todo:
|
for more information, see https://pre-commit.ci
Up! |
@tristanlatr Could you resolve the merge conflicts? |
Conflicts are resolved, but I've not yet lint the code. There are still a couple points to discuss first. Thanks |
It looks like linux python 3.10 tests are sill failing, any clue @DanielNoord ? Thanks Talk to you later |
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 find it difficult to review this as I have absolutely zero knowledge of C-extensions or C in general. I'm not sure we actually have anybody in the maintainers team who does..
At least I answered one question 😅
"""create astroid for a living function object""" | ||
signature = inspect.signature(member) | ||
def _get_args_info_from_callable( | ||
member: Callable, |
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.
Do we know more about this Callable
?
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.
No, it can be any python callable.
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.
Okay, so I finally got some time to review this after having spent some time in the module myself (see #1589).
I don't think this typing is correct as normally all members
are either type
or narrowed down types from the types
packages.
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.
Can you more explicit and maybe suggest another typing for the function ?
# set node's arguments to None to notice that we have no information, not | ||
# and empty argument list |
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.
Yes! Let's do that!
name="mymod", | ||
ext_modules=[cmodule], | ||
packages=['mymod'], | ||
) |
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.
) | |
) | |
@@ -790,5 +797,53 @@ def test_parse_module_with_invalid_type_comments_does_not_crash(): | |||
assert isinstance(node, nodes.Module) | |||
|
|||
|
|||
def test_c_module_text_signature(): |
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.
We should be able to tell pytest to skip it right?
Although I must confess I don't know if this is actually true. Did you find any documentation about this?
There is still the issue of the failing tests... This is definitely a required feature for pydoctor to adopt astroid, because we offer support for c-modules. Talk to you later, Tristan |
"""create astroid for a living function object""" | ||
signature = inspect.signature(member) | ||
def _get_args_info_from_callable( | ||
member: Callable, |
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.
Okay, so I finally got some time to review this after having spent some time in the module myself (see #1589).
I don't think this typing is correct as normally all members
are either type
or narrowed down types from the types
packages.
# __text_signature__ attribute | ||
if getattr(member, "__text_signature__", None) is not None: | ||
f"Cannot parse __text_signature__ signature of {member}" | ||
signature = inspect.Signature() |
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 a change in behaviour, at least for ClassDefs
. Instead of setting the arguments to None
we now set it to empty lists, implying that there are no arguments. That should be reverted to mimic the current situation.
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.
Yes you are right, this was part of the stuff that I needed to change.
# __text_signature__ attribute | ||
if getattr(member, "__text_signature__", None) is not None: | ||
f"Cannot parse __text_signature__ signature of {member}" | ||
signature = inspect.Signature() |
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 a change in behaviour, at least for ClassDefs
. Instead of setting the arguments to None
we now set it to empty lists, implying that there are no arguments. That should be reverted to mimic the current situation.
@tristanlatr I have done some exploring in the module and am now more confident in merging changes here. Please let me know if you have any further questions. We should be cautious about changing stuff here, but I'm willing to help get this merged. One thing I believe would help is if you separated the creation of the new method from also using it in |
Hi @DanielNoord, I don’t think we’re going to use astroid with pydoctor in the end, turns out to be much more complicated than I thought because of divergences compared to the standard library. So I probably won’t update this PR anytime soon. If one likes this feature please fell free to build off my changes and open another PR. Cheers, |
Thanks for the headups! I'll likely cherry pick some changes from this PR and see what I can merge without too much trouble. |
@tristanlatr I have opened #1593 based on your work and some previous cherry picking. I'm going to close this PR as the discussion is quite long and most issues have been resolved in that PR. Would you be willing to do a review of that PR? I think most issue have been addressed, but considering I have no experience with C I'd like some other reviews before undrafting it. |
Steps
Description
This PR adds argument infos from method descriptors, meaning from functions defined in python C-extensions.
Type of Changes