Browse Source

python: expose static AbstractPlugin properties as well.

next
Vladimír Vondruš 3 years ago
parent
commit
2fb45a91f9
  1. 20
      doc/python/conf.py
  2. 7
      doc/python/magnum.text.rst
  3. 21
      doc/python/magnum.trade.rst
  4. 1
      src/python/corrade/pluginmanager.cpp
  5. 24
      src/python/corrade/pluginmanager.h
  6. 13
      src/python/magnum/test/test_trade.py

20
doc/python/conf.py

@ -1,5 +1,6 @@
import os
import sys
from typing import List
# TODO make this less brittle
sys.path = [os.path.join(os.path.dirname(__file__), '../../build/src/python/')] + sys.path
@ -52,6 +53,25 @@ magnum.TARGET_WEBGL = DoNotPrintValue()
magnum.TARGET_EGL = DoNotPrintValue()
magnum.TARGET_VK = DoNotPrintValue()
# TODO ugh... can this be expressed directly in pybind? and the docs parsed
# from it so i don't need to repeat them in docs/*.rst files?
for i in [magnum.text.AbstractFont,
magnum.trade.AbstractImporter,
magnum.trade.AbstractImageConverter,
magnum.trade.AbstractSceneConverter]:
i.__annotations__ = {
'plugin_interface': str,
'plugin_search_paths': List[str],
'plugin_suffix': str,
'plugin_metadata_suffix': str
}
# Don't show the values. Without delattr() first it complains that the
# attribute can't be set
for key in i.__annotations__:
delattr(i, key)
setattr(i, key, DoNotPrintValue())
# TODO ugh... can this be expressed directly in pybind?
corrade.__annotations__ = {
'BUILD_DEPRECATED': bool,

7
doc/python/magnum.text.rst

@ -31,7 +31,14 @@
:ref:`AbstractFont.manager`, ensuring the manager is not deleted before the
plugin instances are.
.. TODO couldn't the plugin_interface etc. docs be parsed from pybind's docs?
repeating them for every plugin is annoying
.. py:class:: magnum.text.AbstractFont
:data plugin_interface: Plugin interface string
:data plugin_search_paths: Plugin search paths
:data plugin_suffix: Plugin suffix
:data plugin_metadata_suffix: Plugin metadata suffix
Similarly to C++, font plugins are loaded through :ref:`FontManager`:

21
doc/python/magnum.trade.rst

@ -289,7 +289,14 @@
:ref:`AbstractImporter.manager`, ensuring the manager is not deleted before
the plugin instances are.
.. TODO couldn't the plugin_interface etc. docs be parsed from pybind's docs?
repeating them for every plugin is annoying
.. py:class:: magnum.trade.AbstractImporter
:data plugin_interface: Plugin interface string
:data plugin_search_paths: Plugin search paths
:data plugin_suffix: Plugin suffix
:data plugin_metadata_suffix: Plugin metadata suffix
Similarly to C++, importer plugins are loaded through :ref:`ImporterManager`:
@ -429,7 +436,14 @@
:ref:`AbstractImageConverter.manager`, ensuring the manager is not deleted
before the plugin instances are.
.. TODO couldn't the plugin_interface etc. docs be parsed from pybind's docs?
repeating them for every plugin is annoying
.. py:class:: magnum.trade.AbstractImageConverter
:data plugin_interface: Plugin interface string
:data plugin_search_paths: Plugin search paths
:data plugin_suffix: Plugin suffix
:data plugin_metadata_suffix: Plugin metadata suffix
Similarly to C++, image converter plugins are loaded through
:ref:`ImageConverterManager`:
@ -462,7 +476,14 @@
:ref:`AbstractSceneConverter.manager`, ensuring the manager is not deleted
before the plugin instances are.
.. TODO couldn't the plugin_interface etc. docs be parsed from pybind's docs?
repeating them for every plugin is annoying
.. py:class:: magnum.trade.AbstractSceneConverter
:data plugin_interface: Plugin interface string
:data plugin_search_paths: Plugin search paths
:data plugin_suffix: Plugin suffix
:data plugin_metadata_suffix: Plugin metadata suffix
Similarly to C++, image converter plugins are loaded through
:ref:`SceneConverterManager`:

1
src/python/corrade/pluginmanager.cpp

@ -27,7 +27,6 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> /* for pluginList() and aliasList() */
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */
#include <Corrade/Containers/StringIterable.h>
#include <Corrade/PluginManager/AbstractManager.h>

24
src/python/corrade/pluginmanager.h

@ -27,6 +27,9 @@
#include <memory> /* :( */
#include <pybind11/pybind11.h>
#include <pybind11/stl.h> /** @todo remove once I can return Array<String> directly */
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/StringStl.h> /** @todo drop once we have our string casters */
#include <Corrade/PluginManager/Manager.h>
#include "Corrade/PythonBindings.h"
@ -70,6 +73,27 @@ namespace corrade {
template<class T> void plugin(py::class_<T, PluginManager::PyPluginHolder<T>, PluginManager::AbstractPlugin>& c) {
c
.def_property_readonly_static("plugin_interface", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
return std::string{T::pluginInterface()};
}, "Plugin interface string")
.def_property_readonly_static("plugin_search_paths", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
std::vector<std::string> out;
for(auto&& i: T::pluginSearchPaths())
out.push_back(i);
return out;
}, "Plugin search paths")
.def_property_readonly_static("plugin_suffix", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
return std::string{T::pluginSuffix()};
}, "Plugin binary suffix")
.def_property_readonly_static("plugin_metadata_suffix", [](const py::object&) {
/** @todo drop std::string in favor of our own string caster */
return std::string{T::pluginMetadataSuffix()};
}, "Plugin metadata file suffix")
/** @todo plugin interface string, search paths, suffix, metadata file
suffix (all are static properties) */
.def_property_readonly("manager", [](const T& self) {
return pyObjectHolderFor<PluginManager::PyPluginHolder>(self).manager;
}, "Manager owning this plugin instance");

13
src/python/magnum/test/test_trade.py

@ -24,6 +24,7 @@
#
import os
import platform
import sys
import tempfile
import unittest
@ -1005,7 +1006,17 @@ class Importer(unittest.TestCase):
manager.unload('NonexistentImporter')
def test(self):
importer = trade.ImporterManager().load_and_instantiate('StbImageImporter')
manager = trade.ImporterManager()
self.assertIn('cz.mosra.magnum.Trade.AbstractImporter', trade.AbstractImporter.plugin_interface)
self.assertIn(manager.plugin_directory, trade.AbstractImporter.plugin_search_paths)
if platform.system() == 'Windows':
self.assertEqual(trade.AbstractImporter.plugin_suffix, '.dll')
else:
self.assertEqual(trade.AbstractImporter.plugin_suffix, '.so')
self.assertEqual(trade.AbstractImporter.plugin_metadata_suffix, '.conf')
importer = manager.load_and_instantiate('StbImageImporter')
self.assertEqual(importer.plugin, 'StbImageImporter')
def test_set_plugin_directory(self):

Loading…
Cancel
Save