@@ -35,22 +35,16 @@ def _is_posix():
3535# ==============================================================================
3636
3737
38- def _is_os_system_call (node ):
38+ def _is_function_call (node , module , function ):
3939 return (
4040 isinstance (node .func , astroid .Attribute )
4141 and isinstance (node .func .expr , astroid .Name )
42- and node .func .expr .name == 'os'
43- and node .func .attrname == 'system'
42+ and node .func .expr .name == module
43+ and node .func .attrname == function
4444 )
4545
4646
47- def _is_os_popen_call (node ):
48- return (
49- isinstance (node .func , astroid .Attribute )
50- and isinstance (node .func .expr , astroid .Name )
51- and node .func .expr .name == 'os'
52- and node .func .attrname == 'popen'
53- )
47+ # ------------------------------------------------------------------------------
5448
5549
5650def _is_os_path_call (node ):
@@ -95,37 +89,27 @@ def _is_builtin_open_for_writing(node):
9589 return False
9690
9791
98- def _is_os_open (node ):
99- return (
100- isinstance (node .func , astroid .Attribute )
101- and isinstance (node .func .expr , astroid .Name )
102- and node .func .attrname == 'open'
103- and node .func .expr .name == 'os'
104- )
105-
106-
10792def _is_os_open_allowed_mode (node , allowed_modes ):
108- if _is_os_open (node ):
109- mode = None
110- flags = None # pylint: disable=unused-variable
111- if len (node .args ) > 1 and isinstance (node .args [1 ], (astroid .Attribute , astroid .BinOp )):
112- # Cover:
113- # * os.open(xxx, os.O_WRONLY)
114- # * os.open(xxx, os.O_WRONLY | os.O_CREATE)
115- # * os.open(xxx, os.O_WRONLY | os.O_CREATE | os.O_FSYNC)
116- flags = node .args [1 ]
117- if len (node .args ) > 2 and isinstance (node .args [2 ], astroid .Const ):
118- mode = node .args [2 ].value
119- elif node .keywords :
120- for keyword in node .keywords :
121- if keyword .arg == 'flags' :
122- flags = keyword .value # pylint: disable=unused-variable # noqa: F841
123- if keyword .arg == 'mode' :
124- mode = keyword .value .value
125- break
126- if mode is not None :
127- # TODO: condition check on the flags value if present (ie. ignore if read-only)
128- return mode in allowed_modes
93+ mode = None
94+ flags = None # pylint: disable=unused-variable
95+ if len (node .args ) > 1 and isinstance (node .args [1 ], (astroid .Attribute , astroid .BinOp )):
96+ # Cover:
97+ # * os.open(xxx, os.O_WRONLY)
98+ # * os.open(xxx, os.O_WRONLY | os.O_CREATE)
99+ # * os.open(xxx, os.O_WRONLY | os.O_CREATE | os.O_FSYNC)
100+ flags = node .args [1 ]
101+ if len (node .args ) > 2 and isinstance (node .args [2 ], astroid .Const ):
102+ mode = node .args [2 ].value
103+ elif node .keywords :
104+ for keyword in node .keywords :
105+ if keyword .arg == 'flags' :
106+ flags = keyword .value # pylint: disable=unused-variable # noqa: F841
107+ if keyword .arg == 'mode' :
108+ mode = keyword .value .value
109+ break
110+ if mode is not None :
111+ # TODO: condition check on the flags value if present (ie. ignore if read-only)
112+ return mode in allowed_modes
129113
130114 # NB: default to True in all other cases
131115 return True
@@ -236,26 +220,6 @@ def _is_yaml_unsafe_call(node):
236220 return False
237221
238222
239- def _is_jsonpickle_encode_call (node ):
240- if isinstance (node .func , astroid .Attribute ):
241- if (
242- isinstance (node .func .expr , astroid .Name )
243- and node .func .expr .name == 'jsonpickle'
244- and node .func .attrname == 'decode'
245- ):
246- return True
247- return False
248-
249-
250- def _is_shlex_quote_call (node ):
251- return (
252- isinstance (node .func , astroid .Attribute )
253- and isinstance (node .func .expr , astroid .Name )
254- and node .func .expr .name == 'shlex'
255- and node .func .attrname == 'quote'
256- )
257-
258-
259223# ==============================================================================
260224
261225
@@ -366,24 +330,24 @@ def visit_call(self, node):
366330 self .add_message ('replace-mktemp' , node = node )
367331 elif _is_yaml_unsafe_call (node ):
368332 self .add_message ('avoid-yaml-unsafe-load' , node = node )
369- elif _is_jsonpickle_encode_call (node ):
333+ elif _is_function_call (node , module = 'jsonpickle' , function = 'decode' ):
370334 self .add_message ('avoid-jsonpickle-decode' , node = node )
371- elif _is_os_system_call (node ):
335+ elif _is_function_call (node , module = 'os' , function = 'system' ):
372336 self .add_message ('avoid-os-system' , node = node )
373337 elif _is_os_path_call (node ):
374338 self .add_message ('replace-os-relpath-abspath' , node = node )
375339 elif _is_shell_true_call (node ):
376340 self .add_message ('avoid-shell-true' , node = node )
377- elif _is_os_popen_call (node ):
341+ elif _is_function_call (node , module = 'os' , function = 'popen' ):
378342 self .add_message ('avoid-os-popen' , node = node )
379343 elif _is_builtin_open_for_writing (node ) and self ._prefer_os_open :
380344 self .add_message ('replace-builtin-open' , node = node )
381345 elif isinstance (node .func , astroid .Name ) and (node .func .name in ('eval' , 'exec' )):
382346 self .add_message ('avoid-eval-exec' , node = node )
383- elif not _is_posix () and _is_shlex_quote_call (node ):
347+ elif not _is_posix () and _is_function_call (node , module = 'shlex' , function = 'quote' ):
384348 self .add_message ('avoid-shlex-quote-on-non-posix' , node = node )
385349 elif (
386- _is_os_open (node )
350+ _is_function_call (node , module = 'os' , function = 'open' )
387351 and self ._prefer_os_open
388352 and not _is_os_open_allowed_mode (node , self ._os_open_modes_allowed )
389353 ):
@@ -425,7 +389,9 @@ def visit_with(self, node):
425389 if item and isinstance (item [0 ], astroid .Call ):
426390 if _is_builtin_open_for_writing (item [0 ]):
427391 self .add_message ('replace-builtin-open' , node = node )
428- elif _is_os_open (item [0 ]) and not _is_os_open_allowed_mode (item [0 ], self ._os_open_modes_allowed ):
392+ elif _is_function_call (item [0 ], module = 'os' , function = 'open' ) and not _is_os_open_allowed_mode (
393+ item [0 ], self ._os_open_modes_allowed
394+ ):
429395 self .add_message ('os-open-unsafe-permissions' , node = node )
430396
431397 def visit_assert (self , node ):
0 commit comments