mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
a82bfa0e7e
The | syntax for unions is only supported in Python 3.10 and later. Since Python 3.8 and 3.9 are still supported upstream for a while and we had a user reporting on IRC that they couldn't use the stub file since they are using 3.8, change to the old syntax for unions to support this. There aren't really any drawbacks of this. It's just a bit more verbose, and a typing import is necessary, but neither of those really matters in a generated stub file.
108 lines
3.3 KiB
Python
Executable File
108 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2019 Simmo Saan <simmo.saan@gmail.com>
|
|
# Copyright (C) 2021-2023 Sébastien Helleu <flashcode@flashtux.org>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
"""
|
|
Generate Python stub: API constants and functions, with type annotations.
|
|
|
|
This script requires Python 3.6+.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from textwrap import indent
|
|
|
|
import re
|
|
|
|
DOC_DIR = Path(__file__).resolve().parent / "en"
|
|
SRC_DIR = Path(__file__).resolve().parent.parent / "src"
|
|
|
|
STUB_HEADER = """\
|
|
#
|
|
# WeeChat Python stub file, auto-generated by python_stub.py.
|
|
# DO NOT EDIT BY HAND!
|
|
#
|
|
|
|
from typing import Dict, Union
|
|
"""
|
|
|
|
CONSTANT_RE = (
|
|
r"( |\|) `(?P<constant>WEECHAT_[A-Z0-9_]+)` "
|
|
r"\((?P<type>(string|integer))\)(?: \+)?"
|
|
)
|
|
|
|
FUNCTION_RE = r"""\[source,python\]
|
|
----
|
|
# prototype
|
|
def (?P<function>\w+)(?P<args>[^)]*)(?P<return>\) -> [^:]+:) \.\.\.(?P<example>.*?)
|
|
----"""
|
|
|
|
|
|
def print_stub_constants() -> None:
|
|
"""Print constants, extracted from the Scripting guide."""
|
|
types = {
|
|
"integer": "int",
|
|
"string": "str",
|
|
}
|
|
constant_pattern = re.compile(CONSTANT_RE)
|
|
with open(
|
|
DOC_DIR / "weechat_scripting.en.adoc", encoding="utf-8"
|
|
) as scripting_file, open(
|
|
SRC_DIR / "plugins" / "weechat-plugin.h", encoding="utf-8"
|
|
) as plugin_header_file:
|
|
scripting = scripting_file.read()
|
|
plugin_header = plugin_header_file.read()
|
|
for match in constant_pattern.finditer(scripting):
|
|
value_re = rf'^#define {match["constant"]} +(?P<value>[\w"-]+)$'
|
|
value_match = re.search(value_re, plugin_header, re.MULTILINE)
|
|
value = f' = {value_match["value"]}' if value_match else ""
|
|
|
|
print(f'{match["constant"]}: {types[match["type"]]}{value}')
|
|
|
|
|
|
def print_stub_functions() -> None:
|
|
"""Print function prototypes, extracted from the Plugin API reference."""
|
|
function_pattern = re.compile(FUNCTION_RE, re.DOTALL)
|
|
with open(DOC_DIR / "weechat_plugin_api.en.adoc",
|
|
encoding="utf-8") as api_doc_file:
|
|
api_doc = api_doc_file.read()
|
|
for match in function_pattern.finditer(api_doc):
|
|
url = f'https://weechat.org/doc/weechat/api/#_{match["function"]}'
|
|
example = (
|
|
f'\n ::\n\n{indent(match["example"].lstrip(), " " * 8)}'
|
|
if match["example"]
|
|
else ""
|
|
)
|
|
print(
|
|
f"""\n
|
|
def {match["function"]}{match["args"]}{match["return"]}
|
|
\"""`{match["function"]} in WeeChat plugin API reference <{url}>`_{example}
|
|
\"""
|
|
..."""
|
|
)
|
|
|
|
|
|
def stub_api() -> None:
|
|
"""Write Python stub file."""
|
|
print(STUB_HEADER)
|
|
print_stub_constants()
|
|
print_stub_functions()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
stub_api()
|