DelphiVCL4Python
DelphiVCL4Python copied to clipboard
Development of Stubs with Delphi Documentation
I used the delphivcl
library in the development of a commercial application and tired of searching in the Delphi documentation for the signature of class members, I started building the stub file containing the complete signature of the internal class members, as well as their documentation.
I know that stubs for delphivcl
and delphifmx
are under development, and my goal here is to contribute to the current work. The official stubs provided with the delphivcl
and delphifmx
packages do not contain the complete list of functions and methods, and most importantly, they have not yet extracted all the existing documentation in Delphi.
To facilitate the review of the stub I developed with the official stub, I organized the definition of the classes following the order of the official stub.
I also started merging specific class members from the Python packages, that is, the properties, methods, and built-in functions of the delphivcl
and delphifmx
modules.
An example of the merge I made can be seen below, a set of specific Python symbols.
__hash__: ClassVar[None] = ...
def __contains__(self, other) -> bool:
def __delattr__(self, name) -> Any:
def __eq__(self, other) -> bool:
def __ge__(self, other) -> bool:
def __getitem__(self, index) -> Any:
def __gt__(self, other) -> bool:
def __iter__(self) -> Any:
def __le__(self, other) -> bool:
def __len__(self) -> int:
def __lt__(self, other) -> bool:
def __ne__(self, other) -> bool:
def __setattr__(self, name, value) -> Any:
I am currently sharing only the delphivcl
stub because, as mentioned earlier, it is necessary to merge specific Python class members and make numerous other adjustments.
EXISTING ISSUES
Type Hint
I converted the Delphi documentation to Python class stubs while developing a commercial application. At that time, I had not yet studied the typing library, and due to deadlines in delivering the work, I gradually developed it without using the correct type hints notation.
The initial goal was to speed up the discovery of the notation of the internal members of the classes, especially since I constantly needed to use Delphi's Code Complete to be able to write Python code.
Unlike the official stub where the event method declaration is written using mainly type hints, I developed the stub with the intention of preserving the entire notation of the function and method signatures, including preserving the parameter names and their type names.
The stub I developed can be considered the full text of the official documentation, even preserving tables, links, and examples in Delphi and C++.
The only change in the text of the official documentation was the removal of the T prefix from the class names. I tried to use the official naming of the delphivcl
and delphifmx
libraries.
As an example, below you can see the difference between the official stub and the stub I developed. The first code snippet is the declaration of the OnMouseDown
method contained in the official stub, and following it is the declaration of the same method in my stub.
# Official stub
OnMouseDown: Callable[[Object,MouseButton,ShiftState,int,int],None]
"""Callable[[Object, MouseButton, ShiftState, int, int], None]:"""
# Stub I developed
def OnMouseDown(self, Sender: Object, Button: MouseButton, Shift: ShiftState, X: int, Y: int) -> None:
'''
# OnMouseDown: MouseEvent
Occurs when the user presses a mouse button with the mouse pointer over a control.
Use the `OnMouseDown <Vcl.Controls.Control.OnMouseDown.htm>`__ event handler to implement any special processing that should occur as a result of pressing a mouse button.
The `OnMouseDown <Vcl.Controls.Control.OnMouseDown.htm>`__ event handler can respond to *left*, *right*, or *center* mouse button presses and *Shift* key plus mouse-button combinations. *Shift* keys are the *Shift*, *Ctrl*, and *Alt* keys. ``'X'`` and ``'Y'`` are the pixel coordinates of the mouse pointer in the client area of the ``Sender``.
`OnMouseDown <Vcl.Controls.Control.OnMouseDown.htm>`__ is an event handler of type `Vcl.Controls.MouseEvent <Vcl.Controls.MouseEvent.htm>`__.
'''
CLASS METHODS
My stub has not yet defined the @classmethod
decorator existing in the official stub.
PRINCIPLE USED IN STUB CONSTRUCTION
The delphivcl 1.0.5 contains 140 classes, the official stub, contained in the delphivcl
package, has 138 class notations defined, while my stub has 287 declared classes!
A significant portion of the 287 defined class definitions does not contain any notations in the internal members; the goal was to provide the definition and documentation of classes used, for example, in property types or in the type of parameters of a function or method.
As initially stated, the goal when building the stub was to provide notations and documentation from the Python code editor. No standards or techniques for writing stub files were used in development. Even so, the result obtained from the PyCharm IDE was excellent; the editor flags issues when trying to invoke methods and functions with different numbers of parameters or values than those defined in the stub.
Below is a screenshot of how PyCharm displays the method signature, as well as its documentation when hovering over a particular function.
Therefore, declaring so many classes in the stub file is the way to provide, in addition to the classes and their members contained in the packages.
PyCharm finds approximately 1000 errors in the declarations of the official stub, in defining the types used in the definitions of the internal members of the classes.
There is another reason why I chose to define all these classes: to prevent the interpreter from reporting hundreds of errors when it cannot find the types of the class members, preventing us from locating other types of problems, such as syntax errors.
The images below show the errors reported by PyCharm for the official stub.
It is important to say that issues reported by PyCharm do not interfere with the proper functioning of the stub! Code Complete, for example, works perfectly, returning the names of the internal members of the classes, as well as their signatures.
Even though there is no problem with the operation of the stub, the truth is that such errors are reported because there are missing class definitions, which are often the types of the members in the signature of properties, functions, or methods. Therefore, there is a reason to define such classes within the stub.
Previously, the method OnMouseDown
was used as an example. The method signature has 2 typed parameters: MouseButton
, ShiftState
.
In both types, we basically find the valid options that the parameter supports. When such types are not defined in the stub, it becomes necessary to search the official documentation or to discover the options through debugging.
Below is the definition of the MouseButton
class, as well as its 3 members.
Even without using the type notation correctly, the mere existence of the existing members within the classes is already enough to understand and know the allowed options and infer their functioning.
class MouseButton:
mbLeft: ...
mbRight: ...
mbMiddle: ...
OnMouseDown: Callable[[Object,MouseButton,ShiftState,int,int],None]
def OnMouseDown(self, Sender: Object, Button: MouseButton, Shift: ShiftState, X: int, Y: int) -> None:
Finally, that is the reason why there are 287 classes in the stub file I developed, even though there are only 140 classes contained in the delphivcl
package.
TRANSLATION
Two years ago, I started translating the documentation of delphivcl
and delphifmx
into Portuguese. I found out that stub files can also be used in separating source code from documentation.
Being a stub file somewhat like a C++ header file, the Python packages used in the module and package documentation cycle (docutils, sphinx, and gettext) can be utilized, and I used them in generating the POT files.
Over the past years, I specialized in the continuous software and documentation translation cycle (internationalization), having translated several books and the documentation of more than 10 Python packages, including the complete Python documentation.
In addition to knowledge and experience with the continuous translation cycle, I developed specialized tools over time for translating technical text, and of course, I gradually trained an AI with the terminologies and jargon found in software development and programming literature in general.
It's important to mention that the use of machine translation, no matter how trained the AI may be, is only meant to speed up the work, but a sentence is marked as finished only after manual review and correction.
As can be seen in the image below, the English sentences were submitted on 10/22/2022, and the last time there were translated or marked as finished sentences was on 03/04/2024.
At this moment, the delphifmx
library has 75% of its sentences verified, and delphivcl
is 70% translated.
In other words, the documentation of delphifmx
has 10,159 sentences, practically all sentences have a translation, and 7,731 have already been verified and corrected (manually), leaving only 2,428 sentences for completion.
Screenshots of the current state of translation, the platform used for management is Transifex.
delphivcl
delphifmx