This file documents the bindings generator, not the bindings themselves. For the bindings documentation, see the README.module file.
The bindings generator generates ctypes-bindings from the include files defining the public API. The same generated module should be compatible with various versions of libvlc 2.* and 3.*. However, there may be incompatible changes between major versions. Versioned bindings for 2.2 and 3.0 are provided in the repository.
The module generator is licensed under the GNU General Public License version 2 or later. The generated module is licensed, like libvlc, under the GNU Lesser General Public License 2.1 or later.
You can get the latest version of the code generator from https://github.com/oaubert/python-vlc/ or https://git.videolan.org/?p=vlc/bindings/python.git.
The code expects to be placed inside a VLC source tree, in vlc/bindings/python, so that it finds the development include files, or to find the installed include files in /usr/include (on Debian, install libvlc-dev).
Once you have cloned the project, you can run
python3 dev_setup.sh
from the root directory (or the python version if on a platform without shell)
This script will install everything that is needed (submodules, virtual environment, treesitter, packages, etc.) for you to generate the bindings. Then, activate the virtual environment:
- On Linux with Bash:
. .venv/bin/activate
- On Windows with Powershell:
.\.venv\Scripts\Activate.ps1
See https://docs.python.org/3/library/venv.html#how-venvs-work for other os-shell combinations.
To generate the vlc.py module and its documentation, for both the
development version and the installed VLC version, use make
.
The Makefile tries to convert files from either ../../include/vlc
(i.e. if the code is placed as a bindings/pyton
in the VLC source
tree) or /usr/include/vlc
.
For running tests, use make test
.
Note that you need vlc installed because some tests require the
libvlc's dynamic library to be present on the system.
If you want to generate the bindings from an installed version of the
VLC includes (which are expected to be in /usr/include/vlc), use the
'installed' target: make installed
.
See more recipes in the Makefile.
To install python-vlc for development purposes (add a symlink to your Python library) simply do
python setup.py develop
preferably inside a virtualenv. You can uninstall it later with
python setup.py develop --uninstall
Documentation building needs sphinx. An online build is available at https://python-vlc.readthedocs.io/en/latest/
The generated module version number is built from the VLC version number and the generator version number:
vlc_major.vlc_minor.(1000 * vlc_micro + 100 * generator_major + generator_minor)
so that it shared it major.minor with the corresponding VLC.
To generate the reference PyPI module (including setup.py, examples and metadata files), use
make dist
First of all, the bindings generator is in generator/generate.py.
It really is the conjunction of two things:
- A parser of C header files (those of libvlc): that is the class
Parser
. - A generator of Python bindings: that is the class
PythonGenerator
.
Parser
parses libvlc's headers and produces a kind of AST where nodes are
instances of either Struct
, Union
, Func
, Par
, Enum
or Val
.
The information kept is what is necessary for PythonGenerator
to then produce
the bindings.
Until version 2 of the bindings generator, parsing was regex-based. It worked pretty well thanks to the consistent coding style of libvlc. However, it remained rather fragile.
Since version 2, parsing is done using Tree-sitter.
More specifically, we use the C Tree-sitter grammar
and Tree-sitter's Python bindings.
It offers a more complete and robust parsing of C code.
The job of Parser
is thus to transform the AST1 produced by Tree-sitter into an "AST"
understandable by the generator.
python-vlc is part of the LibVLC Discord Community server. Feel free to come say hi!
Contributions such as:
- reporting and fixing bugs,
- contributing unit tests
- contributing examples
are welcome!
Footnotes
-
To be exact, it produces a CST: Concrete Syntax Tree. ↩