How to improve PyCharm code completion (auto-complete)?
When you are working with a huge project, especially when it wasn't developed by you, code completion is an essential productivity tool, one that can save you many hours of searching inside source files or documentation.
As we probably all know, code completion cannot perfectly work with dynamic code but this doesn't mean that it has to work only in few cases, and more important the user should be able to write the code and the comments in such way that it will help the IDE to detect the expected type of the variable.
Now, the question is how we can help PyCharm to help us with code completion?
One first issue would be code completion for XMLRPC calls : PY-5313 - or to rephrase it: how can I write the code in such way that I will have code completion available.
请先登录再写评论。
The best thing to do is to pick a docstring style (epydoc or sphinx) and to specify types of parameters and function return values according to that style.
I totally agree with you, the only problem being convincing PyCharm to use the type from the comments.
Take a look at this example https://gist.github.com/1486122
How about if PyCharm allowed us to force a type, with a comment. Similar thi
ngs are done in Java to disable certain inspections:
from openpyxl.reader.excel import load_workbook
book = load_workbook('corpus.xlsx')
sheet = book.get_sheet_by_name('Sheet1')
# @PyCharm:(Sheet)book
The decorator could be 100% PyCharm, without needing to mess with the language.
I love autocompletion... when it works. If we could force declare a type in PyCharm it would unlock a lot of productivity.
See also: http://www.python.org/dev/peps/pep-3107/
As described in this very thread, you can use docstrings to specify types for parameters and instance variables. I see no point in making it possible to specify types for local variables, because you'll spend far more time describing the type than you'll save thanks to the autocompletion which will use the type declaration.
Hi,
I cannot figure out how to specify type of a local variable?
I tried like this #:type s: data.MyClass, but this does not work, ie I still do not have the autocompletion.
thanks
--
Oleksandr Huziy
The very message that you're replying to says that it is not possible to specifty types for local variables, and explains why.
Hi Oleksandr,
actually it's possible to specify type for local variables.
You can see syntax here -- http://youtrack.jetbrains.net/issue/PY-4083
Note: when you declare type using docstrings -- you should write it after variable declaration.
If you use #: syntax -- write it before variable declaration.
Hi,
yes, sorry about that, I've only read the first line of your post...
--
Oleksandr Huziy
Actually this work only for local variables. That is ok, but the same problem with autocompletion is for dynamic code. By example framework SQLAlchemy - declare relation with backreference:
class Group(DeclarativeBase):
"""
Group definition for :mod:`repoze.what`.
Only the ``group_name`` column is required by :mod:`repoze.what`.
"""
__tablename__ = 'tg_group'
#{ Columns
group_id = Column(Integer, autoincrement=True, primary_key=True)
group_name = Column(Unicode(50), unique=True, nullable=False)
display_name = Column(Unicode(255))
created = Column(DateTime, default=datetime.now)
#}
#{ Relations
users = relation('User', secondary=user_group_table, backref='groups')
class User(DeclarativeBase):
"""
User definition.
This is the user definition used by :mod:`repoze.who`, which requires at
least the ``user_name`` column.
"""
__tablename__ = 'tg_user'
#{ Columns
.........
@property
def permissions(self):
"""Return a set of strings for the permissions granted."""
perms = set()
for g in self.groups: <- PROBLEM BEGIN - autocompletion failed because class atribute groups will be created on runtime by SQLAlchemy
perms = perms | set(g.permissions)
return perms
I will be very happy :-) if docstring hint will work also for this cases.
I too would find it useful to be able to specify code completion hints on-the-fly inside code. This is especially true for attributes where PyCharm's inspection doesn't know ahead of time what type the attributes are. Your SQLAlchemy example is a perfect one:
FWIW, I'm a former Wing user and I found the following system they have to be valuable:
I like this because it both tells the editor what to do, and also keeps bugs from creeping into your code. Although admittedly, it isn't ideal for duck typing.
I'd love the combination type checking/type hintnig proposed by @bouncing, but I'd want it to be a true compile time/debugging option, only optionally an assert:
There are plenty of places where I don't care if it's a duck: it better not be a duck: it better be the type I specified.
"I see no point in making it possible to specify types for local variables, because you'll spend far more time describing the type than you'll save thanks to the autocompletion which will use the type declaration"
IMO, you are off on a wrong track here. For the following reasons:
1. I fail to see the huge difference between function parameters and function local variables. It is very useful to be able to specify the type for a function parameter. What makes you think it is not useful to do the same thing for local variables?
2. We (the PyCharm users) want this. Please add it to your product. It will make PyCharm even better.
Is there an issue in the bug tracker I can vote on?
A quick Wing tip: To get the benifit of type hinting and still be able to use duck typing, you can skip the assert.
You simply write:
Type annotations on function parameters can be used to validate that parameters in function calls have the right type. They are also part of the documentation describing how the function is used. Type annotations on local variables have none of these benefits.
As described elsewhere in this thread, PyCharm does in fact support type annotations on local variables.
PyCharm also recognizes the "assert isinstance" pattern for specifying types of variables.
OK, from your initial reply I was under the impression that PyCharm did not support this.
This really needs to go in the documentation.
And validation/documentation is the least useful feature of type annotations, IMO. The code completion feature is more important/useful.
Does PyCharm also support the style without the assert, i.e. simply
isinstance(f, Foo)
?
Yeah, for some reason, I didn't think it was working, but a simple test case shows that it does.
I'll pay close attention and see if this doesn't work for me in the future.
Attachment(s):
Screenshot - 02292012 - 07:36:55 AM.png
Found a few bugs with the parsing...
-- overloaded calls, all return the same type
"""
getCurrency(self, char currency) -> my_Currency
getCurrency(self, int index) -> my_Currency
"""
-- does not parse because it is on one line...
"""getAsOfDate(self) -> my_Date"""
Is there anything I can do to force this to parse?
Looks like pycharm does not support that:
if form.is_valid():
question = form.save(commit=False)
assert isinstance(question, models.CategoryQuestion) # works
isinstance(question, models.CategoryQuestion) # no effect
question.categ<tab>
Is there any way to apply similar type hints within a django template?
There is currently no way to apply type hints in a Django template. You can file a feature request, but frankly speaking I don't see any good way to support them. Putting a {% comment %} / {% endcomment %} block for the sake of a single type hint looks extremely cumbersome to me, and there doesn't seem to be any other way to put meta-information in a Django template that would not affect the output.
I feel the type hints should go in the matching view.
I know that's not without pitfalls: but it also matches the situation where a different class of programmer or web designer works with the templates.
The template author then knows what they've got to work with, if a type hint is provided on all the parameters passed.
Actually if you specify type hints for things you put into the template context (using the standard syntax you use for local variable type hints), this should work in the current version.
I upgraded to pycharm 2.5.2 specifically in hopes this would work, but I get nothing at all in the templates:
{% for entry in entries %}
entry.entry.subtitle
{% endfor %}
category = models.Category.objects.select_related().get(pk=pk)
return render_to_response('xxx_test.html',
dict(category=category),
context_instance=RequestContext(request))
xxx_test1.html
{% block content %}
Curator={ { category.curator.
email} }{% for foo in category.entry.
all%}Title={ {
foo.title} } ID={ {foo.id} }{% endfor %}
{% include 'xxx_test2.html' with test=
category%}{% endblock %}
xxx_test2.html
Curator={ {
test.curator} }All the stuff in
strikethroughdoes not complete. Beyond that, sometimes pycharm lets me complete things with an underscore, which the template system blocks with 'Variables and attributes may not begin with underscores'.It looks like %include does not pass type hints ever.
And the for loop does not recognize the type of the temporary "foo" variable.
At some point pycharm can't do this all via magic: what about duck typing on a template included from two places?
http://youtrack.jetbrains.com/issue/PY-7446
http://youtrack.jetbrains.com/issue/PY-7447
The remaining stuff (including tracking the types of variables used for iterating in the {% for %} tag) is within PyCharm's currently implemented capabilities to analyze and is supposed to work; we'll investigate why this doesn't work in your example.
Also I might call my xxx_test2.html snippet from various includes in various places: I don't see how pycharm could ever properly work out the type without a hint.