blob: 1b182573d41b691b3f5e897a76ebe0f0b389e5f5 [file] [log] [blame]
Anthony Sottile8f615292022-01-15 19:24:05 -05001from __future__ import annotations
2
Ben Webber35996b72017-11-26 00:17:47 +00003import ast
4
5import pytest
6
Anthony Sottile45756522019-02-11 19:56:15 -08007from pre_commit_hooks.check_builtin_literals import Call
Ben Webber35996b72017-11-26 00:17:47 +00008from pre_commit_hooks.check_builtin_literals import main
Anthony Sottile45756522019-02-11 19:56:15 -08009from pre_commit_hooks.check_builtin_literals import Visitor
Anthony Sottile030bfac2019-01-31 19:19:10 -080010
11BUILTIN_CONSTRUCTORS = '''\
Anthony Sottilef5c42a02020-02-05 11:10:42 -080012import builtins
Anthony Sottile030bfac2019-01-31 19:19:10 -080013
14c1 = complex()
15d1 = dict()
16f1 = float()
17i1 = int()
18l1 = list()
19s1 = str()
20t1 = tuple()
21
22c2 = builtins.complex()
23d2 = builtins.dict()
24f2 = builtins.float()
25i2 = builtins.int()
26l2 = builtins.list()
27s2 = builtins.str()
28t2 = builtins.tuple()
29'''
30BUILTIN_LITERALS = '''\
31c1 = 0j
32d1 = {}
33f1 = 0.0
34i1 = 0
35l1 = []
36s1 = ''
37t1 = ()
38'''
Ben Webber35996b72017-11-26 00:17:47 +000039
40
41@pytest.fixture
42def visitor():
Anthony Sottile45756522019-02-11 19:56:15 -080043 return Visitor()
Ben Webber35996b72017-11-26 00:17:47 +000044
45
46@pytest.mark.parametrize(
47 ('expression', 'calls'),
48 [
Anthony Sottiledf935092018-05-17 17:14:25 -070049 # see #285
50 ('x[0]()', []),
Ben Webber35996b72017-11-26 00:17:47 +000051 # complex
Anthony Sottile8626e262019-02-11 19:57:37 -080052 ('0j', []),
53 ('complex()', [Call('complex', 1, 0)]),
54 ('complex(0, 0)', []),
Ben Webber35996b72017-11-26 00:17:47 +000055 ("complex('0+0j')", []),
Ben Webber77586762017-11-30 18:27:16 +000056 ('builtins.complex()', []),
Ben Webber35996b72017-11-26 00:17:47 +000057 # float
Anthony Sottile8626e262019-02-11 19:57:37 -080058 ('0.0', []),
59 ('float()', [Call('float', 1, 0)]),
Ben Webber35996b72017-11-26 00:17:47 +000060 ("float('0.0')", []),
Ben Webber77586762017-11-30 18:27:16 +000061 ('builtins.float()', []),
Ben Webber35996b72017-11-26 00:17:47 +000062 # int
Anthony Sottile8626e262019-02-11 19:57:37 -080063 ('0', []),
64 ('int()', [Call('int', 1, 0)]),
Ben Webber35996b72017-11-26 00:17:47 +000065 ("int('0')", []),
Ben Webber77586762017-11-30 18:27:16 +000066 ('builtins.int()', []),
Ben Webber35996b72017-11-26 00:17:47 +000067 # list
Anthony Sottile8626e262019-02-11 19:57:37 -080068 ('[]', []),
69 ('list()', [Call('list', 1, 0)]),
Ben Webber35996b72017-11-26 00:17:47 +000070 ("list('abc')", []),
71 ("list([c for c in 'abc'])", []),
72 ("list(c for c in 'abc')", []),
Ben Webber77586762017-11-30 18:27:16 +000073 ('builtins.list()', []),
Ben Webber35996b72017-11-26 00:17:47 +000074 # str
75 ("''", []),
Anthony Sottile8626e262019-02-11 19:57:37 -080076 ('str()', [Call('str', 1, 0)]),
Ben Webber35996b72017-11-26 00:17:47 +000077 ("str('0')", []),
Ben Webber77586762017-11-30 18:27:16 +000078 ('builtins.str()', []),
Ben Webber35996b72017-11-26 00:17:47 +000079 # tuple
Anthony Sottile8626e262019-02-11 19:57:37 -080080 ('()', []),
81 ('tuple()', [Call('tuple', 1, 0)]),
Ben Webber35996b72017-11-26 00:17:47 +000082 ("tuple('abc')", []),
83 ("tuple([c for c in 'abc'])", []),
84 ("tuple(c for c in 'abc')", []),
Ben Webber77586762017-11-30 18:27:16 +000085 ('builtins.tuple()', []),
Ben Webber35996b72017-11-26 00:17:47 +000086 ],
87)
88def test_non_dict_exprs(visitor, expression, calls):
89 visitor.visit(ast.parse(expression))
90 assert visitor.builtin_type_calls == calls
91
92
93@pytest.mark.parametrize(
94 ('expression', 'calls'),
95 [
Anthony Sottile8626e262019-02-11 19:57:37 -080096 ('{}', []),
97 ('dict()', [Call('dict', 1, 0)]),
98 ('dict(a=1, b=2, c=3)', []),
Ben Webber35996b72017-11-26 00:17:47 +000099 ("dict(**{'a': 1, 'b': 2, 'c': 3})", []),
100 ("dict([(k, v) for k, v in [('a', 1), ('b', 2), ('c', 3)]])", []),
101 ("dict((k, v) for k, v in [('a', 1), ('b', 2), ('c', 3)])", []),
Ben Webber77586762017-11-30 18:27:16 +0000102 ('builtins.dict()', []),
Ben Webber35996b72017-11-26 00:17:47 +0000103 ],
104)
105def test_dict_allow_kwargs_exprs(visitor, expression, calls):
106 visitor.visit(ast.parse(expression))
107 assert visitor.builtin_type_calls == calls
108
109
110@pytest.mark.parametrize(
111 ('expression', 'calls'),
112 [
Anthony Sottile8626e262019-02-11 19:57:37 -0800113 ('dict()', [Call('dict', 1, 0)]),
114 ('dict(a=1, b=2, c=3)', [Call('dict', 1, 0)]),
Anthony Sottile45756522019-02-11 19:56:15 -0800115 ("dict(**{'a': 1, 'b': 2, 'c': 3})", [Call('dict', 1, 0)]),
Ben Webber77586762017-11-30 18:27:16 +0000116 ('builtins.dict()', []),
Ben Webber35996b72017-11-26 00:17:47 +0000117 ],
118)
119def test_dict_no_allow_kwargs_exprs(expression, calls):
Anthony Sottile45756522019-02-11 19:56:15 -0800120 visitor = Visitor(allow_dict_kwargs=False)
Ben Webber35996b72017-11-26 00:17:47 +0000121 visitor.visit(ast.parse(expression))
122 assert visitor.builtin_type_calls == calls
123
124
125def test_ignore_constructors():
Anthony Sottilefea76b92020-02-03 08:41:48 -0800126 visitor = Visitor(
127 ignore=('complex', 'dict', 'float', 'int', 'list', 'str', 'tuple'),
128 )
Anthony Sottile030bfac2019-01-31 19:19:10 -0800129 visitor.visit(ast.parse(BUILTIN_CONSTRUCTORS))
Ben Webber35996b72017-11-26 00:17:47 +0000130 assert visitor.builtin_type_calls == []
131
132
Anthony Sottile030bfac2019-01-31 19:19:10 -0800133def test_failing_file(tmpdir):
134 f = tmpdir.join('f.py')
135 f.write(BUILTIN_CONSTRUCTORS)
Max Rozentsveygf35bfed2020-05-20 12:07:45 -0400136 rc = main([str(f)])
Ben Webber35996b72017-11-26 00:17:47 +0000137 assert rc == 1
138
139
Anthony Sottile030bfac2019-01-31 19:19:10 -0800140def test_passing_file(tmpdir):
141 f = tmpdir.join('f.py')
142 f.write(BUILTIN_LITERALS)
Max Rozentsveygf35bfed2020-05-20 12:07:45 -0400143 rc = main([str(f)])
Ben Webber35996b72017-11-26 00:17:47 +0000144 assert rc == 0
145
146
Anthony Sottile030bfac2019-01-31 19:19:10 -0800147def test_failing_file_ignore_all(tmpdir):
148 f = tmpdir.join('f.py')
149 f.write(BUILTIN_CONSTRUCTORS)
Max Rozentsveygf35bfed2020-05-20 12:07:45 -0400150 rc = main(['--ignore=complex,dict,float,int,list,str,tuple', str(f)])
Ben Webber35996b72017-11-26 00:17:47 +0000151 assert rc == 0