-
Notifications
You must be signed in to change notification settings - Fork 9
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
Improvement in code quality before the 0.9.x branch was forked #39
base: master
Are you sure you want to change the base?
Conversation
As long as we support Python 2.7 we have to support the different installation methods (virtualenv) for Python 3 and Python 2. For this purpose, a Makefile is added with this patch, which can be removed later when Python 2.7 is no longer supported (in the main line). Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Some of the files in the repository have CRLF line ending other have LF ending. This patch normalizes to unix-style (LF):: find . -type f -not -path './.git*' | xargs sed -i 's/\r//g' Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Command to format the code [1]:: python -m black . Black version:: $ python -m black --version python -m black, 24.3.0 (compiled: yes) Python (CPython) 3.12.2 HINT: Black removes some u'' strings that are Unicode in Python 2.x, these had to be corrected manually. [1] https://black.readthedocs.io/en/stable/# Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This patch adds a pylint profile (.pylintrc) with the aim to have a good compromise in context of Python v2 & v3 and the status of the current implementation. To avoid having to switch off all checks in the profile, many of the issues reported by pylint were handled by using inline comments. Simple errors in the code were corrected, but only if the effect of the change was locally limited and manageable. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This patch disables issues reported by pylint in py3 that we have from the py2 compatibility. HINT: When py2 compatibility is abandoned, this commit can be reverted and the code passages can be converted to Py3. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
The idiomatic way to perform an explicit typecheck in Python is to use `isinstance(x, Y)` rather than `type(x) == Y`, `type(x) is Y`. [1] [1] https://pylint.pycqa.org/en/latest/user_guide/messages/convention/unidiomatic-typecheck.html Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Since the class `datetime.datetime` is a subclass of `datetime.date`, the `isinstance` check is not suitable if a distinction has to be made between the two classes. The `type` check is more suitable in these cases, as no further inheritance can be assumed for these two object classes and the code is also easier to read in the context of this distinction. The situation is completely different with method: - icalendar.Trigger.transformFromNative() in this method (in the Trgger class) a distinction is made between a date and a time duration. Since `datetime.date` is the base class, it is suitable for an `isinstance` check of a date object (which can be an instance of the `datetime.datetime` class as well as `datetime.date`). Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
The tests._test() function has been removed in commit b564a07 / remove obsolte code. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
The base class `vobject.base.Component` defines method's prototype by: def prettyPrint(self, level=0, tabwidth=3): ... Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
…lint (W1113) 1. When defining a keyword argument before variable positional arguments, one can end up in having multiple values passed for the aforementioned parameter in case the method is called with keyword arguments[1]. 2. In the methods: - icalender.VCalendar2_0.serialize - icalender.VTimezone.validate - icalender.VEvent.validate - icalender.VTodo.validate - icalender.VAlarm.validate - icalender.VAvailability.validate - icalender.Available.validate the "arguments-differ (W0221)" [2] message from pylint had to be disbaled. This message is a direct consequence of the "keyword-arg-before-vararg (W1113)" issue already present in the base class. 3. in method: - vcard.Photo.serialize the "signature-differs (W0222)" [3] message from pylint had to be disbaled (for same reason as mentioned in 2.) --- HINT: It is advisable to correct the parameter definitions in a follow-up PR. [1] https://pylint.pycqa.org/en/latest/user_guide/messages/warning/keyword-arg-before-vararg.html [2] https://pylint.pycqa.org/en/latest/user_guide/messages/warning/arguments-differ.html [3] https://pylint.pycqa.org/en/latest/user_guide/messages/warning/signature-differs.html Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Adding the checks to the github workflow for PRs ensures that future PRs cannot be merged before they have passed the quality gate. The tests can be carried out locally as follows (see README.md):: $ make format pylint test The github workflows do not support Python 2 versions, the py2 quality gate can therefore only be tested locally and requires a Python 2 runtime (the Makefile assumes asdf is installed / as described in the README.md):: $ make clean venv2.7 test pylint2.7 CAUTION: There are no automated tests for Python 2 on github, the downward compatible 0.9.x releases have to be tested locally !!! About tools of the quality gate =============================== - Tools such as the code formatting of black are version-dependent / new rules are implemented with each new version of the tool. To ensure that the same rules always apply to the quality gate, the versions of the tools must be pinned:: black ==24.3.0; python_version >= "3.8" # (newest) Black up from py3.8 pylint ==3.1.0; python_version >= "3.8" # (newest) Pylint up from py3.8 pylint ==1.9.5; python_version =="2.7" # old Pylint in py2.7 - Since we support Python versions that have reached their EOL (py2.7 & Py3.7) we cannot add the tools of the quality gate to every python version we want to support / see remarks about the tools below. CAUTION: Upgrading the version of one of these tools must always be done in a separate PR / could be automated by tools like Renovate or Dependabot. About Black =========== - Black is not supported in py2 and py3.7 support stopped in Black v23.7.0. Since the Black test is already executed in other Python versions, a further test in py3.7 can be omitted. - We use black started from current version 24.3.0 About Pylint ============ - py2.7: latest pylint version for py2 is pylint v1.9.5 - py3.7: since the Python test is already executed in other Python versions, a further test in py3.7 can be omitted. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
I am considering an approach where:
|
Yes, was also my intention .. when branch-point is set we have to modify gh workflow in master and in 0,9.x branch.
Is, what we already have .. vobject/.github/workflows/test.yml Lines 4 to 5 in 8f72c86
Is something I had also in mind .. but I would give it a try when 0.9.x branch has been created. / I don't want to mix to many things in this one PR.
Lets discuss in a follow up PR.
In the 0.9.x branch / was at least my intention.
Nope: see comment from above ..
A code formatted by Black v24.3.0 is not accepted by older Black versions / older versions will report errors. This is in the nature of things: the formatting rules are always improved with new versions (they are not static across all versions).
If we have forked the 0.9.x branch, then we can develop a GH workflow that installs python 3 in addition to python 2 and with python 3 you can then also use the Black test ... basically the same way I currently did it (locally) when I developed this PR. But I think these are all steps that we can take after this PR/ when we have python2 & Python 3 issues separetd in branches. The only question for me now is whether this PR is a suitable preparation for all of these follow up task. |
<...>
Yes, only after branching is complete.
The goal here is to allow easy merging of bug fixes from branch-0.9.x to master. To facilitate that, having both branches with identical, or at least, very similar styles would be helpful. On the one hand, even an older version of Black will likely have a lot of overlap with more recent versions, so there might be some value in running it. On the other hand, I don't expect to be making major changes in the 0.9.x branch, so ... manually formatting the code in a Black-latest compatible way is probably easily done.
I'm concerned that modern Black uses (or will use in future) formatting that is incompatible with Python 2.7. It might do more harm than good on the 0.9 branch at some point?
I'm mostly inclined to just merge this as is, and work out any issues in master (and/or the 0.9.x branch). I have two minor concerns about the tooling: introducing a dependency on Also keen for feedback from others .. @rsb-23? |
Yeah, we can decide later / if we see a need for tooling in the 0.9x branch we implement something :)
We do not need to upgrade Black in the master branch at the next time / BTW I don't expect any formatting issues related to the py2 vs py3 version .. I have not seen one while I was working on this PR.
I totally understand... we can replace the Makefile and asdf after this PR is merged. For now, it was a cheap and quick way to get a quick handle on the various challenges // I wanted to get started and avoid long discussions regarding the appropriate tools at this stage.
👍 |
There's also @rsb-23's PR with its use of I did a bunch of work on top of that PR also, but perhaps we can "rebase" it once this is merged, and pull in the useful changes? |
May be .. its something I had in mind, but I don't have practices and didn't know how I can reconcile the different interests of local testing with those of testing in GH workflows. We will have more build tasks later, not only those that fit a pre-commt (e.g. local build of documentation or packages) ... for this we will need a suitable tool, I don't know yet which one that will be, which is why I would like to move these discussions to dedicated threads.
The changes from your branch have a large overlap with those from this PR here ... I think it's easiest to just cherry picking after this PR ha been merged (I can assist if you want). Update: Instead of a tool that is made for pre-commit tasks we should look out for a project focused tool like one of these .. but we should discuss it in a dedicated thread :) |
@da4089 - I need a little time (1-2 days) to go through the discussion and changes.
Can we move this conversation to GitHub/discussion? It has option to _reply_ instead of _quote reply_ Since, we have 3-4 things to discuss and it will be easier to follow in threaded conversation. |
Based on this branch here I implemented a solution that uses environment managemen from Hatch, see PR on my fork:
See discussion: |
.....continued to #41 |
@return42 and @rsb-23 -- I'd like to move this forward. I'm not super-familiar with the mechanics of GitHub PRs, but .. can we work in a single branch, and get some of these cleanups applied to master, so we can merge this? Then we can break of some of these other patches for automation, etc, and apply them after the split. |
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 think for test_files/*.ics
, we should leave them as DOS-style CRLF line endings, because that's what the iCalendar/vCard specs require?
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.
This patch has already been merged
Ooops .. YES should be CRLF / sorry my fail.
PR's are nothing more than a branch .. with a comment function in GH ..
We/you can create a new branch and cherry pick commits from the branch of this PR. From this new branch we create a new PR. While cherry picking you have to slightly modify some of the patches (to solve conflicts and to remove hunks like the Makefile & GH CI).
I assume you refer to bd01503 .. / don't cherry pick. I'm not sure in detail what you want to have in the new branch (PR) .. if you need help to create the new branch & cherry picking and remove hunks ask me. |
The aim of the project is to improve the code quality before the 0.9.x branch point, before downward compatibility to python 2 is dropped in master. If it only started after the branch point, the diffs between the master branch and the 0.9.x branch would be too large to merge bug fixes downwards.
Improving code quality is an ongoing process. This PR is intended to set the basis for this: adding the checks to the github workflow for PRs ensures that future PRs cannot be merged before they have passed the quality gate.
The tests can be carried out locally as follows (see README.md)::
The github workflows do not support Python 2 versions, the py2 quality gate can therefore only be tested locally and requires a Python 2 runtime (the Makefile assumes asdf is installed / as described in the README.md)::
Caution
There are no automated tests for Python 2 on github, the downward compatible 0.9.x releases have to be tested locally !!!
About tools of the quality gate
Tools such as the code formatting of black are version-dependent / new rules are implemented with each new version of the tool. To ensure that the same rules always apply to the quality gate, the versions of the tools must be pinned::
Since we support Python versions that have reached their EOL (py2.7 & Py3.7) we cannot add the tools of the quality gate to every python version we want to support / see remarks about the tools below.
Caution
Upgrading the version of one of these tools must always be done in a separate PR / could be automated by tools like Renovate or Dependabot.
About Black
Black is not supported in py2 and py3.7 support stopped in Black v23.7.0. Since the Black test is already executed in other Python versions, a further test in py3.7 can be omitted.
We use black started from current version 24.3.0
About Pylint
py2.7: latest pylint version for py2 is pylint v1.9.5
py3.7: since the Python test is already executed in other Python versions, a further test in py3.7 can be omitted.
About linting & code quality
In order to improve the code quality of an existing code base, it is necessary to know it well and identify weak points: Pylint is the right tool for this, it tells you a lot about the code base.
Initially, a profile (a set of rules) should be found that future PRs must adhere to. These rules are defined in the
.pylintrc
, they essentially correspond to the general standards, with a few exceptions. Typically, the initial application of such a profile to an existing code base reveals many issues.The quality of these problems varies greatly and is partly determined by the project objectives (e.g. the limits of downward compatibility):
initially, only marginal changes should be made, which are manageable and guaranteed not to result in any functional changes.
Issues reported from the lint that are more far-reaching are initially deactivated via inline comments. To get a full list try:
grep '# pylint: disable=' ./*.py ./*/*.py
The latter can be successively eliminated in the following PRs. In this PR, a few thematic groupings are already made, whereby a separate PR has been set up for each topic, which sets the inline comments.
Important
Read the commit messages along this patch series carefully to understand the story behind.