A colleague of mine and I edit code from the same repository. Its a Python application using psycopg2 as a database driver to speak to PostgreSQL clusters. We are both decently new at this, so good documentation and doc support by the IDE is paramount to prevent mistakes.
To have autocompletion of methods, classes, functions and the likes the IDE needs to know what type of objects the variables are. As sometimes it is difficult for the IDE to determine this itself, you can usually use annotations of the syntax
myvar = functioncall() # type: <Class/Data type>
This defines myvar as the type given at the end of the line, and enables the IDE to autocomplete methods in myvar from the class/data type given.
In the following line, Pycharm could not determine the type of value that the methods returns:
with psycopg2.connect(dsn) as conn:
I took a look into the definition of psycopg2.connect() using Ctrl+q, and I got this printout:
psycopg2
def connect(dsn: Any = None,
connection_factory: Any = None,
cursor_factory: Any = None,
**kwargs: Any) -> None
Plus the whole documentation about the parameters, and ending with the note:
< Python 3.9 (venv39selected) >
The Python version we both use is 3.9, and venv39selected is the name of the venv that I use.
So I could see why the IDE could not determine the data type of the return value of connect, it doesn't document a return type.
However, after complaining to my colleague about the problem, he showed me his Ctrl+q popup, and in that, the following is printed:
psycopg2
def connect(dsn: Any | None = ...,
connection_factory: Any | None = ...,
cursor_factory: Any | None = ...,
**kwargs: Any) -> connection | connection
So he seems to have a different popup than me, one that allows his IDE to find the right return type for the variable. In all program versions, our systems and installations are the same. Python 3.9 on Windows, the same packages inside the venv, psycopg2 in version 2.9.3.
However, and that is the most interesting part: You can use Ctrl+mouseclick to enter any method/function definition. Entering the function definition of the connect method shows the same exact code for both our IDEs, and both are without the return type!
So the documentation shown in the Ctrl+q popup must come from somewhere else than from parsing the code shown using Ctrl+click. But from where? Where is that configured?
Related
I've recently been doing some programming in Rust using Clion. This provides a utility whereby when you pass positional arguments to a function it will show you which argument will pick up each value (as if you had passed them in as keyword arguments) see below:
I've found this to be a very nice feature as it's made code a fair bit more readable and prevented me making a couple of stupid mistakes. Therefore, I'd love to have this functionality in PyCharm for programming Python, does anyone know of a plugin which can do this?
I think the Python Inlay Params plugin does what you want. It adds inlay hints both for callable parameters, values, and for types on variables.
Here's a convenient snippet transcribed from the demo for testing:
class Dimens:
width: int
height: int
def __init__(self, width, height):
self.width = width
self.height = height
a = Dimens(1, 2)
And a screenshot in action using PyCharm 2022.1 Pro
See the Settings instructions on the Python Inlay Params GitHub's page. The above snippet worked for me using the default settings after installing the plugin.
For pytest users there's also the Pytest Parametrize Inlay Hint.
Just for type hints and not variables (thus not for parameters or values) there's also Python Inlay Hints.
There aren't currently any other plugins for PyCharm on JetBrains marketplace that do what you want.
It should be mentioned that using PyCharm without plugins you can already get values for parameters shown in the editor just using the debugger. For example with the following snippet:
def my_func(a: int, b: str):
c = a
c = c + 1
print(str(a), b)
return
my_func(1, 'b')
During debugging the values will be shown alongside the variables and the parameters, although not embedded in the code of the signatures themselves. As shown in the screenshot:
To configure the shown functionality go to File > Settings > Build, Execution, Deployment > Debugger > Data Views and under Editor check Show values inline. See the PyCharm documentation View values inline.
I'm looking for a Python linter, that can check types usage according to the type hints in the code.
The purpose is to run a single check that verifies style, logic, and type errors.
I need to run this on CI server, and as a file watcher during development.
For example, I need this code to output an error for passing the wrong type argument -
def double(x: int):
return x * 2
result = double('hello')
I've checked the documentation of PyLint and flake8, and couldn't find any support for type checking.
With PyLint I also verified there are no errors when checking the above code.
Yes, there is, it's called mypy
class Class:
def __init__(self, path):
self._path = path
string = open(self._path, 'r'). #HERE
When I try to type read() intelliSense says no completions.
However, I know open() function returns file object, which has read() function. I want to see all supported function after typing a dot.
PyCharm shows me recommanded function list, but PTVS does not support.
I want to know this is casual things in PTVS or only happening to me.
My current Python Enviroment is Anaconda 4.3.0 (Python 3.5.3)
How can I fix it?
We've already fixed the specific case of open for our upcoming update (not the one that released today - the next one), but in short the problem is that you don't really know what open is going to return. In our fix, we guess one of two likely types, which should cover most use cases.
To work around it right now, your best option is to assign the result of open to a variable and force it to a certain type using an assert statement. For example:
f = open(self._path, 'r')
import io
assert isinstance(f, io.TextIOWrapper)
f = open(self._path, 'rb')
import io
assert isinstance(f, io.BufferedIOBase)
Note that your code will now fail if the variable is not the expected type, and that the code for Python 2 would be different from this, but until you can get the update where we embed this knowledge into our code it is the best you can do.
When I write a function in Python (v2.7), I very often have a type in mind for one of the arguments. I'm working with the unbelievably brilliant pandas library at the movemement, so my arguments are often 'intended' to be pandas.DataFrames.
In my favorite IDE (Spyder), when you type a period . a list of methods appear. Also, when you type the opening parenthesis of a method, the docstring appears in a little window.
But for these things to work, the IDE has to know what type a variable is. But of course, it never does. Am I missing something obvious about how to write Pythonic code (I've read Python Is Not Java but it doesn't mention this IDE autocomplete issue.
Any thoughts?
I don't know if it works in Spyder, but many completion engines (e.g. Jedi) also support assertions to tell them what type a variable is. For example:
def foo(param):
assert isinstance(param, str)
# now param will be considered a str
param.|capitalize
center
count
decode
...
Actually I use IntelliJ idea ( aka pyCharm ) and they offer multiple ways to specify variable types:
1. Specify Simple Variable
Very simple: Just add a comment with the type information behind the definition. From now on Pycharm supports autcompletition! e.g.:
def route():
json = request.get_json() # type: dict
Source: https://www.jetbrains.com/help/pycharm/type-hinting-in-pycharm.html
2. Specify Parameter:
Add three quote signs after the beginning of a method and the idea will autocomplete a docstring, as in the following example:
Source: https://www.jetbrains.com/help/pycharm/using-docstrings-to-specify-types.html
(Currently on my mobile, going to make it pretty later)
If you're using Python 3, you can use function annotations. As an example:
#typechecked
def greet(name: str, age: int) -> str:
print("Hello {0}, you are {1} years old".format(name, age))
I don't use Spyder, but I would assume there's a way for it to read the annotations and act appropriately.
I don't know whether Spyder reads docstrings, but PyDev does:
http://pydev.org/manual_adv_type_hints.html
So you can document the expected type in the docstring, e.g. as in:
def test(arg):
'type arg: str'
arg.<hit tab>
And you'll get the according string tab completion.
Similarly you can document the return-type of your functions, so that you can get tab-completion on foo for foo = someFunction().
At the same time, docstrings make auto-generated documention much more helpful.
The problem is with the dynamic features of Python, I use Spyder and I've used a lot more of python IDEs (PyCharm, IDLE, WingIDE, PyDev, ...) and ALL of them have the problem you stated here. So, when I want code completion for help I just instantiate the variable to the type I want and then type ".", for example: suppose you know your var df will be a DataFrame in some piece of code, you can do this df = DataFrame() and for now on the code completion should work for you just do not forget to delete (or comment) the line df = DataFrame() when you finish editing the code.
When I'm using a 3rd party l
ibrary such as boto, PyCharm seems to be able to auto-complete quite nicely
However, as soon as I define a function of my own, auto-complete breaks down inside that function. I understand why, since I can't give the function any type information about its arguments, so it can't guess how to auto-complete. Is there a way around this issue?
Edit
I tried using the docstring (for Python 2), but still no auto-complete
def delete_oldest_backups(conn, backups_to_keep, backup_description):
"""
delete_oldest_backups(EC2Connection, int, string)
"""
(Also tried boto.ec2.connection.EC2Connection instead of just EC2Connection)
You can use type hints: http://www.jetbrains.com/pycharm/webhelp/type-hinting-in-pycharm.html
def some_method(self, conn):
"""
#type conn: EC2Connection
"""
conn.<autocomplete>
You can specify the type information about the parameters of the function using Python 3 parameter and return value annotations. If you're using Python 2, you can also specify information in the function's docstring. PyCharm understands the format used by docstrings of binary modules in the standard library, for example:
"""
foo(int, string) -> list
Returns the list of something
"""
In order for PyCharm to recognize an instance of an object and retrieve all its methods, we have to use the following statements. But I think that both is a terrible way of wasting programming and run time.
assert isinstance(instanceX, ClassOfInstanceX)
instanceX.{#list of method/properties appears}
Alternatively, you can also use the class name will recall the method or property everytime you want to invoke it and pass in the instance to the self parameter. But this is too verbose, for my liking, esp for nested class
ClassOfInstanceX.{#list of method/properties appears}
# then you will have...
ClassOfInstance.method(instanceX, args...)
You can install the library via pyCharm "package manager".
Go to Settings -> Project Interpreter -> Python Interpreters
And in the Packages list, click on install and search for the library you want to install
Once installed, auto-complete will be available on editor.
Hope this is what you are looking for.