Skip to content
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

Ignoring an entire file #964

Closed
JukkaL opened this issue Oct 25, 2015 · 19 comments
Closed

Ignoring an entire file #964

JukkaL opened this issue Oct 25, 2015 · 19 comments

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 25, 2015

Edit from 2023: Do not do this.

See the following instead:


A # type: ignore at the top level of the module should ignore errors in the entire file.

Example:

# type: ignore

1 + 'x'   # no error reported!

We should still try to semantically analyze the file for some level of checking for code that uses the module, such as function argument count checking. It's not obvious whether this is always desirable, as the semantic analyzer might miss some definitions and cause false positives elsewhere.

All type annotations in the file should be ignored and not even parsed for PEP 484 conformance.

Let's require the comment to be at the beginning of a file, before the first non string literal token (before or after the docstring).

If we can't fully parse the file (but can analyze it enough to detect the # type: ignore comment) we shouldn't generate an error but basically implicitly act as if there was # type: ignore everywhere where the module is imported, and treat the module as unknown/missing.

@jhance
Copy link
Collaborator

jhance commented Nov 17, 2015

Do shebangs get parsed as a comment? We do want

#!/usr/bin/env python
#  type: ignore

to work. In general requiring the first comment is inflexible as it clashes with anything else that may require first comment.

@gvanrossum
Copy link
Member

Yes, to Python itself the #! line is just a comment. This is also why # coding: ... may be on the second line (and that may even mean that # type: ignore may have to be on the third line).

On Tue, Nov 17, 2015 at 10:26 AM, Jared Hance notifications@github.com
wrote:

Do shebangs get parsed as a comment? We do want

#!/usr/bin/env python

type: ignore

to work


Reply to this email directly or view it on GitHub
#964 (comment).

--Guido van Rossum (python.org/~guido)

@JukkaL
Copy link
Collaborator Author

JukkaL commented Nov 18, 2015

Any comment before the first non string literal, non whitespace token should be fine.

For example, this should be okay:

#!/usr/bin/env python
# coding: mypy

# This is an example.
"""This is a docstring

...
"""

# more comments

# type: ignore

import stuff
...

@ddfisher ddfisher modified the milestones: Future, 0.3.3 Mar 2, 2016
@gnprice gnprice removed the priority label Mar 2, 2016
@alunduil
Copy link
Contributor

This doesn't appear to work when the issue is alternative uses for annotations in a module. Is there another way to force mypy to not consider a module while parsing a directory where one module uses annotations for purposes other than typing?

To recap, the module in question does not import typing and when I added as the first line # type: ignore it still provided note and error output from this module.

@gvanrossum
Copy link
Member

Sorry, this hasn't been implemented in mypy yet. It should be easy to do so but few people have asked for it.

I'm curious what your use case is? Do you actually have code you want to type-check with mypy except for one file?

A hacky way to make mypy ignore the module would be to add a stub file to the same directory, e.g. if you want mypy to ignore foo.py, add an empty foo.pyi.

I don't know what PyCharm will do though.

(Also, the presence or absence of import typing is no longer relevant.)

@alunduil
Copy link
Contributor

Thanks @gvanrossum! That worked like a charm.

I'm using annotations to implement a small DSL-ish interface for functions in a particular module and mypy is obviously and correctly barfing on my custom annotations. So that one module should be skipped by mypy but everything else should be typed as normal.

I might even look into using the pyi files with types for those functions to get the best of both worlds.

I saw the note in the documents about the presence of typing being irrelevant but it also says that one shouldn't rely on this. Has that changed at all?

@gvanrossum
Copy link
Member

You should also be able to stop mypy from looking for annotations in a class or function by adding the @no_type_check decorator to it. In this case mypy will still do some limited semantic analysis on the code -- that may be good or bad, but you might play with it and see how well it works for your use case.

Regarding the need to import typing: PEP 484 doesn't require that so consider that advice dead. Where did you see that note? (There are too many different sites that provide some of the documentation, and grepping them all for "typing" is not very effective. :-)

We do have a variety of early ideas about marking files as requiring various levels of checking, but our thoughts about this topic are still very much evolving as we explore ever larger code bases.

@alunduil
Copy link
Contributor

The decorator looks useful but my particular case is a whole module or package in a project. Adding that decorator to every function would be a little tedious for the code it contains.

The note indicating that typing would be required at some point can be found here: http://mypy.readthedocs.org/en/latest/basics.html

Well if you need any opinions on various proposed solutions I can walk this case through them and see how they feel. I do like this pyi solution but still need to get everything working to see how well it's functioning.

Thanks again.

@gvanrossum
Copy link
Member

gvanrossum commented Apr 14, 2016 via email

@bdarnell
Copy link
Contributor

I have a slightly different use case for excluding a whole file: I have an optional module tornado/platform/asyncio.py which only works on python 3. This file should be analyzed in py3 mode, but skipped in py2 mode. Of course there are workarounds for this (pass in a list of files instead of pointing mypy at the whole directory, or run it and filter out the errors after the fact), but it would be nice if there were something i could put either in the file itself or in a per-project config file to skip it in py2 mode.

@gvanrossum
Copy link
Member

gvanrossum commented Apr 17, 2016 via email

@bdarnell
Copy link
Contributor

That would work, but I would consider indenting the entire file to be a less appealing option than taking more control of which files I pass in to mypy.

Also, mypy doesn't special-case if sys.version_info[0] >= 3;, but it does special-case the name PY3, so I do most of my conditional imports these days with

PY3 = sys.version_info[0] >= 3
if PY3:
    import ...

@gvanrossum
Copy link
Member

Disregarding the additional discussion, mypy should at least support this feature from PEP 484:

a # type: ignore comment on a line by itself disables all type checking for the rest of the file.

@gvanrossum
Copy link
Member

Duplicate of #626 ?

@alunduil
Copy link
Contributor

@gvanrossum, I'd agree for my portions at least.

@gvanrossum
Copy link
Member

Closing as duplicate of #626.

@adamtheturtle
Copy link

#626 Does not cover my use case.

I don't think that there is a solution for my use case. I want to have mypy check all files I write, but not vendored libraries and not generated files like those created by python-versioneer.

I currently use the following hack:

"""
Run ``mypy``, ignoring relevant errors.
"""

import subprocess
import sys


def main() -> None:
    args = ['mypy', '.']
    ignore_paths = {
        'src/dcos_e2e/_vendor',
        'src/dcos_e2e/_version.py',
        'versioneer.py',
    }
    result = subprocess.run(args=args, stdout=subprocess.PIPE)
    result_lines = result.stdout.decode().strip().split('\n')
    error_lines = [
        line for line in result_lines
        if not any(line.startswith(path) for path in ignore_paths)
    ]
    print('\n'.join(error_lines))
    sys.exit(int(bool(error_lines)))


if __name__ == '__main__':
    main()

@gvanrossum
Copy link
Member

Please open a new issue.

@adamtheturtle
Copy link

I created #4675.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants