A simple program which checks Python source files for errors

Overview

Pyflakes

A simple program which checks Python source files for errors.

Pyflakes analyzes programs and detects various errors. It works by parsing the source file, not importing it, so it is safe to use on modules with side effects. It's also much faster.

It is available on PyPI and it supports all active versions of Python: 2.7 and 3.4 to 3.8.

Installation

It can be installed with:

$ pip install --upgrade pyflakes

Useful tips:

  • Be sure to install it for a version of Python which is compatible with your codebase: for Python 2, pip2 install pyflakes and for Python3, pip3 install pyflakes.
  • You can also invoke Pyflakes with python3 -m pyflakes . or python2 -m pyflakes . if you have it installed for both versions.
  • If you require more options and more flexibility, you could give a look to Flake8 too.

Design Principles

Pyflakes makes a simple promise: it will never complain about style, and it will try very, very hard to never emit false positives.

Pyflakes is also faster than Pylint or Pychecker. This is largely because Pyflakes only examines the syntax tree of each file individually. As a consequence, Pyflakes is more limited in the types of things it can check.

If you like Pyflakes but also want stylistic checks, you want flake8, which combines Pyflakes with style checks against PEP 8 and adds per-project configuration ability.

Mailing-list

Share your feedback and ideas: subscribe to the mailing-list

Contributing

Issues are tracked on GitHub.

Patches may be submitted via a GitHub pull request or via the mailing list if you prefer. If you are comfortable doing so, please rebase your changes so they may be applied to master with a fast-forward merge, and each commit is a coherent unit of work with a well-written log message. If you are not comfortable with this rebase workflow, the project maintainers will be happy to rebase your commits for you.

All changes should include tests and pass flake8.

GitHub Actions build status

Changelog

Please see NEWS.rst.

Comments
  • Detect type hint comments: PEP484

    Detect type hint comments: PEP484

    Original report by w-thomas-q on Launchpad:


    Hi,

    thanks for this really great tool! One issues I stumbled upon was that type hints seem to be ignored / not detected. For example, we have an import at the top of a file:

    from typing import List
    

    And then later in an __init__ function something like this:

    self.scripts = []  # type: List[script.Script]
    

    Now running pyflakes (through flake8) gives me this error:

    foo.py:4:1: F401 'List' imported but unused
    

    PEP484 defines this kind of type comments. Is there an option to enable type hint detection? Or can we have that as feature request? I guess I'm fine with type comments only for the time being, but of course a fully PEP484 compliant solution would be greatly appreciated :)

    Thanks!

    help wanted 
    opened by pyflakes-bot 33
  • Ignore

    Ignore "_" vars in "Unused Variable" check

    Original report by archardlias on Launchpad:


    Would it be possible to ignore variables named "_" from "Unused Variable" checks?

    I'm not really sure whether "_" is officially specified anywhere. But I do see it a lot and in a lot of languages including python to denote a variable to be ignored (place holder dummy). PyLint implements this pseudo(?)-convention (? second-hand knowledge).

    Would be great, since I would love to be explicit about "things returned but not used" instead of just calling without assignment which looks tantamount to "this function does never return anything / does not contain a return statement". A great plus in signature visibility throughout the code, specially for first-time readers.

    Best regards, ~arlias

    opened by pyflakes-bot 33
  • Update project metadata

    Update project metadata

    Point people to GitHub, not Launchpad. All that's left on Launchpad are a bunch of stale bugs.

    Update the author field to reflect the large number of contributors. Remove the maintainer field because a bug in something (setuptools?) overwrites the author field with the maintainer field when the package gets uploaded to PyPI.

    opened by bitglue 31
  • Warn against reusing exception names after the except: block on Python 3

    Warn against reusing exception names after the except: block on Python 3

    The following code is invalid on Python 3:

    try:
        raise ValueError('ve')
    except ValueError as exc:
        pass
    
    print("Last exception:", exc)    # raises an UnboundLocalError
    

    This pull request makes the Checker warn against this problem. There are new tests that pass on both Python 2 and Python 3.

    opened by ambv 26
  • Tuple object has no attribute ctx

    Tuple object has no attribute ctx

    With this code:

    for i in seq_a:
        for j in seq_b:
            print(i, j)
    

    Running flake8 gives me this exception:

    CRITICAL:flake8.checker:Plugin F raised an unexpected exception
    Traceback (most recent call last):
      File "/home/ubuntu/.local/lib/python3.6/site-packages/flake8/checker.py", line 435, in run_check
        return plugin["plugin"](**arguments)
      File "/home/ubuntu/.local/lib/python3.6/site-packages/flake8/plugins/pyflakes.py", line 94, in __init__
        file_tokens=file_tokens,
      File "/home/ubuntu/.local/lib/python3.6/site-packages/pyflakes/checker.py", line 672, in __init__
        self.handleChildren(tree)
      File "/home/ubuntu/.local/lib/python3.6/site-packages/pyflakes/checker.py", line 1073, in handleChildren
        self.handleNode(node, tree)
      File "/home/ubuntu/.local/lib/python3.6/site-packages/pyflakes/checker.py", line 1120, in handleNode
        handler(node)
      File "/home/ubuntu/.local/lib/python3.6/site-packages/pyflakes/checker.py", line 1073, in handleChildren
        self.handleNode(node, tree)
      File "/home/ubuntu/.local/lib/python3.6/site-packages/pyflakes/checker.py", line 1120, in handleNode
        handler(node)
      File "/home/ubuntu/.local/lib/python3.6/site-packages/pyflakes/checker.py", line 1541, in TUPLE
        if not PY2 and isinstance(node.ctx, ast.Store):
    AttributeError: 'Tuple' object has no attribute 'ctx'
    "pyflakes" failed during execution due to "'Tuple' object has no attribute 'ctx'"
    Run flake8 with greater verbosity to see more details
    
    opened by Dreamsorcerer 24
  • The Next Release (pyflakes 2.2.x)

    The Next Release (pyflakes 2.2.x)

    :wave: I'd like to organize the next release of pyflakes

    I'll be pinning this issue and collecting feedback on things that should end up in this release

    Due to the number of contributions that have gone into pyflakes since the last release, I'm planning to do this as 2.2.0a1 first (an alpha pre-release) -- this should hopefully expand the number of people trying the release (though I suspect not all that many will use the alpha still)


    How you can help:

    • try out the latest master on your repositories: pip install --force-reinstall git+https://github.com/pycqa/pyflakes
    • review open PRs
    opened by asottile 23
  • Add a structured list reporter to pyflakes.reporter

    Add a structured list reporter to pyflakes.reporter

    Adding a simple reporter class to log to a list of dictionaries with a consistent format across all message types and sources:

    • message_class: analogous to E/W/L, e.g., "error"
    • message_type: more specific type or description, e.g., "syntax_error"
    • filename: file name if provided, else None
    • lineno: line number if provided, else None
    • message: "message" from the perspective of the sender
    • source: source code if provided, else None

    Sample output:

    >>> reporter = pyflakes.reporter.ListReporter()
    >>> pyflakes.api.check(source_bytes, file_name, reporter)
    >>> print(reporter.entries)
    [{'message_class': 'warning',
      'message_type': 'flake_warning',
      'filename': '0-core-client-1.1.0a8/zeroos/core0/client/__init__.py',
      'lineno': 1,
      'offset': 0,
      'message': "'.client.Client' imported but unused",
      'source': None},
     {'message_class': 'warning',
      'message_type': 'flake_warning',
      'filename': '0-core-client-1.1.0a8/zeroos/core0/client/__init__.py',
      'lineno': 1,
      'offset': 0,
      'message': "'.client.ResultError' imported but unused",
      'source': None},
     {'message_class': 'warning',
      'message_type': 'flake_warning',
      'filename': '0-core-client-1.1.0a8/zeroos/core0/client/__init__.py',
      'lineno': 1,
      'offset': 0,
      'message': "'.client.JobNotFoundError' imported but unused",
      'source': None},
     {'message_class': 'warning',
      'message_type': 'flake_warning',
      'filename': '0-core-client-1.1.0a8/zeroos/core0/client/client.py',
      'lineno': 742,
      'offset': 8,
      'message': "'raise NotImplemented' should be 'raise NotImplementedError'",
      'source': None}]
    
    opened by mjbommar 23
  • Checking for non-ast syntax errors

    Checking for non-ast syntax errors

    This is the successor to https://github.com/pyflakes/pyflakes/pull/8.

    So far, I have only extended https://github.com/pyflakes/pyflakes/pull/13 to check for return at a module scope.

    I have worked on checking for break and continue outside of loops, but it's tricky to get all the corner cases right. I'll need to double check what Python does with every type of ast node to make sure I don't miss anything. For instance, a naive "bubble up until we see a loop" is wrong, because the following are all syntax errors

    while True:
        def f():
            continue
    
    while True:
        pass
    else:
        continue
    
    while True:
        try:
            pass
        finally:
            continue
    

    The compile.c code in CPython uses some different kind of ast object that already knows what kinds of valid blocks a node is in, so doesn't seem to be directly helpful in this case.

    I do plan to push more changes up here, though, including this one when I finish it. Feel free to merge early, however, if the work so far is fine (I may get stalled on this, so don't feel that you need to hold off until everything is finished).

    opened by asmeurer 23
  • TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

    TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

    Original report by ma-latorre-diaz on Launchpad:


    This simple code make pyflakes throw and exception (python 2.7.11 and 3.5.1).

    # -*- coding: utf-8 -*-
    
    from . import foo
    
    class MyClass(object):
        pass
    
    Traceback (most recent call last):
      File "/usr/lib/python3.5/runpy.py", line 170, in _run_module_as_main
        "__main__", mod_spec)
      File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "pyflakes/__main__.py", line 5, in <module>
        main(prog='pyflakes')
      File "/home/mal/develop/python/pyflakes/pyflakes/api.py", line 184, in main
        warnings = checkRecursive(args, reporter)
      File "/home/mal/develop/python/pyflakes/pyflakes/api.py", line 141, in checkRecursive
        warnings += checkPath(sourcePath, reporter)
      File "/home/mal/develop/python/pyflakes/pyflakes/api.py", line 108, in checkPath
        return check(codestr, filename, reporter)
      File "/home/mal/develop/python/pyflakes/pyflakes/api.py", line 69, in check
        w = checker.Checker(tree, filename)
      File "/home/mal/develop/python/pyflakes/pyflakes/checker.py", line 403, in __init__
        self.handleChildren(tree)
      File "/home/mal/develop/python/pyflakes/pyflakes/checker.py", line 725, in handleChildren
        self.handleNode(node, tree)
      File "/home/mal/develop/python/pyflakes/pyflakes/checker.py", line 772, in handleNode
        handler(node)
      File "/home/mal/develop/python/pyflakes/pyflakes/checker.py", line 1151, in IMPORTFROM
        node.module, alias.name)
      File "/home/mal/develop/python/pyflakes/pyflakes/checker.py", line 199, in __init__
        full_name = module + '.' + self.real_name
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
    
    opened by pyflakes-bot 20
  • Check for non-ast SyntaxErrors

    Check for non-ast SyntaxErrors

    This includes return and yield outside of a function and break and continue outside of a loop. Fixes lp 1293654.

    The problem is that these SyntaxErrors are not encoded in the ast grammar, so they are not detected when just compiling to ast. You must compile down to bytecode to catch them. The advantage here is that we can still check for other kinds of errors in this case, because the ast is still valid.

    opened by asmeurer 20
  • Ignore reexports in .pyi files for F401

    Ignore reexports in .pyi files for F401

    Is it possible for flake8 F401 to ignore this kind of re-exports? https://github.com/typeddjango/django-stubs/blob/master/django-stubs/db/models/init.pyi

    mypy uses those to be able to discern between imports which could, and which could not be imported from the file.

    opened by mkurnikov 19
  • branch analysis

    branch analysis

    I'm creating this mostly as a duplicate target

    pyflakes currently does not do any branch analysis and as such can't really know when things are conditionally defined / undefined / dead code / etc.

    doing accurate branch analysis is a hard problem and often requires some amount of dynamic analysis so it is unlikely pyflakes will ever actually implement this

    there are better alternatives which attempt to do this such as type checkers (mypy, pyright) and to some extent pylint

    opened by asottile 0
  • Warn about certain sequences of chained comparisons

    Warn about certain sequences of chained comparisons

    I was pointed to this buggy line:

      if x is None != y is None:
    

    (For context, Python allows chaining any of the comparison operators ==, !=, is, is not, >, >=, <, <=, in, not in. a OP b OP c is equivalent to a OP b and b OP c except that b is only evaluated once.)

    I find it hard to imagine a use case for combining is and != in the same chained comparison, so it would be useful for linters to warn about this and similar patterns.

    In my company's internal linter, I implemented a check that disallows all chained comparison pairs except == + ==, is + is, </<= + </<=, and >/>= + >/>=.

    It found one false positive where someone had intentionally written == + !=, but I'd argue it's clearer with and:

    -                        value.fullName == existing.fullName != "*"
    +                        (value.fullName == existing.fullName and value.fullName != "*")
    

    Would pyflakes be interested in a similar check?

    opened by JelleZijlstra 1
  • Add end coordinates for column and line number

    Add end coordinates for column and line number

    Closes #454.

    • [x] Added offset when handling positions in docstrings (same as for the start coordinates)
    • [x] Added test for the offset handling, conditional on Python >= 3.8\
    • [x] Checked that tests pass locally and no flake8 warnings are introduced
    opened by krassowski 1
  • Check for invalid format specifiers

    Check for invalid format specifiers

    pyflakes does some format specifier checks (https://github.com/PyCQA/pyflakes/pull/443), but it isn't able to detect invalid format specifiers. For example

    f"{x:f.1}"
    "{x:f.1}".format(x=1)
    

    are both wrong (the f is supposed to go after the .1). Also the f-string one is a ValueError and is only checked at runtime.

    The format specification mini-language is pretty complicated, so this would be useful, but also maybe not easy to implement. For .format strings you can use https://docs.python.org/3/library/string.html#string.Formatter.parse, but for f-strings, there's nothing in the standard library that can tokenize the f-string components (it would be useful if there were). Libraries like pygments and parso can tokenize them, or maybe the tokenizer added in https://github.com/PyCQA/pyflakes/pull/443 can be extended to handle them.

    opened by asmeurer 0
  • track `if typing.TYPE_CHECKING` to warn about non runtime bindings

    track `if typing.TYPE_CHECKING` to warn about non runtime bindings

    When importing or defining values in if typing.TYPE_CHECKING blocks the bound names will not be available at runtime and may cause errors when used in the following way:

    import typing
    
    if typing.TYPE_CHECKING:
        from module import Type  # some slow import or circular reference
    
    def method(value) -> Type:  # the import is needed by the type checker
        assert isinstance(value, Type)  # this is a runtime error
    

    This change allows pyflakes to track what names are bound for runtime use, and allows it to warn when a non runtime name is used in a runtime context.

    opened by terencehonles 6
Owner
Python Code Quality Authority
Organization for code quality tools (and plugins) for the Python programming language
Python Code Quality Authority
:sparkles: Surface lint errors during code review

✨ Linty Fresh ✨ Keep your codebase sparkly clean with the power of LINT! Linty Fresh parses lint errors and report them back to GitHub as comments on

Lyft 183 Dec 18, 2022
A framework for detecting, highlighting and correcting grammatical errors on natural language text.

Gramformer Human and machine generated text often suffer from grammatical and/or typographical errors. It can be spelling, punctuation, grammatical or

Prithivida 1.3k Jan 8, 2023
Flake8 plugin that checks import order against various Python Style Guides

flake8-import-order A flake8 and Pylama plugin that checks the ordering of your imports. It does not check anything else about the imports. Merely tha

Python Code Quality Authority 270 Nov 24, 2022
OpenStack Hacking Style Checks. Mirror of code maintained at opendev.org.

Introduction hacking is a set of flake8 plugins that test and enforce the OpenStack StyleGuide Hacking pins its dependencies, as a new release of some

Mirrors of opendev.org/openstack 224 Jan 5, 2023
A plugin for Flake8 that checks pandas code

pandas-vet pandas-vet is a plugin for flake8 that provides opinionated linting for pandas code. It began as a project during the PyCascades 2019 sprin

Jacob Deppen 146 Dec 28, 2022
A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.

flake8-bugbear A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycode

Python Code Quality Authority 869 Dec 30, 2022
open source tools to generate mypy stubs from protobufs

mypy-protobuf: Generate mypy stub files from protobuf specs We just released a new major release mypy-protobuf 2. on 02/02/2021! It includes some back

Dropbox 527 Jan 3, 2023
An open-source, mini imitation of GitHub Copilot for Emacs.

Second Mate An open-source, mini imitation of GitHub Copilot using EleutherAI GPT-Neo-2.7B (via Huggingface Model Hub) for Emacs. This is a much small

Sam Rawal 238 Dec 27, 2022
Simple Python style checker in one Python file

pycodestyle (formerly called pep8) - Python style guide checker pycodestyle is a tool to check your Python code against some of the style conventions

Python Code Quality Authority 4.7k Jan 1, 2023
Mylint - My really simple rendition of how a linter works.

mylint My really simple rendition of how a linter works. This original version was written for my AST article. Since then I've added tests and turned

Tushar Sadhwani 2 Dec 29, 2021
Optional static typing for Python 3 and 2 (PEP 484)

Mypy: Optional Static Typing for Python Got a question? Join us on Gitter! We don't have a mailing list; but we are always happy to answer questions o

Python 14.4k Jan 8, 2023
A Python Parser

parso - A Python Parser Parso is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python

Dave Halter 520 Dec 26, 2022
Performant type-checking for python.

Pyre is a performant type checker for Python compliant with PEP 484. Pyre can analyze codebases with millions of lines of code incrementally – providi

Facebook 6.2k Jan 4, 2023
A static type analyzer for Python code

pytype - ?? ✔ Pytype checks and infers types for your Python code - without requiring type annotations. Pytype can: Lint plain Python code, flagging c

Google 4k Dec 31, 2022
The strictest and most opinionated python linter ever!

wemake-python-styleguide Welcome to the strictest and most opinionated python linter ever. wemake-python-styleguide is actually a flake8 plugin with s

wemake.services 2.1k Jan 1, 2023
Static type checker for Python

Static type checker for Python Speed Pyright is a fast type checker meant for large Python source bases. It can run in a “watch” mode and performs fas

Microsoft 9.2k Jan 3, 2023
Tool to check the completeness of MANIFEST.in for Python packages

check-manifest Are you a Python developer? Have you uploaded packages to the Python Package Index? Have you accidentally uploaded broken packages with

Marius Gedminas 270 Dec 26, 2022
Flake8 extension for checking quotes in python

Flake8 Extension to lint for quotes. Major update in 2.0.0 We automatically encourage avoiding escaping quotes as per PEP 8. To disable this, use --no

Zachary Heller 157 Dec 13, 2022
Check for python builtins being used as variables or parameters

Flake8 Builtins plugin Check for python builtins being used as variables or parameters. Imagine some code like this: def max_values(list, list2):

Gil Forcada Codinachs 98 Jan 8, 2023