qgis / QGIS-Enhancement-Proposals

QEP's (QGIS Enhancement Proposals) are used in the process of creating and discussing new enhancements for QGIS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PyQGIS linter warnings

troopa81 opened this issue · comments

Date 2024/03/12

Author Julien Cabieces (@troopa81)

Contact julien dot cabieces at oslandia dot com

maintainer @troopa81

Version QGIS 3.40

Summary

As we get closer to a fully Qt 6 support and a potential QGIS 4.0 release, plugins migrations from QGIS 3 to QGIS 4 becomes more and more important.

The migration could be painfull (as it was when switching from QGIS 2 to QGIS 3), and so this QEP proposes to smooth things out by advertising publicly plugin developers/mainteners that some modifications are highly recommended and will be required with QGIS 4.0.

To do so, this QEP proposes to:

  • Provide a static linter able to detect QGIS deprecated classes and methods
  • Provide a static linter able to detect Qt 5 deprecated classes and methods
  • Document the way to use those linters
  • Trigger those linters on the plugins.qgis.org plateform in order to inform plugin owner with current warnings

Proposed Solution

Deprecated method

For now, thanks to the SIP Deprecated annotation, a message is displayed whenever a deprecated method/class is used, but there is no easy way to find out all deprecated use in a plugin.

According to quite recent PEP 702 targeted for python version 3.13, it will be possible to add deprecated decorator to functions and classes so they could be identified statically by linter.

So far, SIP doesn't set this decorator, but we can hope it would do in the future.

Deprecated decorator needs to be added in each module pyi file for every methods/classes marked with SIP_DEPRECATED

For instance in _core.pyi file within QgsProject class

    ...
    @deprecated("deprecated since QGIS 3.2 use absoluteFilePath(), baseName() or lastModifiedTime() instead")
    def fileInfo(self) -> QtCore.QFileInfo: ...

This way, it could then be detected by linter, for instance PyRight, one of the few linter which support the PEP 702 for now.

$ pyright
deprecated_qgis.py
  deprecated_qgis.py:12:27 - error: The method "fileInfo" in class "QgsProject" is deprecated
    deprecated since QGIS 3.2 use absoluteFilePath(), baseName() or lastModifiedTime() instead (reportDeprecated)
1 error, 0 warnings, 0 informations 

How to

In order to add the deprecated decorators, it is needed to update pyi files right after their generation by SIP. To properly modify those files, it is necessary to:

  • Extract deprecated classes/methods and the associated \deprecated message from header files.
    We could use clang C++ parser python binding to extract them instead of relying on sipify script which has proven to be hard to maintain
  • Modify pyi files to add decorator on extracted classes/methods with their associated deprecated message
    ast and tokenize_rt modules can be used to modify properly the pyi in a way similar to pyqt5_to_pyqt6.py

As the deprecated decorator is still not avaible in our current python version, it's necessary to import it from typing-extensions module within pyi files

Qt 5 deprecated methods

pyqt5_to_pyqt6.py allows already to migrate python source files to be compatible with both Qt 5 and Qt 6

The script has to be modified in order to be able to only report elements needing to be fixed without actually modifying the source code, hence allowing to launch the script as a linter only.

Documentation

PyQGIS developer cookbook tips and tricks chapter needs to be updated to describe how to use the 2 linters above.

Trigger linters on plugins.qgis.org

In order to enforce migration of plugins, plugins.qgis.org automatic plugin verifications needs to integrate the 2 linters so the plateform could report the detected errors to the plugin maintainer.

Those errors are considered non blocking and doesn't prevent plugin approval. They shall be reported as warning the same way it as be done for license requirement

Affected Files

  • pyqt5_to_pyqt6.py
  • .pyi files (core, gui, server, analysis, 3d)

Performance Implications

None

Further Considerations/Improvements

Besides this proposal, we (Oslandia) also plan to update QGIS Plugin templater so it could trigger those linters in GitHub/GitLab CI. It could also serve as examples on how to correctly set up GitHub/GitLab CI for plugin maintainer who doesn't use this plugin.

Backwards Compatibility

No impact on backwards compatibility

Issue Tracking ID(s)

None

Votes

(required)