mirror of
https://github.com/ModOrganizer2/pystubs-generation.git
synced 2026-07-27 14:07:13 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41b5672069 | ||
|
|
49a77592f9 | ||
|
|
6fe9b1d569 | ||
|
|
dd80b67a0a | ||
|
|
8789b59f23 |
@@ -18,12 +18,13 @@ jobs:
|
||||
python-version: 3.12
|
||||
- uses: abatilo/actions-poetry@v2
|
||||
- name: Install
|
||||
run: |
|
||||
poetry install
|
||||
run: poetry install
|
||||
- name: Install libgl1
|
||||
run: sudo apt install -y libgl1 libegl1 libglib2.0-0 libxkbcommon0 libdbus-1-3
|
||||
- name: Copy stubs
|
||||
run: cp stubs/2.5.2/mobase-stubs/__init__.pyi docs/mobase.py
|
||||
run: |
|
||||
mkdir -p docs/src
|
||||
cp -r stubs/2.5.2/mobase-stubs docs/src/mobase
|
||||
- name: Build
|
||||
run: poetry run sphinx-build -b html docs/source docs/build
|
||||
env:
|
||||
@@ -109,7 +109,6 @@ import mobase
|
||||
import mobase.widgets
|
||||
```
|
||||
|
||||
|
||||
**Note:** Most classes in `mobase` cannot be instantiated, so this is mostly intended
|
||||
for MO2 developers.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
sphinx-rtd-theme
|
||||
sphinx-autodoc-typehints
|
||||
sphinx-automodapi
|
||||
PyQt6
|
||||
+5
-1
@@ -27,8 +27,9 @@ extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx_autodoc_typehints",
|
||||
"sphinx.ext.napoleon",
|
||||
"autoapi.extension",
|
||||
# "sphinx.ext.autosummary",
|
||||
"sphinx_automodapi.automodapi",
|
||||
# "sphinx_automodapi.automodapi",
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
@@ -39,6 +40,9 @@ templates_path = ["_templates"]
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = []
|
||||
|
||||
autoapi_dirs = ["../src"]
|
||||
autoapi_member_order = "groupwise"
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ This documentation is dedicated to writting MO2 **Python** plugins.
|
||||
plugin-types
|
||||
writing-plugins
|
||||
faq
|
||||
mobase
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
``mobase`` API
|
||||
==============
|
||||
|
||||
.. currentmodule:: mobase
|
||||
|
||||
.. automodapi:: mobase
|
||||
:no-inheritance-diagram:
|
||||
:no-heading:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
@@ -1,7 +0,0 @@
|
||||
mobase
|
||||
======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
mobase
|
||||
@@ -64,10 +64,8 @@ These plugins (shall eventually) implement all the game specific features and fu
|
||||
able to add support for further games.
|
||||
The plugin is also responsible to help MO determine if (and where) the game is installed in the first place.
|
||||
Since supporting a game properly requires extensions in many places of the UI.
|
||||
To allow this without creating one huge plugin interface that involves every aspect of MO, game plugins
|
||||
expose a *feature list*.
|
||||
The list of possible features can be found in the "game_features" project and each feature can itself be
|
||||
considered a plugin interface.
|
||||
To allow this without creating one huge plugin interface that involves every aspect of MO,
|
||||
game plugins can register only the features they need to MO2 using :meth:`registerFeature<mobase.IGameFeatures.registerFeature>`
|
||||
|
||||
As an example for a game feature take BSA invalidation: If the game requires BSA invalidation it will implement
|
||||
this feature.
|
||||
@@ -147,4 +145,4 @@ File Mappings
|
||||
|
||||
This interface allows plugins to add virtual file (or directory) links to the virtual file system in addition to the
|
||||
mod files.
|
||||
Profile-local save games, ini-files and load-orders are all implemented this way in MO2.
|
||||
Profile-local save games, ini-files and load-orders are all implemented this way in MO2.
|
||||
|
||||
Generated
+32
-1
@@ -11,6 +11,17 @@ files = [
|
||||
{file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "3.3.1"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
optional = false
|
||||
python-versions = ">=3.9.0"
|
||||
files = [
|
||||
{file = "astroid-3.3.1-py3-none-any.whl", hash = "sha256:a1a30b911ef8d74988c2a3a59d55ddf9cb973382f115479e213752a4fad36c7c"},
|
||||
{file = "astroid-3.3.1.tar.gz", hash = "sha256:98eb59d8b92d141d618f92435407cbcd5c12dc9f5f4f0c5570fc2e4ba4ddc6aa"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "babel"
|
||||
version = "2.16.0"
|
||||
@@ -567,6 +578,26 @@ docs = ["sphinxcontrib-websupport"]
|
||||
lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"]
|
||||
test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx-autoapi"
|
||||
version = "3.2.1"
|
||||
description = "Sphinx API documentation generator"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "sphinx_autoapi-3.2.1-py2.py3-none-any.whl", hash = "sha256:72fe556abc579528a46494f4fcbeaeaaf3e0b031f6514f7b496f6c36754c5430"},
|
||||
{file = "sphinx_autoapi-3.2.1.tar.gz", hash = "sha256:1f9d56b3a98d5653d1fad5644abeed2c042cec304a126ef72c236dae4af16b90"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
astroid = {version = ">=3.0.0a1", markers = "python_version >= \"3.12\""}
|
||||
Jinja2 = "*"
|
||||
PyYAML = "*"
|
||||
sphinx = ">=6.1.0"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "sphinx", "sphinx-design"]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx-autodoc-typehints"
|
||||
version = "2.2.3"
|
||||
@@ -784,4 +815,4 @@ zstd = ["zstandard (>=0.18.0)"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "a84158bffbc4f7ac0d6e8c9f8009d42abeb97bf648db79efd613c1bd9d455b69"
|
||||
content-hash = "97106de296f79cfdd92e616a411bccc7677d7dbe6f84be55e85093e9550b80fa"
|
||||
|
||||
@@ -27,6 +27,7 @@ sphinx-rtd-theme = "^2.0.0"
|
||||
sphinx-autodoc-typehints = "^2.2.3"
|
||||
sphinx-automodapi = "^0.17.0"
|
||||
sphinx = "<8"
|
||||
sphinx-autoapi = "^3.2.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
|
||||
@@ -8,7 +8,7 @@ from pathlib import Path
|
||||
from typing import Callable
|
||||
|
||||
from .loader import load_mobase
|
||||
from .mtypes import Class, Constant, PyTyping
|
||||
from .mtypes import Class, Constant, Enum, Function, PyTyping
|
||||
from .parser import is_enum
|
||||
from .register import MobaseRegister
|
||||
from .utils import Settings, clean_class
|
||||
@@ -146,6 +146,8 @@ def main() -> None:
|
||||
[
|
||||
# the "real" IPlugin is IPluginBase
|
||||
"IPlugin",
|
||||
# this is deprecated
|
||||
"PluginSetting",
|
||||
],
|
||||
),
|
||||
"mobase.widgets": extract_objects(mobase.widgets), # type: ignore
|
||||
@@ -171,6 +173,9 @@ def main() -> None:
|
||||
# Create the corresponding object:
|
||||
c = register.make_object(n, o)
|
||||
|
||||
for n, _o in objects:
|
||||
c = register.get_object(n)
|
||||
|
||||
if isinstance(c, Class):
|
||||
# Clean the class (e.g., remove duplicates methods due to wrappers):
|
||||
clean_class(c)
|
||||
@@ -198,6 +203,21 @@ def main() -> None:
|
||||
# create directory if required
|
||||
output_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# sort the stubs
|
||||
def _key_fn(o: Class | Constant | list[Function] | PyTyping) -> tuple[int, ...]:
|
||||
# order is PyTyping -> Constant -> Function -> Enum -> Top-Level Class -> Child Level Classes
|
||||
return (
|
||||
not isinstance(o, PyTyping),
|
||||
not isinstance(o, Constant),
|
||||
not isinstance(o, list),
|
||||
not isinstance(o, Enum),
|
||||
isinstance(o, Class) and len(o.all_bases),
|
||||
)
|
||||
|
||||
stub_objects = sorted(
|
||||
(register.get_object(n) for n, _o in objects), key=_key_fn
|
||||
)
|
||||
|
||||
# write everything
|
||||
with open(output_folder.joinpath("__init__.pyi"), "w") as output:
|
||||
writer = Writer(package=name, output=output, settings=settings)
|
||||
@@ -208,10 +228,7 @@ def main() -> None:
|
||||
|
||||
module_headers[name](writer)
|
||||
|
||||
for n, _o in objects:
|
||||
# Get the corresponding object:
|
||||
c = register.get_object(n)
|
||||
|
||||
for c in stub_objects:
|
||||
writer.print_object(c)
|
||||
|
||||
subprocess.run(
|
||||
|
||||
@@ -33,7 +33,7 @@ def load_mobase(path: os.PathLike[Any]) -> Module:
|
||||
os.add_dll_directory(str(path.joinpath("dlls"))) # type: ignore
|
||||
|
||||
# We need to add plugins/data to sys.path, mainly for PyQt6
|
||||
sys.path.insert(1, path.joinpath("plugins", "plugin_python", "libs").as_posix())
|
||||
sys.path.insert(1, path.joinpath("proxies", "python", "libs").as_posix())
|
||||
|
||||
import mobase # type: ignore
|
||||
|
||||
|
||||
@@ -234,6 +234,8 @@ def make_class(e: type, register: MobaseRegister) -> Class:
|
||||
# members to exclude
|
||||
EXCLUDED_MEMBERS = [
|
||||
"__init_subclass__",
|
||||
"__dict__",
|
||||
"__doc__",
|
||||
"__module__",
|
||||
"__subclasshook__",
|
||||
"__hash__",
|
||||
@@ -346,7 +348,7 @@ def make_class(e: type, register: MobaseRegister) -> Class:
|
||||
|
||||
direct_bases: list[Class] = []
|
||||
for c in e.__bases__:
|
||||
if c.__module__ != "pybind11_builtins":
|
||||
if c.__module__ not in ("pybind11_builtins", "builtins"):
|
||||
b = register.get_object(c.__name__)
|
||||
assert isinstance(b, Class)
|
||||
direct_bases.append(b)
|
||||
|
||||
+1718
-1525
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,17 @@ class TaskDialog:
|
||||
Customizable choice dialog.
|
||||
"""
|
||||
|
||||
def __init__(self: TaskDialog, parent: PyQt6.QtWidgets.QWidget | None = None, title: str = '', main: str = '', content: str = '', details: str = '', icon: PyQt6.QtWidgets.QMessageBox.Icon = PyQt6.QtWidgets.QMessageBox.Icon.NoIcon, buttons: list[TaskDialogButton] = [], remember: Union[str, tuple[str, str]] = '') -> None:
|
||||
def __init__(
|
||||
self: TaskDialog,
|
||||
parent: PyQt6.QtWidgets.QWidget | None = None,
|
||||
title: str = "",
|
||||
main: str = "",
|
||||
content: str = "",
|
||||
details: str = "",
|
||||
icon: PyQt6.QtWidgets.QMessageBox.Icon = PyQt6.QtWidgets.QMessageBox.Icon.NoIcon,
|
||||
buttons: list[TaskDialogButton] = [],
|
||||
remember: Union[str, tuple[str, str]] = "",
|
||||
) -> None:
|
||||
"""
|
||||
Construct a new TaskDialog.
|
||||
|
||||
@@ -91,7 +101,7 @@ class TaskDialog:
|
||||
main: Main message of the dialog.
|
||||
"""
|
||||
...
|
||||
def setRemember(self: TaskDialog, action: str, file: str = '') -> TaskDialog:
|
||||
def setRemember(self: TaskDialog, action: str, file: str = "") -> TaskDialog:
|
||||
"""
|
||||
Configure the dialog to remember user-choice.
|
||||
"""
|
||||
@@ -113,7 +123,6 @@ class TaskDialog:
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class TaskDialogButton:
|
||||
"""
|
||||
Special button to be used inside TaskDialog widgets.
|
||||
@@ -123,19 +132,21 @@ class TaskDialogButton:
|
||||
def button(self) -> PyQt6.QtWidgets.QMessageBox.StandardButton: ...
|
||||
@button.setter
|
||||
def button(self, arg0: PyQt6.QtWidgets.QMessageBox.StandardButton) -> None: ...
|
||||
|
||||
@property
|
||||
def description(self) -> str: ...
|
||||
@description.setter
|
||||
def description(self, arg0: str) -> None: ...
|
||||
|
||||
@property
|
||||
def text(self) -> str: ...
|
||||
@text.setter
|
||||
def text(self, arg0: str) -> None: ...
|
||||
|
||||
@overload
|
||||
def __init__(self: TaskDialogButton, text: str, description: str, button: PyQt6.QtWidgets.QMessageBox.StandardButton) -> None:
|
||||
def __init__(
|
||||
self: TaskDialogButton,
|
||||
text: str,
|
||||
description: str,
|
||||
button: PyQt6.QtWidgets.QMessageBox.StandardButton,
|
||||
) -> None:
|
||||
"""
|
||||
Create a TaskDialogButton.
|
||||
|
||||
@@ -146,7 +157,11 @@ class TaskDialogButton:
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def __init__(self: TaskDialogButton, text: str, button: PyQt6.QtWidgets.QMessageBox.StandardButton) -> None:
|
||||
def __init__(
|
||||
self: TaskDialogButton,
|
||||
text: str,
|
||||
button: PyQt6.QtWidgets.QMessageBox.StandardButton,
|
||||
) -> None:
|
||||
"""
|
||||
Create a TaskDialogButton without description.
|
||||
|
||||
@@ -155,5 +170,3 @@ class TaskDialogButton:
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,172 @@
|
||||
from __future__ import annotations
|
||||
|
||||
__version__ = "2.5.2"
|
||||
|
||||
from typing import List, Tuple, Union, overload
|
||||
|
||||
import PyQt6.QtCore
|
||||
import PyQt6.QtGui
|
||||
import PyQt6.QtWidgets
|
||||
|
||||
class TaskDialog:
|
||||
"""
|
||||
Customizable choice dialog.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self: TaskDialog,
|
||||
parent: PyQt6.QtWidgets.QWidget | None = None,
|
||||
title: str = "",
|
||||
main: str = "",
|
||||
content: str = "",
|
||||
details: str = "",
|
||||
icon: PyQt6.QtWidgets.QMessageBox.Icon = PyQt6.QtWidgets.QMessageBox.Icon.NoIcon,
|
||||
buttons: list[TaskDialogButton] = [],
|
||||
remember: Union[str, tuple[str, str]] = "",
|
||||
) -> None:
|
||||
"""
|
||||
Construct a new TaskDialog.
|
||||
|
||||
Args:
|
||||
parent: Parent widget of the dialog.
|
||||
title: Title of the dialog.
|
||||
main: Header of the dialog (big text at the top).
|
||||
content: Main message of the dialog (text below main).
|
||||
details: Details for the dialog, initially collapsed (bottom of the dialog).
|
||||
icon: Icon for the dialog.
|
||||
buttons: List of buttons for the dialog.
|
||||
remember: Remember the choice for this dialog.
|
||||
"""
|
||||
...
|
||||
def addButton(self: TaskDialog, button: TaskDialogButton) -> TaskDialog:
|
||||
"""
|
||||
Add a custom button to this TaskDialog.
|
||||
|
||||
Args:
|
||||
button: Button to add to the dialog.
|
||||
"""
|
||||
...
|
||||
def addContent(self: TaskDialog, widget: PyQt6.QtWidgets.QWidget) -> None:
|
||||
"""
|
||||
Add a custom widget content to this TaskDialog. Widget content are put between
|
||||
content and buttons (above buttons).
|
||||
|
||||
Args:
|
||||
widget: Widget to add.
|
||||
"""
|
||||
...
|
||||
def exec(self: TaskDialog) -> PyQt6.QtWidgets.QMessageBox.StandardButton:
|
||||
"""
|
||||
Display this dialog and wait for user-interaction to return. This is a blocking
|
||||
function.
|
||||
|
||||
Returns:
|
||||
The button clicked by the user. Without custom buttons, this return Ok,
|
||||
otherwise it returns the button set in the TaskDialogButton.
|
||||
"""
|
||||
...
|
||||
def setContent(self: TaskDialog, content: str) -> TaskDialog:
|
||||
"""
|
||||
Set the top-level message of this dialog.
|
||||
|
||||
Args:
|
||||
content: Top-level message to set.
|
||||
"""
|
||||
...
|
||||
def setDetails(self: TaskDialog, details: str) -> TaskDialog:
|
||||
"""
|
||||
Set the details for this TaskDialog.
|
||||
|
||||
The details are hidden by default and the user can display them by clicking
|
||||
the "Details" button at the bottom of the TaskDialog.
|
||||
|
||||
Args:
|
||||
details: Details content to display. Can be a multi-line string.
|
||||
"""
|
||||
...
|
||||
def setIcon(self: TaskDialog, icon: PyQt6.QtWidgets.QMessageBox.Icon) -> TaskDialog:
|
||||
"""
|
||||
Set the icon of the dialog.
|
||||
|
||||
Args:
|
||||
icon: Icon of the dialog.
|
||||
"""
|
||||
...
|
||||
def setMain(self: TaskDialog, main: str) -> TaskDialog:
|
||||
"""
|
||||
Set the main message of the dialog. The main message is displayed at the top of
|
||||
the dialog in large font.
|
||||
|
||||
Args:
|
||||
main: Main message of the dialog.
|
||||
"""
|
||||
...
|
||||
def setRemember(self: TaskDialog, action: str, file: str = "") -> TaskDialog:
|
||||
"""
|
||||
Configure the dialog to remember user-choice.
|
||||
"""
|
||||
...
|
||||
def setTitle(self: TaskDialog, title: str) -> TaskDialog:
|
||||
"""
|
||||
Set the title of the dialog.
|
||||
|
||||
Args:
|
||||
title: Title of the dialog.
|
||||
"""
|
||||
...
|
||||
def setWidth(self: TaskDialog, width: int) -> None:
|
||||
"""
|
||||
Set the width of the dialog.
|
||||
|
||||
Args:
|
||||
width: Width of the dialog.
|
||||
"""
|
||||
...
|
||||
|
||||
class TaskDialogButton:
|
||||
"""
|
||||
Special button to be used inside TaskDialog widgets.
|
||||
"""
|
||||
|
||||
@property
|
||||
def button(self) -> PyQt6.QtWidgets.QMessageBox.StandardButton: ...
|
||||
@button.setter
|
||||
def button(self, arg0: PyQt6.QtWidgets.QMessageBox.StandardButton) -> None: ...
|
||||
@property
|
||||
def description(self) -> str: ...
|
||||
@description.setter
|
||||
def description(self, arg0: str) -> None: ...
|
||||
@property
|
||||
def text(self) -> str: ...
|
||||
@text.setter
|
||||
def text(self, arg0: str) -> None: ...
|
||||
@overload
|
||||
def __init__(
|
||||
self: TaskDialogButton,
|
||||
text: str,
|
||||
description: str,
|
||||
button: PyQt6.QtWidgets.QMessageBox.StandardButton,
|
||||
) -> None:
|
||||
"""
|
||||
Create a TaskDialogButton.
|
||||
|
||||
Args:
|
||||
text: Label of the button.
|
||||
description: Description of the button.
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def __init__(
|
||||
self: TaskDialogButton,
|
||||
text: str,
|
||||
button: PyQt6.QtWidgets.QMessageBox.StandardButton,
|
||||
) -> None:
|
||||
"""
|
||||
Create a TaskDialogButton without description.
|
||||
|
||||
Args:
|
||||
text: Label of the button.
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
"""
|
||||
...
|
||||
Reference in New Issue
Block a user