Skip to content

Commit bf49259

Browse files
bcallerBen Caller
authored andcommitted
Add basic python logging to pyt with -v -vv -vvv
Very basic python logging added to pyt. Very useful when you want to see: - which files are being processed - if your imports are not being inspected - which file crashed pyt
1 parent c07551d commit bf49259

File tree

5 files changed

+44
-10
lines changed

5 files changed

+44
-10
lines changed

pyt/__main__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""The comand line module of PyT."""
22

3+
import logging
34
import os
45
import sys
56
from collections import defaultdict
@@ -26,6 +27,8 @@
2627
is_function_without_leading_
2728
)
2829

30+
log = logging.getLogger(__name__)
31+
2932

3033
def discover_files(targets, excluded_files, recursive=False):
3134
included_files = list()
@@ -37,11 +40,13 @@ def discover_files(targets, excluded_files, recursive=False):
3740
if file.endswith('.py') and file not in excluded_list:
3841
fullpath = os.path.join(root, file)
3942
included_files.append(fullpath)
43+
log.debug('Discovered file: %s', fullpath)
4044
if not recursive:
4145
break
4246
else:
4347
if target not in excluded_list:
4448
included_files.append(target)
49+
log.debug('Discovered file: %s', target)
4550
return included_files
4651

4752

@@ -60,6 +65,14 @@ def retrieve_nosec_lines(
6065
def main(command_line_args=sys.argv[1:]): # noqa: C901
6166
args = parse_args(command_line_args)
6267

68+
logging_level = (
69+
logging.ERROR if not args.verbose else
70+
logging.WARN if args.verbose == 1 else
71+
logging.INFO if args.verbose == 2 else
72+
logging.DEBUG
73+
)
74+
logging.basicConfig(level=logging_level, format='[%(levelname)s] %(name)s: %(message)s')
75+
6376
files = discover_files(
6477
args.targets,
6578
args.excluded_paths,
@@ -74,6 +87,7 @@ def main(command_line_args=sys.argv[1:]): # noqa: C901
7487

7588
cfg_list = list()
7689
for path in sorted(files):
90+
log.info("Processing %s", path)
7791
if not args.ignore_nosec:
7892
nosec_lines[path] = retrieve_nosec_lines(path)
7993

pyt/cfg/stmt_visitor.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import ast
22
import itertools
3+
import logging
34
import os.path
5+
from pkgutil import iter_modules
46

57
from .alias_helper import (
68
as_alias_handler,
@@ -52,6 +54,9 @@
5254
remove_breaks
5355
)
5456

57+
log = logging.getLogger(__name__)
58+
uninspectable_modules = {module.name for module in iter_modules()} # Don't warn about failing to import these
59+
5560

5661
class StmtVisitor(ast.NodeVisitor):
5762
def __init__(self, allow_local_directory_imports=True):
@@ -429,9 +434,12 @@ def visit_Assign(self, node):
429434
else:
430435
label = LabelVisitor()
431436
label.visit(node)
432-
print('Assignment not properly handled.',
433-
'Could result in not finding a vulnerability.',
434-
'Assignment:', label.result)
437+
log.warn(
438+
'Assignment not properly handled in %s. Could result in not finding a vulnerability.'
439+
'Assignment: %s',
440+
getattr(self, 'filenames', ['?'])[0],
441+
self.label.result,
442+
)
435443
return self.append_node(AssignmentNode(
436444
label.result,
437445
label.result,
@@ -1022,6 +1030,10 @@ def visit_Import(self, node):
10221030
name.asname,
10231031
retrieve_import_alias_mapping(node.names)
10241032
)
1033+
for alias in node.names:
1034+
if alias.name not in uninspectable_modules:
1035+
log.warn("Cannot inspect module %s", alias.name)
1036+
uninspectable_modules.add(alias.name) # Don't repeatedly warn about this
10251037
return IgnoredNode()
10261038

10271039
def visit_ImportFrom(self, node):
@@ -1061,4 +1073,7 @@ def visit_ImportFrom(self, node):
10611073
retrieve_import_alias_mapping(node.names),
10621074
from_from=True
10631075
)
1076+
if node.module not in uninspectable_modules:
1077+
log.warn("Cannot inspect module %s", node.module)
1078+
uninspectable_modules.add(node.module)
10641079
return IgnoredNode()

pyt/core/ast_helper.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@
22
Useful when working with the ast module."""
33

44
import ast
5+
import logging
56
import os
67
import subprocess
78
from functools import lru_cache
89

910
from .transformer import PytTransformer
1011

11-
12+
log = logging.getLogger(__name__)
1213
BLACK_LISTED_CALL_NAMES = ['self']
1314
recursive = False
1415

1516

1617
def _convert_to_3(path): # pragma: no cover
1718
"""Convert python 2 file to python 3."""
1819
try:
19-
print('##### Trying to convert file to Python 3. #####')
20+
log.warn('##### Trying to convert %s to Python 3. #####', path)
2021
subprocess.call(['2to3', '-w', path])
2122
except subprocess.SubprocessError:
22-
print('Check if 2to3 is installed. '
23-
'https://docs.python.org/2/library/2to3.html')
23+
log.exception('Check if 2to3 is installed. https://docs.python.org/2/library/2to3.html')
2424
exit(1)
2525

2626

pyt/usage.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ def _add_required_group(parser):
3030

3131
def _add_optional_group(parser):
3232
optional_group = parser.add_argument_group('optional arguments')
33-
33+
optional_group.add_argument(
34+
'-v', '--verbose',
35+
action='count',
36+
help='Increase logging verbosity. Can repeated e.g. -vvv',
37+
)
3438
optional_group.add_argument(
3539
'-a', '--adaptor',
3640
help='Choose a web framework adaptor: '

tests/usage_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_no_args(self):
2525

2626
self.maxDiff = None
2727

28-
EXPECTED = """usage: python -m pyt [-h] [-a ADAPTOR] [-pr PROJECT_ROOT]
28+
EXPECTED = """usage: python -m pyt [-h] [-v] [-a ADAPTOR] [-pr PROJECT_ROOT]
2929
[-b BASELINE_JSON_FILE] [-t TRIGGER_WORD_FILE]
3030
[-m BLACKBOX_MAPPING_FILE] [-i] [-o OUTPUT_FILE]
3131
[--ignore-nosec] [-r] [-x EXCLUDED_PATHS]
@@ -36,6 +36,7 @@ def test_no_args(self):
3636
targets source file(s) or directory(s) to be scanned
3737
3838
optional arguments:
39+
-v, --verbose Increase logging verbosity. Can repeated e.g. -vvv
3940
-a ADAPTOR, --adaptor ADAPTOR
4041
Choose a web framework adaptor: Flask(Default),
4142
Django, Every or Pylons
@@ -74,7 +75,7 @@ def test_valid_args_but_no_targets(self):
7475
with capture_sys_output() as (_, stderr):
7576
parse_args(['-j'])
7677

77-
EXPECTED = """usage: python -m pyt [-h] [-a ADAPTOR] [-pr PROJECT_ROOT]
78+
EXPECTED = """usage: python -m pyt [-h] [-v] [-a ADAPTOR] [-pr PROJECT_ROOT]
7879
[-b BASELINE_JSON_FILE] [-t TRIGGER_WORD_FILE]
7980
[-m BLACKBOX_MAPPING_FILE] [-i] [-o OUTPUT_FILE]
8081
[--ignore-nosec] [-r] [-x EXCLUDED_PATHS]

0 commit comments

Comments
 (0)