Kodi Community Forum

Full Version: GSoC 2018 - Add code validation and do static code analysis in Kodi's add-on checker
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
I am Gobinath a graduate student at Western University, Canada willing to get experience with Kodi and more Python coding standards. I developed a code quality analyzer for Java during my internship which was a good opportunity to learn the best practices and possible bugs in Java. Even though I use Python, I am not well familiar with Python standards. I find this project as an opportunity to learn more coding standards and best practices in Python.

1. Tell us about the computer(s) and devices you have available for working on your SoC project?
I have a Laptop with Linux Mint 18.3, i7 processor and 8 GB RAM and an Android phone (which I guess not necessary for this project)

2. When did you first start programming?
I started programming in early 2006 with Visual Basic 6. Then I switched to VB.Net, C#.Net and finally Java.
I would say I can code anything in Java but depending on requirements I choose the language.
Nowadays I use Python for my university projects and research.

3. Are you a user of Kodi? When did you first start using it?
Personally I have not use Kodi in my computer. However, I watch movies in my friend's Android box on Kodi.

4. Have you contributed to other Open Source projects? If so, which projects and can we see some of your code?
I participated in GSoC 2017 and coded for WSO2 an open source middleware company. For more details and pull requests: GSoC: Siddhi Pattern to detect absence of events

I also maintain few open source projects:
Safe Eyes - A Free and Open Source Linux alternative to EyeLeo
libreoffice-code-highlighter - A LibreOffice addon for code highlighting
Google Calendar Desklet - A Cinnamon desklet to show Google calendar events on your desktop
uget-chrome-wrapper - Integrate uGet Download manager with your favorite web browser

5. What sorts of programming projects have you done on your own time?
Listed above. Programming is my hobby. If an existing software does not meet my requirement and if I have time, I will write my own.

6. How much time do you have available, and how would you plan to use it?
7. Do you plan to have a job or study during the summer in conjunction with Summer of Code?
I like to answer both together. As a graduate student I do not have summer holiday. However I have successfully completed my last GSoC under the same scenario last year.
If you are looking for quantitative answer, I would say 20 hours per week on average.

Could you please let me know where to start and more detailed expected outcomes.
1. What is the targeted Python version?
2. What are the code metrics you are interested on?
3. How to test the existing addon implementation?

(2018-02-21, 04:56)gobinath Wrote: [ -> ]Could you please let me know where to start and more detailed expected outcomes.
1. What is the targeted Python version?
2. What are the code metrics you are interested on?
3. How to test the existing addon implementation?
Hey Smile

You can find the current version of the addon checker here: https://github.com/xbmc/addon-check
1. At the moment it is checking python2 code but will need to be python3 ready, at least during 2019.
2. Well metric wise we're interested in everything that helps the devs and the PR reviewers. We haven't spend much time to figure that out yet.
3. You can run the code listed above against one of our repos. Or just grab the repo code and resolve the submodule. Be sure to grab a branch like https://github.com/xbmc/repo-plugins/tree/krypton you can then find the submodule code in ".tests". I normally run it in vscode or just via commandline. You should be able to just say "py addon_check.py" or something like that, I don't have my environment with me right now.
So best would be to check out the current base and trying to find out how to extend it in the most meaningful way.

Thank you for the details. I have successfully run the check-addon against krypton repo-plugin.

According to my knowledge, pylint and/or pyflake can be used for code analysis. I hope I can come up with a configurable solution that can handle both Python 2 and 3. I will research more on it and update you.

Well metric wise we're interested in everything that helps the devs and the PR reviewers

I will look for available tools and list all possible metrices we can collect.

After analyzing the current code, I find it easy to extend by adding some more functions to test Python code. However, I think it is a good time to consider the maintainability of "addon-check". Adding all functions into a single script "check_addon.py" may cause to lack of readability and maintainability in future. Shall I also come up with a more structured design for addon-check?

Sure, if you think the approach doesn't scale. At the moment those two classes are mainly due to the two usecases:
- Run it against a repo via check_repo.py (what we or a third party would do on their servers)
- Run it against a single addon via check_addon.py (what you would do locally if you want to push your addon and make sure it is in a good shape)
I have listed some well-known tools to analyze Python 2 & 3 code:

Pylint is a well-known code analyzer which checks code style based on PEP8 guidelines and errors to an here.extend. All possible messages can be found

PyFlake is faster than Pylint because it only checks for syntax tree but not the style. Developers of PyFlake recommends Flake8 for those who want to check PEP8 styles in addition.

[b]pycodestyle (formerly pep8)[/b]
This tool checks the style conventions according toPEP8 guidelines.

Flake8 is a wrapper which uses pycodestyle and pyflake and mccabe.

Mccabe used in flake8 checks only cyclomatic complexity. Radon checks more metrics which can be useful to make decisions on the quality of the code:
  • Cyclomatic Complexity
  • Maintainability Index
  • LOC: the total number of lines of code
  • LLOC: the number of logical lines of code
  • SLOC: the number of source lines of code
  • Number of comments
  • Number of multi-line comments
  • Number of blank lines
I find both Pylint and Flake8 as tough competitors. Running both on same Python file generates different reports with some overlaps. Therefore, I propose a configurable addon_check plugin where the developer must be able to choose the linter to use. Of course, we can provide a default configuration. Flake 8 provides more flexible API to be used as a Python library. On the other hand, the API exposed by Pylint is not rich enough so we need to do some post-processing. In addition, supporting Radon is a must regardless of Pylint or Flake8.
Therefore my proposal is: implementing code validation and static code analysis in Kodi’s add-on checker without tight dependency with any  linters
I will implement three separate modules as part of add-on checker to use Pylint, Flake8, and Radon which can be enabled/disabled with parameters/configuration. These modules will be configurable to support all command line arguments of their respective tools. In the process of this implementation, I will structure the current addon_checker.py more modulus without losing current functionalities so that you can extend it for different checkers in future.

Please provide your opinion on this draft proposal. If you find it as the way to go, I will work on finalizing the proposal and a prototype to demonstrate the proposed solution.

In the current implementation, add-on checker prints the report in plain text. When it comes to code analysis, single Python script may have plenty of issues. In such scenario, what is your expected output format?

Well personally I don't see the point in making it able to run multiple checkers. It's nice if we choose the wrong default to be able to easily change, but I feel that's a lot of work for something that might never happen. Which should free up quiet some time to improve the implementation or spend it on other things not related to code checks.

Well output format should probably still be text with an option to do markdown (for github comments)
Then I prefer to use Flake8. For report, I will go with the text and markdown.
If others are okay, may I start working on finalyzing the proposal and a prototype?

(2018-02-25, 16:22)gobinath Wrote: [ -> ]Then I prefer to use Flake8. For report, I will go with the text and markdown.
If others are okay, may I start working on finalyzing the proposal and a prototype?

 Sounds like a plan.

Please find the my flake8 prototype implementation at https://github.com/slgobinath/pycode-analyzer.
This code calls Flake8 Python API from test_flake8.py script against two Python scripts (one my own script, other one was taken from  plugin.audio.detektorfm).
We can configure flake8 using its command line parameters but I have not include them in this prototype. Please provide your feedback for this implementation.

One limitation of flake8 (and pylint too) is we should run it using same Python version of the code to analyze. So if the source code is written in Python 2, flake8 must be installed for Python 2.
My script is written using Python 3.

Having it to match the version is going to be a very very serious problem for us. Not sure how to overcome that.
Implementation looks good, but obviously very basic. I will have to look into flake8 what it can actually do and how configurable it is.
The Flake 8 API does not offer a fancy API but I beleive it has all we need. The get_style_guide method accepts all command line parameters listed here: http://flake8.pycqa.org/en/latest/manpage.html
Therefore it won't be complex at the code level. The parameters can be defined in tests-config.json file which I will include once I start actual implementation.
Quote:Having it to match the version is going to be a very very serious problem for us

I agree with you. In my testings, pylint also has such a limitation. For example, both of them reported Python 2 print statement as error in Python 3 environment.
To the best of my knowledge, we may need to create two add-ons one for Python 2 and one for Python 3.
Well is it only python 2 vs python 3 or is it also python 2.6 vs python 2.7?
It does require specific Python minor version if we are interested in changes specific to the minor version. However, according to my knowledge, minor versions do not change syntax (or less chance). Instead, there can be changes in modules and their APIs.

Flake 8 reports most of the best practice violations which are common for all Python versions. One important error message E999 [1] is reported if Flake 8 is failed to build a syntax tree of a given Python source file. This happens if there is a syntax error in Python script. This is where Python major version is important. If Flake 8 is running on Python 3, it will fail to build syntax tree for Python 2. Same happens on the other way too. I ran Flake 8 (installed for Python 3) against repo-plugins[2] and got the following list of E999 errors. Instead of error messages, I have listed sed commands to see the actual lines categorized into error types. (There was an inconsistent use of tabs and spaces in indentation issue which I have ignored here).

Print (print 'hello' in Python 2 but print('hello') in Python 3)
sed -n 47p ./plugin.video.fsgo/resources/lib/fsgo.py
sed -n 118p ./plugin.video.mmlive/resources/globals.py
sed -n 345p ./plugin.video.ustvnow/resources/lib/ustvnow.py
sed -n 1987p ./plugin.video.iplayerwww/resources/lib/ipwww_video.py
sed -n 312p ./plugin.video.catchuptvandmore/addon.py
sed -n 21p ./plugin.video.charge/resources/lib/scraper.py
sed -n 52p ./plugin.video.nfl.gamepass/resources/lib/pigskin.py
sed -n 31p ./plugin.video.mediathek/default.py
sed -n 131p ./plugin.video.mediathek/mediathek/wdr.py
sed -n 176p ./plugin.video.mediathek/mediathek/ndr.py
sed -n 53p ./plugin.video.montreal.greek-tv/addon.py
sed -n 136p ./plugin.audio.lastfmtube/default.py
sed -n 63p ./plugin.video.spurs-tv/resources/lib/youtube.py

Comma in except (except urllib2.URLError, e: in Python 2 but except urllib2.URLError as e: in Python 3)
sed -n 142p ./plugin.video.tvvn/tvvn.py
sed -n 47p ./plugin.video.revision3/resources/lib/generalutils.py
sed -n 24p ./plugin.video.iplayerwww/default.py
sed -n 117p ./plugin.video.playonbrowser/default.py
sed -n 140p ./plugin.video.ispot/default.py
sed -n 60p ./plugin.video.nfl.gamepass/default.py
sed -n 83p ./plugin.video.newsmaxtv/resources/lib/newsmaxtv.py
sed -n 896p ./plugin.video.embycon/resources/lib/websocket.py
sed -n 240p ./plugin.video.embycon/resources/lib/downloadutils.py
sed -n 83p ./plugin.video.skynews/resources/lib/skynews.py
sed -n 136p ./plugin.video.plutotv/resources/lib/plutotv.py
sed -n 84p ./plugin.video.massengeschmack/resources/lib/__init__.py
sed -n 84p ./plugin.video.newsy/resources/lib/newsy.py

Octal syntax mismatch (0777 in Python 2 but 0o777 in Python 3)
sed -n 80p ./plugin.video.catchuptvandmore/resources/lib/utils.py

As you can see all are due to syntax changes introduced in Python 3. Therefore, I believe making two add-ons for Python 2 and 3, will solve this problem.


[1] http://flake8.pycqa.org/en/latest/user/error-codes.html
[2] https://github.com/xbmc/repo-plugins.git
Yes, we will need at least two implentations then and need it to be configurable in our addon-checker, which it should use.
Today I came across this GitHub issue: #45: Think about creating a pip package from this while writing my proposal. In fact, I had this idea and wanted to discuss with you.
I have experience in publishing Python 3 package to pypi. Though I do not have hands-on experience in publishing the same package for Python 2 and 3, it is possible to do so [1]. There are Python applications available for both Python 2 and 3 and users can pick either of them by using pip2 or pip3.

For example, assuming kodi-add-on-checker is the package name, if a developer installs our addon using the following command, it will verify Python 3 scripts:
sudo pip3 install kodi - add-on -checker
On the other hand, if he/she installs it using pip2, it will verify Python 2 scripts.

It will overcome our version specific problem discussed in last thread with a cost of maintaining two separate add-on checkers. Since the current implementation is in Python 3, I can implement Python 3 code analyzer first and publish it to pip. Later, depending on available time, I can migrate the code to Python 2.
If maintaining two versions of add-on checker is not a good idea, the only workaround I can think about is writing a standalone script for Python 2 with flake8, execute it using Python 2 from add-on checker and read its standard output.

If you agree on this, my milestone deliverables will be:
  1. Python 3 code analyzer
    • Use Flake8
    • Flake 8 parameters must be configurable
    • Print Flake8 report to the console
    • Implement support for markdown report generation
  2. Upload Python 3 add-on checker to pypi
  3. Migrate Python 3 code to Python 2
  4. Upload Python 2 add-on checker to pypi

I have few more questions:
  1. How would you like to pass flake8 related configurations to add-on checker? Via command-line parameters or .tests-config.json?
  2. Can I share the Google Doc link to my draft proposal here (is it okay to share in public)?


[1] https://stackoverflow.com/a/43851706/4382663
Pages: 1 2 3