guilatrova / tryceratops

A linter to prevent exception handling antipatterns in Python (limited only for those who like dinosaurs).
MIT License
427 stars 25 forks source link

Crash when the code analysed is unparseable #30

Closed Pierre-Sassoulas closed 2 years ago

Pierre-Sassoulas commented 2 years ago

Hello, thank you for this tool, I appreciate it.

I encountered a crash on some code with git artifact not removed:

Traceback (most recent call last):
  File "/home/psassoulas/.cache/pre-commit/repo1clg70g2/py_env-python3/lib/python3.8/site-packages/tryceratops/files/discovery.py", line 54, in _parse_python_files_from_dir
    parsed, filefilter = parse_file(filename)
  File "/home/psassoulas/.cache/pre-commit/repo1clg70g2/py_env-python3/lib/python3.8/site-packages/tryceratops/files/parser.py", line 42, in parse_file
    tree = parse_tree(content)
  File "/home/psassoulas/.cache/pre-commit/repo1clg70g2/py_env-python3/lib/python3.8/site-packages/tryceratops/files/parser.py", line 37, in parse_tree
    return ast.parse(content.read())
  File "/usr/lib/python3.8/ast.py", line 47, in parse
    return compile(source, filename, mode, flags,
  File "<unknown>", line 74
    <<<<<<< Updated upstream
guilatrova commented 2 years ago

Hey! Thanks for trying Tryceratops! Can you share more info? The steps to reproduce the bug, or maybe a repo with this state to help me digging deeper?

Pierre-Sassoulas commented 2 years ago

Sorry for not providing a snippet, I think this would do:

<<<<<<< Updated upstream
guilatrova commented 2 years ago

I'll check it later this week! (Probably on the weekend)

guilatrova commented 2 years ago

Sorry for the long response.

I just tested and I couldn't find a crash. The current behavior is intended.

Steps to reproduce

  1. Add <<<<<<< Updated upstream to any Python file
  2. Run tryceratops on the dir (e.g. tryceratops src/tests/samples/violations/)
  3. See output:
Failed to parse file src/tests/samples/violations/call_too_many_try.py, skipping it
Traceback (most recent call last):
  File "/Users/guilhermelatrova/guilatrova/tryceratops/src/tryceratops/files/discovery.py", line 54, in _parse_python_files_from_dir
    parsed, filefilter = parse_file(filename)
  File "/Users/guilhermelatrova/guilatrova/tryceratops/src/tryceratops/files/parser.py", line 42, in parse_file
    tree = parse_tree(content)
  File "/Users/guilhermelatrova/guilatrova/tryceratops/src/tryceratops/files/parser.py", line 37, in parse_tree
    return ast.parse(content.read())
  File "/usr/local/Cellar/python@3.9/3.9.7_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ast.py", line 50, in parse
    return compile(source, filename, mode, flags,
  File "<unknown>", line 20
    <<<<<<< Updated upstream
    ^
SyntaxError: invalid syntax
[TC400] Use logging '.exception' instead of '.error' - src/tests/samples/violations/except_prefer_log_method.py:16:8
[TC201] Simply use 'raise' without specifying exception object again - src/tests/samples/violations/except_reraise_no_cause.py:23:8
[TC200] Use 'raise from' to specify exception cause - src/tests/samples/violations/except_reraise_no_cause.py:16:8
[TC003] Avoid specifying long messages outside the exception class - src/tests/samples/violations/call_raise_long_str.py:17:8
[TC201] Simply use 'raise' without specifying exception object again - src/tests/samples/violations/call_raise_long_str.py:29:8
[TC202] You're ignoring a broad exception without even logging - src/tests/samples/violations/except_pass.py:18:8
[TC202] You're ignoring a broad exception without even logging - src/tests/samples/violations/except_pass.py:27:8
[TC202] You're ignoring a broad exception without even logging - src/tests/samples/violations/except_pass.py:35:12
[TC201] Simply use 'raise' without specifying exception object again - src/tests/samples/violations/except_verbose_reraise.py:20:8
[TC201] Simply use 'raise' without specifying exception object again - src/tests/samples/violations/except_verbose_reraise.py:28:12
[TC401] Do not log exception object, give context instead - src/tests/samples/violations/log_object.py:16:40
[TC401] Do not log exception object, give context instead - src/tests/samples/violations/log_object.py:23:47
[TC401] Do not log exception object, give context instead - src/tests/samples/violations/log_object.py:30:40
[TC300] Consider moving this statement to an 'else' block - src/tests/samples/violations/try_consider_else.py:20:8
[TC003] Avoid specifying long messages outside the exception class - src/tests/samples/violations/call_raise_vanilla.py:13:8
[TC201] Simply use 'raise' without specifying exception object again - src/tests/samples/violations/call_raise_vanilla.py:21:8
[TC002] Create your own exception - src/tests/samples/violations/call_raise_vanilla.py:13:8
[TC400] Use logging '.exception' instead of '.error' - src/tests/samples/violations/log_error.py:15:8
[TC301] Abstract raise to an inner function - src/tests/samples/violations/try_inner_raise.py:21:12
[TC301] Abstract raise to an inner function - src/tests/samples/violations/try_inner_raise.py:35:8
Done processing! 🦖✨
Processed 12 files
Found 20 violations
Failed to process 1 files

If Tryceratops can't parse the Python file, it's impossible to assess the file.

The behavior is similar to how black works:

 black src/tests/samples/violations/call_too_many_try.py
error: cannot format src/tests/samples/violations/call_too_many_try.py: Cannot parse: 20:4:     <<<<<<< Updated upstream
Oh no! 💥 💔 💥
1 file failed to reformat.
# Error code: 123