-
-
Notifications
You must be signed in to change notification settings - Fork 508
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
Allow specialized plugins to help Jedi understand metaclasses (and other things) #626
Comments
Hmm I would actually say that it should be a Jedi plugin (a library called [jedi-django]) or even namespace packages. However, it's going to be difficult to design an API. |
I actually kept a similar idea boiling in my head for quite a while now. The idea was to cleanly separate things that Jedi can confidently reason about and the rest. For example, jedi can trace the path of a function argument within a function, but it cannot with certainty say where did the argument come from in the first place. That would be an "entrypoint". The simplest way to think about "entrypoints" was to take a module — since Jedi as of now operates on per-module basis — and try to find all the places that could change about that module, that would be, from the top of my head:
Once we identify an "entrypoint", there should be a way for a plugin to help Jedi core to resolve that entrypoint using heuristics or other a priori knowledge. For example, docstring parser that tries to guess types of the variables would become a plugin. There also could be a plugin that would scan a certain directory and subdirectories looking for usages of a function and returning found argument types. Or a plugin that traces the execution of a certain script and returns arguments found that way. In that scenario, a metaclass might simply become another entrypoint to be handled by plugins. |
@immerrr Have you seen the |
Built-in (as in written in C, not necessarily part of the standard library) objects and modules (being objects themselves) are indeed prime examples of entry points. Built-in functions, well, they are interesting beasts. I thought of entry points as objects available in the analyzed module, but created/modified outside of Jedi's reach, in a space you can think of as "terra incognita" and the entry points would be objects that "enter" the analyzed module from that "terra incognita". So a built-in function most likely being a part of a built-in module or a method on a built-in object, can be an entry point, too. What's interesting is that the function is also a short instantiation of that "terra incognita". That means, the returned values become entry points, and so do after-exit values of mutable function arguments. In rare cases, those built-in functions might also alter module-level objects. Now that I have written this down, I wonder if tracking separate entry points is actually a good idea... |
It might be better to cover with plugins these patches of "terra incognita", such as:
metaclasses could also be a special case of terra incognita that changes the scope as a whole. |
What do you mean by that? My questions about
There is no need special need for built-in functions IMO. I don't get what you mean with |
I know it is possible through setuptools entry points, but never tried that myself. So you could devise a As for assessing the API itself, things going on during Jedi type lookups are still quite confusing to me, so I don't think my opinion on it is worth anything right now. |
Ok. Thanks for the information. I think such a system (with versioning as well) would make a lot of sense!
What is exactly confusing? :) |
Question: how much of this could be managed by using Python 3.5 type hinting stub files https://www.python.org/dev/peps/pep-0484/#stub-files (assuming Jedi could read them)? |
Good question. Thank you for bringing this up, since I forgot about those However, I don't think they would help with Django's meta classes, since Django really does type conversions. |
The last comment is about 7 months old. Just curious: has Jedi gained any mechanisms to help it understand metaclasses (such as Django models) or is this discussion still up-to-date? |
The discussion is very much up-to-date and will probably be for at least another year. |
for what it's worth, another project also has dealing with static analysis of meta classes on their roadmap: python/mypy#1240 |
Is it still up to date? |
Yes. |
I'm interested having this as a feature, what would the plugin API require? are there other types of plugins you want to see in Jedi @davidhalter ? |
Well the problem is basically that it requires a LOT of different ways of injecting stuff. I don't Jedi is even closely ready for this. I think opening Jedi only makes sense once a lot of the type inference stuff is documented and you can inherit from that stuff. Otherwise it just won't work, I think. |
regarding the inference, could jedi use code that something like mypy uses to trace what the types of things are? Maybe not directly, but they've got type inference written in python so I'm hoping there's some potential there. |
Probably not, but I've never really looked into it. |
@cpdean I believe inferencing via mypy is possible, but it doesn't have a public API for this yet. Check: python/mypy#2097 |
Jedi may also fail for metaclasses like this: https://github.com/django/django/blob/2.0/django/contrib/admin/options.py#L98 Try a GoToAssignment of https://github.com/django/django/blob/2.0/django/contrib/admin/options.py#L315
|
metaclass support exists now internally. I have used it for If anyone volunteers, I'm happy to help out with questions about Django metaclasses. BTW: I haven't had a lot of questions regarding non-Django metaclasses. So I suppose support for metaclasses outside of Django is not even that important. |
Maybe I could help you. What are the questions you are talking about? |
Well, it's just someone has to do the work and I would help out if problems arise. Also if you're interested in helping out, please look at the code of |
Could you provide me a conception? The fields the method provides is a set of fields for Enum instance if metaclass name is Tell me if I'm out of the question too far :) |
Contexts are basically Python objects: functions, classes, etc. You can call stuff like Filters are the way how Jedi infers variables. The easiest example is probably classes. The first filter for a class would be the self name filter (because names defined as So get_metaclass_filters allows you to insert additional filters for meta classes that have higher priority. Therefore if there is a And
For Django it's probably first ok to ignore the Let me know if you have further questions. |
Ok, I've got the picture. One more question. How can I test my |
It's decorated by the plugin manager, see Don't worry about where you implement this. You don't need to add another "plugin". This stuff is not documented at all, so just do it in Also if you have further questions, please open a specific issue about Django classes. People are probably watching this issue and reading our kind of offtopic discussion :). |
This likely won't happen in the near/far future. There is a plugin structure, but it's not public. The reasons to not make it public are:
If you really need plugins for your software, feel free to contact me and open a new issue for your specific case. I would seriously be interested in case studies that are not covered. I don't really know about anything else than Django and Pytest, where we are working on better support. |
Take Django for example. It uses a lot of metaclasses to support declarative syntax. Would it befeasible for Jedi to let a specialized Django plugin re-write a Model AST node before parsing it to simulate what its metaclass would do?
The text was updated successfully, but these errors were encountered: