-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a copyright checker as a pylint plugin #4577
Conversation
Also modify existing Python files that violate the copyright checking.
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
It is required by the copyright checker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for opening this! This is a good looking change. Few high level comments.
# | ||
# -*- coding: utf-8 -*- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are these coding: utf-8 entries for ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think it is needed (anymore), but it is originally in the head. That line violates the copyright checking rule. Therefore, I move it here, below the copyright. We can delete it if it is of no use. There are also other files sharing the same situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original entry in the first line complies with Python's standard of declaring the source file encoding. However, the default encoding of Python 3 has become utf-8. Therefore, the declarations in this project are unnecessary. I will remove all such comments in the next commit. If we need them back, they can also be unrolled. Some autogenerated files (such as *_pb2.py) also have this line in the beginning. I will not touch them.
for (lineno, line) in enumerate(stream): | ||
if lineno >= len(golden): | ||
break | ||
|
||
if lineno == 0: | ||
# Use Regex to accept various years such as 2018 and 2021. | ||
if not re.compile(golden[0]).match(line): | ||
self.add_message("wrong-copyright-notice", line=1) | ||
break | ||
elif line.rstrip() != golden[lineno]: | ||
self.add_message("wrong-copyright-notice", line=lineno + 1) | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can probably tighten this up a bit with:
for expected_line, (lineno, line) in zip(golden, enumerate(stream)):
if not re.match(expected_line, line):
self.add_message("wrong-copyright-notice", line=lineno + 1)
break
And use regex on every line so that we can replace doing rstrip() and lstrip() equality checks with something more like: ^expected stuff$
. Also, a quick look at the API for add_message and I think we might be able to add a col_offset
as well so the user knows what column the disagreement is on as well as the line number (this might make using regex hard).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the suggestions. Indeed, it would be difficult to use Regex to report a position. I looked for some ways (such as this). They all seem too complex for this task. I am also worried about the performance since running pylint on the whole project already takes quite a long time. Therefore, I choose to use plain byte comparison, which might be stricter than regex solutions. However, it is probably fine. For example, there is no point to have some whitespaces before the #
. Nevertheless, the right part of a line should have more flexibility. For example, Windows and Linux have different line endings and whitespaces cannot been seen in the editor. Therefore, I apply strip()
to the part of the file line longer than the template. As long as the longer part consists of only whitespace, it will be allowed.
Unfortunately, the test utility provided by pylint does not support the col_offset
feature. Therefore, it is not tested in the test file. I have tried it with several different cases manually, and it works as expected.
@@ -13,4 +13,5 @@ cd "$(git rev-parse --show-toplevel)" | |||
|
|||
CIRQ_MODULES=$(env PYTHONPATH=. python dev_tools/modules.py list --mode package-path) | |||
|
|||
pylint --rcfile=dev_tools/conf/.pylintrc $@ $CIRQ_MODULES dev_tools examples |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to add this change to pylint-incremental
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Added it.
pylint~=2.6.0 | ||
astroid<2.5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like pylint already has this here: https://github.com/PyCQA/pylint/blob/2.6/pylint/__pkginfo__.py#L43
Do we need this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not have this in commit 6a2937a, which fails the CI process. The report says E ModuleNotFoundError: No module named 'astroid'
. Maybe adding this can solve this problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like that failure is caused by pylint not getting explicitly installed. That CI test triggers this dev_tools/conf/pip-install-minimal-for-pytest-changed-files.sh
. Which does not include the pylint install which is now a requirement for dev tools testing. With that in mind I would suggest we try adding a line like -r pylint.txt
to pytest.txt
with a comment explaining that in order to test this custom plugin, we need pylint installed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. So in the new commit, I added -r pylint.txt
to pip-install-minimal-for-pytest-changed-files.sh
and removed astroid
from pylint.txt
. Hope it works :)
@@ -1,5 +1,3 @@ | |||
# -*- coding: utf-8 -*- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note this line: coding: utf8-8
Also remove some encoding declarations.
Let's have |
Automerge cancelled: A required status check is not present. Missing statuses: ['cla/google'] |
Thanks. It triggers the CI, and the cla check passed! |
Automerge cancelled: A required status check is not present. Missing statuses: ['Build docs', 'Build protos', 'Changed files test', 'Coverage check', 'Doc test', 'Format check', 'Lint check', 'Misc check', 'Notebook formatting', 'Pytest MacOS (3.7)', 'Pytest MacOS (3.8)', 'Pytest MacOS (3.9)', 'Pytest Ubuntu (3.7)', 'Pytest Ubuntu (3.8)', 'Pytest Ubuntu (3.9)', 'Pytest Windows (3.7)', 'Pytest Windows (3.8)', 'Pytest Windows (3.9)', 'Type check', 'Typescript lint check', 'Typescript tests', 'Typescript tests coverage'] |
Automerge cancelled: Merging is blocked (I don't understand why). |
@yjt98765 Merged. Thanks for your patience! |
This PR implements a pylint checker that automatically checks the copyright notice at the beginning of a python file. This task is proposed in [Issue 4564](quantumlib#4564). The PR consists of the following parts: 1. The implemented pylint checker (dev_tools/pylint_copyright_checker.py) and its test file (dev_tools/pylint_copyright_checker_test.py). The checker reports a message with id "R0001" if there is no copyright notice or the notice does not conform to the standard one. The letter 'R' represents refactoring. The checking can be disabled in the file with pragma `# pylint: disable=wrong-copyright-notice` 2. Modification of pylint-related files (check/pylint, check/pylint-changed-files, dev_tools/conf/.pylintrc) to integrate the new checker into the workflow. 3. Python files that failed in this check. Some copyright notices were wrong (e.g. cirq-core/cirq/circuits/circuit_dag.py and cirq-core/cirq/ops/qubit_order_test.py), and they are corrected. Some files did not have a copyright notice. In this case, the "disable" pragma is added. Note that not all the files need to have a copyright notice, [probably](https://softwareengineering.stackexchange.com/a/19653/322605). After the modification, these files can pass pylint checking again.
This PR implements a pylint checker that automatically checks the copyright notice at the beginning of a python file. This task is proposed in [Issue 4564](quantumlib#4564). The PR consists of the following parts: 1. The implemented pylint checker (dev_tools/pylint_copyright_checker.py) and its test file (dev_tools/pylint_copyright_checker_test.py). The checker reports a message with id "R0001" if there is no copyright notice or the notice does not conform to the standard one. The letter 'R' represents refactoring. The checking can be disabled in the file with pragma `# pylint: disable=wrong-copyright-notice` 2. Modification of pylint-related files (check/pylint, check/pylint-changed-files, dev_tools/conf/.pylintrc) to integrate the new checker into the workflow. 3. Python files that failed in this check. Some copyright notices were wrong (e.g. cirq-core/cirq/circuits/circuit_dag.py and cirq-core/cirq/ops/qubit_order_test.py), and they are corrected. Some files did not have a copyright notice. In this case, the "disable" pragma is added. Note that not all the files need to have a copyright notice, [probably](https://softwareengineering.stackexchange.com/a/19653/322605). After the modification, these files can pass pylint checking again.
This PR implements a pylint checker that automatically checks the copyright notice at the beginning of a python file. This task is proposed in [Issue 4564](quantumlib#4564). The PR consists of the following parts: 1. The implemented pylint checker (dev_tools/pylint_copyright_checker.py) and its test file (dev_tools/pylint_copyright_checker_test.py). The checker reports a message with id "R0001" if there is no copyright notice or the notice does not conform to the standard one. The letter 'R' represents refactoring. The checking can be disabled in the file with pragma `# pylint: disable=wrong-copyright-notice` 2. Modification of pylint-related files (check/pylint, check/pylint-changed-files, dev_tools/conf/.pylintrc) to integrate the new checker into the workflow. 3. Python files that failed in this check. Some copyright notices were wrong (e.g. cirq-core/cirq/circuits/circuit_dag.py and cirq-core/cirq/ops/qubit_order_test.py), and they are corrected. Some files did not have a copyright notice. In this case, the "disable" pragma is added. Note that not all the files need to have a copyright notice, [probably](https://softwareengineering.stackexchange.com/a/19653/322605). After the modification, these files can pass pylint checking again.
This PR implements a pylint checker that automatically checks the copyright notice at the beginning of a python file. This task is proposed in Issue 4564.
The PR consists of the following parts:
# pylint: disable=wrong-copyright-notice