Ignore doctests/docstrings with pyflakes/pylint - python

Right now, if I have some function like this and I'd like to be able to get the error about index not being defined, while ignoring the error that some_index is not defined.
def myfunction(ind, other):
"""
Parameters
----------
ind: Index
other: Index or set
Returns
-------
Index.
Examples
--------
>>> myfunction(some_index, other)
"""
return index + other
If I run this through flake8 I get:
file.py:15:1: F821 undefined name 'other'
file.py:15:1: F821 undefined name 'some_index'
file.py:17:1: F821 undefined name 'index'
But what I want to see is just the index error and ignore the others:
file.py:17:1: F821 undefined name 'index'
If I run pylint or pyflakes on it, gives an error about some_index and other not being defined (which is True, but not necessarily useful all the time). How do I tell the programs to skip those errors? I'm working on a big library with many examples scattered throughout, some of which aren't defined but are just set to be examples of how to call them. Yes, it isn't great to not be able to run the doctests, but for the moment, it adds a ton of noise to pylint or pyflakes output. Flake8 doesn't seem to offer the option to skip them either.
How can I make this work? Is there an easy way to detect which things are docstrings in Python and filter the results that way?

Checking docstrings is a regression in pyflakes; please go comment on that bug to add your voice to the discussion.
You can disable it for now by setting the environment variable PYFLAKES_NODOCTEST.

flake8 provides an option ignore:
flake8 --ignore=F821 a.py

Related

Type error when accessing Django request.POST

I'm attempting to build an XML document out of request.POST data in a Django app:
ElementTree.Element("occasion", text=request.POST["occasion"])
PyCharm is giving me an error on the text parameter saying Expected type 'str', got 'Type[QueryDict]' instead. I only bring up PyCharm because I know its type checker can be overzealous sometimes. However, I haven't been able to find anything about this issue specifically.
Am I doing something wrong? Or should I try to silence this error?
Assuming you're not posting anything unusual, like json, request.POST['occasion'] should return a string, either the field 'occasion' or the last value of the list submitted with that name (or an error, if empty. Use request.POST.get('occasion') to avoid).
There are apparently some httprequest related issues with pycharm, but the way to doublecheck if this is happening here would be to print out and/or type check request.POST['occasion'] prior to that line to make sure of what it returns, eg:
occasion = request.POST['occasion']
print(type(occasion), occasion)
ElementTree.Element("occasion", text=occasion)
In the last line, using a variable assigned ahead of time might be a simple way to remove the pycharm error without turning off warnings, depending on your tolerance for extra code.

Mypy catch AttributeError

have been using the following code
import yaml
try:
filterwarnings(yaml.YAMLLoadWarning)
except AttributeError:
pass
But when I tried to run mypy today I got "module has no attribute YAMLLoadWarning". Which is true on some versions of python. Is there a better way to write this?
EDIT:
To be a little clearer, I know how to ignore the error (and catch the exception related to the python 3.6 version of pyyaml not including that exception). My question is more about working with the parser. Consider these examples-
I know that if you have a function that returns a more specific type
def bad(a: Optional[int]) -> int:
return a # Incompatible return value type (got "Optional[int]", expected "int")
You can use a branch to force only the correct type to be returned, and the parser notices
def good(a: Optional[int]) -> int:
if a:
return a
return 0
So in situations where you handle error situations using a try/catch statement, is there a way to construct this so that the parser realizes that the attribute error is handled?
def exception_branch(a: Optional[str])-> list:
try:
return a.split() # Item "None" of "Optional[str]" has no attribute "split"
except:
return []
So in situations where you handle error situations using a try/catch statement, is there a way to construct this so that the parser realizes that the attribute error is handled?
No, there is not, I'm afraid. The problem is that catch AttributeError does not indicate where from the exception comes. So if you had
try:
print(foo.barr)
return a.split()
except AttributeError:
return []
The typechecker can ignore the fact that a can be None, but it would have to ignore also the fact that you misspelled bar and there is no barr attribute in the object foo. See also here.
I'm assuming you're using PyYAML?
In that case, the best long-term fix is probably for you to submit a pull request to Typeshed including type hints for this class. (Typeshed is the repository of type hints for standard library modules and select third party modules. The stubs for PyYAML happen to be included within typeshed here.)
It seems PyYAML defines YAMLLoadWarning within the module's __init__.py file so you should probably add type hints for that class within the corresponding __init__.pyi file in Typeshed.
Then you wait for the next release of mypy -- it bakes in the latest available version of Typeshed the time of release.
I believe mypy is actually scheduled to release later today, so the timing might be a bit tight if you end up submitting a PR. But worst case scenario, you'll just need to wait for another month or two for the subsequent mypy release.
In the meantime, you can just add a # type: ignore comment to that line, as suggested by Georgy in the comments.
If you do this, I also recommend running mypy with the --warn-unused-ignores command line flag. This will help you find # type: ignore comments you no longer need as mypy releases/improves over time.

Parameterized generics cannot be used with class or instance checks

I wrote the code, but I get the following message in pycharm(2019.1):
"Parameterized generics cannot be used with class or instance checks"
def data_is_valid(data):
keys_and_types = {
'comment': (str, type(None)),
'from_budget': (bool, type(None)),
'to_member': (int, type(None)),
'survey_request': (int, type(None)),
}
def type_is_valid(test_key, test_value):
return isinstance(test_value, keys_and_types[test_key])
type_is_valid('comment', 3)
I really do not understand this message well. Did I do something wrong or is it a bug in pycharm?
The error disappears if I explicitly typecast to tuple.
def type_is_valid(test_key, test_value):
return isinstance(test_value, tuple(keys_and_types[test_key]))
That looks like a bug in pycharm where it's a bit overeager in assuming that you're using the typing module in an unintended way. See this example here where that assumption would have been correct:
The classes in the typing module are only useful in a type annotation context, not to inspect or compare to actual classes, which is what isinstance tries to do. Since pycharm sees a simple object with square brackets that do not contain a literal, it jumps to the wrong conclusion you are seeing.
Your code is fine, you can use it exactly as it is.
I will not repeat after others that this is a pycharm bug. Just if you are a perfectionist and the error hurts your eyes, add the comment
# noqa
to the line where the "error" is
This was a known bug in PyCharm 2018, reported here.
There are some related bugs still in more recent PyCharm versions, e.g. PyCharm 2021.2.2, here.
In general, when you found that some PyCharm warning is incorrect, I would first isolate a simple test case where it becomes more clear what PyCharm is actually incorrect about. When it is clear that PyCharm is wrong with the warning, then you should always fill a bug report about it (or maybe search for existing bug reports first). Here this is clear because PyCharm says you cannot do sth, while in fact you can, so sth is wrong.
Since it's agreed it's a bug, you can suppress it in Pycharm by the line:
# noinspection PyTypeHints

Can I suppress mypy errors in-line?

I recently made the mistake of opening my $PYTHONSTARTUP file with mypy syntax checking enabled. As a result, I started getting this error:
startup.py|79 col 2 error| Incompatible types in assignment (expression has type "HistoryPrompt", variable has type "str")
On line 79:
sys.ps1 = HistoryPrompt()
I immediately thought, "By Jove, mypy! You're entirely correct! And yet, that is exactly what I want to do, so you're also wrong!"
I went looking to see if there was some kind of "stub" for the sys module, but couldn't find anything. I'm guessing that mypy is determining the type by looking at the value stored in the variable (default is ">>> ", which is a str).
In reality, of course, the type needs to be the non-existant typing.Stringifiable, indicating an object that will respond to str(x).
Having reached that dead end, I went looking for a way to tell mypy to suppress the error. So many of the other tools support # noqa: xxx that I figured there must be something, right?
Wrong. Or at least, I couldn't find it in my version, which is: mypy 0.670
So I devised a hack clever work-around:
import typing
# Work around mypy error: Incompatible types in assignment
suppress_mypy_error: typing.Any = HistoryPrompt()
sys.ps1 = suppress_mypy_error
My question is this: Is there a way to suppress this particular error in-line (best), or in mypy.ini, or by submitting a PR to python/mypy, or ...?
To explicitly suppress MyPy on a specific line, add a comment of the form # type: ignore.
To suppress MyPy for an entire module, add the same comment at the top of the module.
Source: https://mypy.readthedocs.io/en/latest/common_issues.html#spurious-errors-and-locally-silencing-the-checker
Overview
I prefer to suppress mypy errors based on 2 things:
specific lines (your question), and
specific error.
Example
For example, the # type: ignore [no-untyped-call]:
# ignore mypy error because azure has broken type hints.
# See https://github.com/Azure/azure-sdk-for-python/issues/20083 (the issue is closed but the problem remains)
exception = azure.core.exceptions.ResourceNotFoundError("Test") # type: ignore [no-untyped-call]
You can find out the "error code" (e.g. no-untyped-call) in the mypy output by configuring mypy with:
in pyproject.toml
[tool.mypy]
show_error_codes = true
or in mypy.ini
[mypy]
show_error_codes = True
Benefits
Documentation in code: You can see exactly what error is being suppressed.
You won't ignore other errors by mypy. Otherwise, that line could be a source of bugs in the future and mypy would not warn you.

PyCharm TensorFlow warning - Type 'Variable' doesn't have expected attribute '__sub__'

Upon copying retrain.py from the TensorFlow GitHub repository
And then opening it in PyCharm, on lines 794 and 802 PyCharm shows the following warning:
Type 'Variable' doesn't have expected attribute '__sub__'
Here is a screenshot if that helps:
Can somebody please explain:
What does this mean?
How can this be resolved or the warning suppressed?
Clearly PyCharm thinks that layer_weights does not have an attribute "__sub__", but what does this mean and why would a __sub__ attribute be necessary? The function variable_summaries() does not refer to an attribute __sub__ (copied/pasted starting at line 735):
def variable_summaries(var):
"""Attach a lot of summaries to a Tensor (for TensorBoard visualization)."""
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.summary.scalar('mean', mean)
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
tf.summary.scalar('stddev', stddev)
tf.summary.scalar('max', tf.reduce_max(var))
tf.summary.scalar('min', tf.reduce_min(var))
tf.summary.histogram('histogram', var)
# end of function
Can somebody explain why an attribute __sub__ would be necessary?
After reading the this post, I'm under the impression that a comment to suppress this warning could be added, possibly something like:
#type whatGoesHere: ??
#attribute __sub__: comment here?? # is this correct?
#param whatGoesHere: ??
Is something like this doable, and what should the comment be?
I prefer to not disable PyCharm's warnings as I find them helpful in many cases. Can somebody please provide some enlightenment on the above so as to avoid disabling this warning in PyCharm?
- Edit:
Thanks for the explanation Shu. For the moment this seems to be the best way to deal with this in PyCharm without disabling that inspection entirely:
# this comment is necessary to suppress an unnecessary PyCharm warning
# noinspection PyTypeChecker
variable_summaries(layer_weights)
If eventually somebody could inform me of a better option that would be great.
The - operator is called on var inside variable_summaries:
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
Normally Python would be looking for the __sub__ method of var when evaluating the expression var - mean. However, a tf.Variable instance is wrapped around state_ops.variable_op_v2 in order to support Ops on GPU/CPU and does not have a __sub__ method that Python would normally expect.
Therefore, this warning is inherent to the way TensorFlow heavily customizing standard Python operators on Tensorflow objects in order to support the expressions we are used to while enabling GPU/CPU computation with Tensorflow OPs.
I'd say you can safely ignore this warning on any Tensorflow object. Unfortunately I don't know how you can suppress this warning in PyCharm.

Categories

Resources