Skip to content

Commit

Permalink
Merge pull request #86 from gforcada/builtins-whitelist
Browse files Browse the repository at this point in the history
Builtins ignorelist
  • Loading branch information
gforcada authored Oct 8, 2022
2 parents 552face + 2dff078 commit b3461fb
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Changelog

- Overhaul GitHub actions to test on actual supported python versions. [gforcada]

- New flake8 option `--builtins-ignorelist` to specify a list of builtins to ignore. [gsingh93]

1.5.3 (2020-05-14)
------------------

Expand Down
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ Install with pip::

$ pip install flake8-builtins

Options
-------

One can use `--builtins-ignorelist` option, or configuration option,
to ignore a custom list of builtins::

$ flake8 --builtins-ignorelist id,copyright *.py

Requirements
------------
- Python 3.7, 3.8, 3.9
Expand Down
24 changes: 22 additions & 2 deletions flake8_builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

from flake8 import utils as stdin_utils

WHITE_LIST = {
IGNORE_LIST = {
'__name__',
'__doc__',
'credits',
'_',
}


BUILTINS = [a[0] for a in inspect.getmembers(builtins) if a[0] not in WHITE_LIST]
# Will be initialized in `BuiltinsChecker.parse_options`
BUILTINS = None

if sys.version_info >= (3, 8):
NamedExpr = ast.NamedExpr
Expand All @@ -32,6 +33,25 @@ def __init__(self, tree, filename):
self.tree = tree
self.filename = filename

def add_options(option_manager):
option_manager.add_option(
'--builtins-ignorelist',
metavar='builtins',
parse_from_config=True,
comma_separated_list=True,
help='A comma separated list of builtins to skip checking',
)

def parse_options(option_manager, options, args):
global BUILTINS

if options.builtins_ignorelist is not None:
IGNORE_LIST.update(options.builtins_ignorelist)

BUILTINS = [
a[0] for a in inspect.getmembers(builtins) if a[0] not in IGNORE_LIST
]

def run(self):
tree = self.tree

Expand Down
22 changes: 20 additions & 2 deletions run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,33 @@
from flake8_builtins import BuiltinsChecker


class FakeOptions:
builtins_ignorelist = []

def __init__(self, ignore_list=''):
if ignore_list:
self.builtins_ignorelist = ignore_list


class TestBuiltins(unittest.TestCase):
def check_code(self, source, expected_codes=None):
def check_code(self, source, expected_codes=None, ignore_list=None):
"""Check if the given source code generates the given flake8 errors
If `expected_codes` is a string is converted to a list,
if it is not given, then it is expected to **not** generate any error.
If `ignore_list` is provided, it should be a list of names
that will be ignored if found, as if they were a builtin.
"""
if isinstance(expected_codes, str):
expected_codes = [expected_codes]
elif expected_codes is None:
expected_codes = []
if ignore_list is None:
ignore_list = []
tree = ast.parse(textwrap.dedent(source))
checker = BuiltinsChecker(tree, '/home/script.py')
checker.parse_options(FakeOptions(ignore_list=ignore_list), None)
return_statements = list(checker.run())

self.assertEqual(
Expand Down Expand Up @@ -169,13 +183,17 @@ def bla():
"""
self.check_code(source, ['A001', 'A001'])

def test_ignore_whitelisted_names(self):
def test_default_ignored_names(self):
source = """
class MyClass(object):
__name__ = 4
"""
self.check_code(source)

def test_custom_ignored_names(self):
source = 'copyright = 4'
self.check_code(source, ignore_list=('copyright',))

def test_for_loop_variable(self):
source = """
for format in (1, 2, 3):
Expand Down

0 comments on commit b3461fb

Please sign in to comment.