Trailing Comments
February 23, 2021
Today’s exercise is based on a blog entry that Reddit pointed me to. Sean is trying to write a program that finds lines of code in his Python programs that have trailing comments at the ends of lines, which he considers bad style. His naive program improperly flagged a line as containing a trailing comment when the comment marker is embedded in a quoted string:
x = "# This is fine"
"This \# is fine too"
x = "" # This is not
Sean gets a little bit sidetracked in his blog entry, and never quite solves the problem; I’m not convinced the code he writes is correct (though he seems to think it is), and I’m also not convinced that trailing comments are a bad thing. Nevertheless, the task makes an interesting exercise, especially when we also handle quoted escape sequences.
Your task is to write a program that identifies lines of code with trailing comments. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
@programmingpraxis, I believe the solution you posted considers full comment lines (those starting with a “#”, possibly preceded by whitespace) as trailing comments. For example, the line
# comment
would seemingly be counted as a trailing comment. Have I interpreted your code correctly, and should there be a distinction between 1) full comment lines and 2) lines that have code followed by a comment? I’ve assumed that a trailing comment detector would only detect the latter.Here’s a solution in Python, which takes a Python file as input and outputs the line numbers with trailing comments. I’ve utilized Python’s built-in tokenize module. This accommodates comment markers in either single or double quoted strings, and also handles trailing comments that occur at the end of multi-line strings after the triple quotes.
Example usage:
[sourcode lang=”text”]
x = ‘# this is not a trailing comment’
“this # is not part of a trailing comment”
x = “” # this is a trailing comment
this is not (full comment line)
x = “””
:-) # this multi-line string text is not part of a trailing comment
“”” # this text is
[/sourcecode]
[sourcode lang=”text”]
$ python3 trailing_comments.py example.py
[/sourcecode]
Output:
I misspelled “sourcecode” in my example usage. Here’s another attempt.
Example usage:
x = ‘# this is not a trailing comment’
"this # is not part of a trailing comment"
x = "" # this is a trailing comment
# this is not (full comment line)
x = """
:-) # this multi-line string text is not part of a trailing comment
""" # this text is
$ python3 trailing_comments.py example.py
Output:
Another attempt.
x = ‘# this is not a trailing comment’
"this # is not part of a trailing comment"
x = "" # this is a trailing comment
# this is not (full comment line)
x = """
:-) # this multi-line string text is not part of a trailing comment
""" # this text is
$ python3 trailing_comments.py example.py
Output:
A last attempt to correct formatting of my example usage.
Output:
A solution in Racket:
Test source code file, trailing-comments.py:
Testing:
Here is my take on this using Julia 1.5: https://pastebin.com/afzBbauw
This solution works with a single line, but it’s not too difficult to adapt it to run on a whole program. Cheers