GithubHelp home page GithubHelp logo

pluginbase's Introduction

PluginBase

PluginBase is a module for Python that enables the development of flexible plugin systems in Python.

Step 1:

from pluginbase import PluginBase
plugin_base = PluginBase(package='yourapplication.plugins')

Step 2:

plugin_source = plugin_base.make_plugin_source(
    searchpath=['./path/to/plugins', './path/to/more/plugins'])

Step 3:

with plugin_source:
    from yourapplication.plugins import my_plugin
my_plugin.do_something_cool()

Or alternatively:

my_plugin = plugin_source.load_plugin('my_plugin')
my_plugin.do_something_cool()

pluginbase's People

Contributors

altf02 avatar argv0 avatar jhermann avatar mitsuhiko avatar pombredanne avatar talhasch avatar zerosteiner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pluginbase's Issues

list_plugins() displaying each plugin twice, but I'm probably mistaken about something

$ tree -I 'venv|.git|__pycache__'
.
├── app.py
└── sources
    ├── one.py
    └── two.py
from pluginbase import PluginBase

plugin_base = PluginBase(package='app.sources')
plugin_source = plugin_base.make_plugin_source(searchpath=['./sources'])

for plugin_name in plugin_source.list_plugins():
    print(plugin_name)

And when running app.py, I see:

:!/usr/bin/env python app.py
one
two
one
two

If you could kindly point out the error I'm most definitely making, that'd be cool.

Exception thrown when loading plugins

Hi,

I was implementing pluginbase from the example code and stumbled upon an exception which I don't get. Running my code I get the following:

  File "main.py", line 44, in <module>
    app_obj = App(debug=True)
  File "main.py", line 32, in __init__
    for plugin_name in self.plugin_source.list_plugins():
  File "/usr/lib/python2.7/site-packages/pluginbase.py", line 257, in list_plugins
    for _, modname, ispkg in pkgutil.iter_modules(self.mod.__path__):
  File "/usr/lib/python2.7/site-packages/pluginbase.py", line 137, in __path__
    return ps.searchpath + ps.base.searchpath
TypeError: cannot concatenate 'str' and 'list' objects

The list_plugins() function is the one throwing the exception. The way I implemented plugin loading is:

    def __init__(self, debug=False):
        self.debug = debug

        self.plugins = {}
        self.plugin_source = plugin_base.make_plugin_source(
            searchpath=get_path('./plugins/'))

        for plugin_name in self.plugin_source.list_plugins():
            plugin = self.plugin_source.load_plugin(plugin_name)
            plugin.setup(self, self.debug)

The plugin_base object is constructed like this:

    searchpath=[get_path('./plugins')])

Basically all my plugins are located in ./plugins/ and I'm just trying to load them one by one. The setup(self,debug=False) function on every plugin registers the plugin as the example script does.

Any clue on what I'm doing wrong?

Error when exiting a program

Exception ignored in: <bound method PluginSource.__del__ of <pluginbase.PluginSource object at 0x7f1a4e229be0>>
Traceback (most recent call last):
  File "/usr/lib/python3.4/site-packages/pluginbase.py", line 247, in __del__
  File "/usr/lib/python3.4/site-packages/pluginbase.py", line 303, in cleanup
  File "/usr/lib/python3.4/site-packages/pluginbase.py", line 318, in __cleanup
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

DeprecationWarning in pluginbase.py line 439

c:\python\python37\lib\site-packages\pluginbase.py:439: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

KeyError warning when sys.modules is empty as PluginSource.cleanup is called

Not sure of the exact cause yet, but running the following source on python 3.4:

from pluginbase import PluginBase
a_base = PluginBase('some')
a_source = a_base.make_plugin_source(searchpath=['.'])

import asyncio

@asyncio.coroutine
def what():
    return

results in the following warning being displayed:

Exception ignored in: <bound method PluginSource.__del__ of <pluginbase.PluginSource object at 0x021F0AF0>>
Traceback (most recent call last):
  File "d:\python34\lib\site-packages\pluginbase.py", line 247, in __del__
  File "d:\python34\lib\site-packages\pluginbase.py", line 303, in cleanup
  File "d:\python34\lib\site-packages\pluginbase.py", line 319, in __cleanup
KeyError: ('pluginbase._internalspace._spf57aab93650650e4c1433e9cb9bd5a38',)

Could potentially be fixed by adding a default None to the _sys.modules.pop() call causing the KeyError.

importerror: util

when I have:

from pluginbase import PluginBase
from pyechonest import config
from pyechonest import song

I get

Traceback (most recent call last):
  File "partyled.py", line 9, in <module>
    from pyechonest import song
  File "/usr/local/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
    fromlist, level)
  File "build/bdist.macosx-10.10-x86_64/egg/pyechonest/song.py", line 12, in <module>
  File "/usr/local/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
    fromlist, level)
ImportError: No module named util

however if I change the order to

from pyechonest import config
from pyechonest import song
from pluginbase import PluginBase

things work fine. Given the order in which things override, I'm inclined to suspect of PluginBase of doing something weird here.

list_plugins method drops the modules with same name from different plugin directory

The modules with same names in different plugin directory won't be returned in list_plugins.

Here is my case, I have a plugins directory structure like this,

plugins
├── __init__.py
├── builtin
│   ├── __init__.py
│   ├── logger
│   │   ├── __init__.py
│       ├── setup.py
│   │   └── logger.py
├── device
│   ├── __init__.py
│   ├── setup.py

Expect

The list_plugins returns all the module names including those with the same name and could be load_plugin correctly.
['logger', 'setup', 'setup']

Actual

The list_plugins returns all the unique names only and could be load_plugin correctly.
['logger', 'setup']

Code

plugin_base = PluginBase(package='app.plugins',
                            searchpath=[get_path('plugins/builtin')])

source = plugin_base.make_plugin_source(
    searchpath=[get_path('./plugins/%s/' % name)],
    identifier=self.name)
print source.list_plugins()

pluginbase cause import error in pyvirtualdisplay: ImportError: No module named display

from pyvirtualdisplay import Display
  File "/Users/dev/.virtualenvs/kraken-32/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
    fromlist, level)
  File "/Users/dev/.virtualenvs/kraken-32/lib/python2.7/site-packages/pyvirtualdisplay/__init__.py", line 1, in <module>
    from display import Display
  File "/Users/dev/.virtualenvs/kraken-32/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
    fromlist, level)
ImportError: No module named display

Loading recursion depth

Would it be possible to add a recursion depth for the search path?

my_program.py
plugins
    - plugin 1
        - foo.py
        - bar.py
    - plugin 2
        - foobar.py

Currently I am scanning plugins with os.listdir, and searchpathing each. Having a recursion depth would be great.

PluginBase causes ImportError in PyYAML

PluginBase seems to break PyYAML, causing ImportErrors on import.
I'm using the latest version of PyYAML (3.11) and PluginBase.
Tested on OS X and Linux.

Importing PluginBase first causes errors:

Python 2.7.3 (default, Mar 18 2014, 05:13:23) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pluginbase
>>> import yaml
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pluginbase.py", line 404, in plugin_import
    fromlist, level)
  File "/usr/local/lib/python2.7/dist-packages/yaml/__init__.py", line 2, in <module>
    from error import *
  File "/usr/local/lib/python2.7/dist-packages/pluginbase.py", line 404, in plugin_import
    fromlist, level)
ImportError: No module named error

Importing YAML first works fine:

Python 2.7.3 (default, Mar 18 2014, 05:13:23) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import yaml
>>> import pluginbase

pytest failed

git clone https://github.com/mitsuhiko/pluginbase/
pip install .
pytest
Below is the error information:

=============================================================== test session starts ================================================================
platform linux -- Python 3.9.17, pytest-6.2.5, py-1.11.0, pluggy-1.2.0
rootdir: /home/v-lihaoran/reptile/pluginbase
plugins: xdist-2.5.0, anyio-3.7.1, lazy-fixture-0.6.3, mock-3.11.1, cov-2.12.1, forked-1.6.0
collected 9 items                                                                                                                                  

tests/test_advanced.py FF                                                                                                                    [ 22%]
tests/test_basics.py EEFFFE                                                                                                                  [ 88%]
tests/test_shutdown.py F                                                                                                                     [100%]

====================================================================== ERRORS ======================================================================
_______________________________________________________ ERROR at setup of test_basic_plugin ________________________________________________________

request = <FixtureRequest for <Function test_basic_plugin>>

    def fill(request):
        item = request._pyfuncitem
        fixturenames = getattr(item, "fixturenames", None)
        if fixturenames is None:
            fixturenames = request.fixturenames
    
        if hasattr(item, 'callspec'):
            for param, val in sorted_by_dependency(item.callspec.params, fixturenames):
                if val is not None and is_lazy_fixture(val):
                    item.callspec.params[param] = request.getfixturevalue(val.name)
                elif param not in item.funcargs:
                    item.funcargs[param] = request.getfixturevalue(param)
    
>       _fillfixtures()

/anaconda/envs/test/lib/python3.9/site-packages/pytest_lazyfixture.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/conftest.py:19: in source
    return base.make_plugin_source(searchpath=['./plugins'],
/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:213: in make_plugin_source
    return PluginSource(self, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pluginbase.PluginSource object at 0x7f9fe6496340>, base = <pluginbase.PluginBase object at 0x7f9fe6496130>, identifier = 'demo'
searchpath = ['./plugins'], persist = False

    def __init__(self, base, identifier=None, searchpath=None,
                 persist=False):
        #: indicates if this plugin source persists or not.
        self.persist = persist
        if identifier is None:
            identifier = str(uuid.uuid4())
        #: the identifier for this source.
        self.identifier = identifier
        #: A reference to the plugin base that created this source.
        self.base = base
        #: a list of paths where plugins are searched in.
        self.searchpath = searchpath
        #: The internal module name of the plugin source as it appears
        #: in the :mod:`pluginsource._internalspace`.
        self.spaceid = '_sp' + hashlib.md5(
            _to_bytes(self.base.package) + b'|' +
            _to_bytes(identifier),
        ).hexdigest()
        #: a reference to the module on the internal
        #: :mod:`pluginsource._internalspace`.
        self.mod = _PluginSourceModule(self)
    
        if hasattr(_internalspace, self.spaceid):
>           raise RuntimeError('This plugin source already exists.')
E           RuntimeError: This plugin source already exists.

/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:271: RuntimeError
__________________________________________________ ERROR at setup of test_fetching_plugin_source ___________________________________________________

request = <FixtureRequest for <Function test_fetching_plugin_source>>

    def fill(request):
        item = request._pyfuncitem
        fixturenames = getattr(item, "fixturenames", None)
        if fixturenames is None:
            fixturenames = request.fixturenames
    
        if hasattr(item, 'callspec'):
            for param, val in sorted_by_dependency(item.callspec.params, fixturenames):
                if val is not None and is_lazy_fixture(val):
                    item.callspec.params[param] = request.getfixturevalue(val.name)
                elif param not in item.funcargs:
                    item.funcargs[param] = request.getfixturevalue(param)
    
>       _fillfixtures()

/anaconda/envs/test/lib/python3.9/site-packages/pytest_lazyfixture.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/conftest.py:19: in source
    return base.make_plugin_source(searchpath=['./plugins'],
/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:213: in make_plugin_source
    return PluginSource(self, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pluginbase.PluginSource object at 0x7f9fe63f7bb0>, base = <pluginbase.PluginBase object at 0x7f9fe63f7c10>, identifier = 'demo'
searchpath = ['./plugins'], persist = False

    def __init__(self, base, identifier=None, searchpath=None,
                 persist=False):
        #: indicates if this plugin source persists or not.
        self.persist = persist
        if identifier is None:
            identifier = str(uuid.uuid4())
        #: the identifier for this source.
        self.identifier = identifier
        #: A reference to the plugin base that created this source.
        self.base = base
        #: a list of paths where plugins are searched in.
        self.searchpath = searchpath
        #: The internal module name of the plugin source as it appears
        #: in the :mod:`pluginsource._internalspace`.
        self.spaceid = '_sp' + hashlib.md5(
            _to_bytes(self.base.package) + b'|' +
            _to_bytes(identifier),
        ).hexdigest()
        #: a reference to the module on the internal
        #: :mod:`pluginsource._internalspace`.
        self.mod = _PluginSourceModule(self)
    
        if hasattr(_internalspace, self.spaceid):
>           raise RuntimeError('This plugin source already exists.')
E           RuntimeError: This plugin source already exists.

/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:271: RuntimeError
________________________________________________________ ERROR at setup of test_load_plugin ________________________________________________________

request = <FixtureRequest for <Function test_load_plugin>>

    def fill(request):
        item = request._pyfuncitem
        fixturenames = getattr(item, "fixturenames", None)
        if fixturenames is None:
            fixturenames = request.fixturenames
    
        if hasattr(item, 'callspec'):
            for param, val in sorted_by_dependency(item.callspec.params, fixturenames):
                if val is not None and is_lazy_fixture(val):
                    item.callspec.params[param] = request.getfixturevalue(val.name)
                elif param not in item.funcargs:
                    item.funcargs[param] = request.getfixturevalue(param)
    
>       _fillfixtures()

/anaconda/envs/test/lib/python3.9/site-packages/pytest_lazyfixture.py:39: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/conftest.py:19: in source
    return base.make_plugin_source(searchpath=['./plugins'],
/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:213: in make_plugin_source
    return PluginSource(self, *args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pluginbase.PluginSource object at 0x7f9fe6458940>, base = <pluginbase.PluginBase object at 0x7f9fe6458610>, identifier = 'demo'
searchpath = ['./plugins'], persist = False

    def __init__(self, base, identifier=None, searchpath=None,
                 persist=False):
        #: indicates if this plugin source persists or not.
        self.persist = persist
        if identifier is None:
            identifier = str(uuid.uuid4())
        #: the identifier for this source.
        self.identifier = identifier
        #: A reference to the plugin base that created this source.
        self.base = base
        #: a list of paths where plugins are searched in.
        self.searchpath = searchpath
        #: The internal module name of the plugin source as it appears
        #: in the :mod:`pluginsource._internalspace`.
        self.spaceid = '_sp' + hashlib.md5(
            _to_bytes(self.base.package) + b'|' +
            _to_bytes(identifier),
        ).hexdigest()
        #: a reference to the module on the internal
        #: :mod:`pluginsource._internalspace`.
        self.mod = _PluginSourceModule(self)
    
        if hasattr(_internalspace, self.spaceid):
>           raise RuntimeError('This plugin source already exists.')
E           RuntimeError: This plugin source already exists.

/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:271: RuntimeError
===================================================================== FAILURES =====================================================================
________________________________________________________________ test_custom_state _________________________________________________________________

base = <pluginbase.PluginBase object at 0x7f9fe6496340>

    def test_custom_state(base):
        class App(object):
            name = 'foobar'
        source = base.make_plugin_source(searchpath=['./plugins'])
        source.app = App()
    
>       plg = source.load_plugin('advanced')

tests/test_advanced.py:10: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:301: in load_plugin
    return __import__(self.base.package + '.' + name,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <module 'pluginbase.import_hook'>, name = 'dummy.plugins.advanced'
globals = {'ModuleType': <class 'module'>, 'NativeBytesIO': <class '_io.BytesIO'>, 'PY2': False, 'PluginBase': <class 'pluginbase.PluginBase'>, ...}
locals = {}, fromlist = ['__name__'], level = 0

    def plugin_import(self, name, globals=None, locals=None,
                      fromlist=None, level=None):
        if level is None:
            # set the level to the default value specific to this python version
            level = -1 if PY2 else 0
        import_name = name
        if self.enabled:
            ref_globals = globals
            if ref_globals is None:
                ref_globals = sys._getframe(1).f_globals
            space = _discover_space(name, ref_globals)
            if space is not None:
                actual_name = space._rewrite_module_path(name)
                if actual_name is not None:
                    import_name = actual_name
    
>       return self._system_import(import_name, globals, locals,
                                   fromlist, level)
E       ModuleNotFoundError: No module named 'pluginbase._internalspace._sp8cf9ccbd2c645f151f331651bb414377.advanced'

/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:438: ModuleNotFoundError
______________________________________________________________ test_plugin_resources _______________________________________________________________

source = <pluginbase.PluginSource object at 0x7f9fe6458be0>

    def test_plugin_resources(source):
>       with source.open_resource('withresources', 'hello.txt') as f:

tests/test_advanced.py:15: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:316: in open_resource
    mod = self.load_plugin(plugin)
/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:301: in load_plugin
    return __import__(self.base.package + '.' + name,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <module 'pluginbase.import_hook'>, name = 'dummy.plugins.withresources'
globals = {'ModuleType': <class 'module'>, 'NativeBytesIO': <class '_io.BytesIO'>, 'PY2': False, 'PluginBase': <class 'pluginbase.PluginBase'>, ...}
locals = {}, fromlist = ['__name__'], level = 0

    def plugin_import(self, name, globals=None, locals=None,
                      fromlist=None, level=None):
        if level is None:
            # set the level to the default value specific to this python version
            level = -1 if PY2 else 0
        import_name = name
        if self.enabled:
            ref_globals = globals
            if ref_globals is None:
                ref_globals = sys._getframe(1).f_globals
            space = _discover_space(name, ref_globals)
            if space is not None:
                actual_name = space._rewrite_module_path(name)
                if actual_name is not None:
                    import_name = actual_name
    
>       return self._system_import(import_name, globals, locals,
                                   fromlist, level)
E       ModuleNotFoundError: No module named 'pluginbase._internalspace._sp7bb7d8da1d24ae5a5205609c951b8be4.withresources'

/anaconda/envs/test/lib/python3.9/site-packages/pluginbase.py:438: ModuleNotFoundError
___________________________________________________________________ test_cleanup ___________________________________________________________________

base = <pluginbase.PluginBase object at 0x7f9fe63c8d90>

    def test_cleanup(base):
        new_source = base.make_plugin_source(searchpath=['./plugins'])
        mod_name = new_source.mod.__name__
        assert sys.modules.get(mod_name) is new_source.mod
    
        with new_source:
>           from dummy.plugins import hello
E           ImportError: cannot import name 'hello' from 'pluginbase._internalspace._spff350f7f1d735bef78c28587b3641876' (unknown location)

tests/test_basics.py:60: ImportError
___________________________________________________________________ test_persist ___________________________________________________________________

base = <pluginbase.PluginBase object at 0x7f9fe64062b0>

    def test_persist(base):
        new_source = base.make_plugin_source(searchpath=['./plugins'],
                                             persist=True)
        mod_name = new_source.mod.__name__
        assert sys.modules.get(mod_name) is new_source.mod
    
        with new_source:
>           from dummy.plugins import hello
E           ImportError: cannot import name 'hello' from 'pluginbase._internalspace._sp1f2dd722ad6c6e260b703039fbb0e803' (unknown location)

tests/test_basics.py:75: ImportError
________________________________________________________________ test_list_plugins _________________________________________________________________

source = <pluginbase.PluginSource object at 0x7f9fe6459490>

    def test_list_plugins(source):
        plugins = source.list_plugins()
        hello_plugins = [x for x in plugins if x.startswith('hello')]
>       assert hello_plugins == ['hello', 'hello2']
E       AssertionError: assert [] == ['hello', 'hello2']
E         Right contains 2 more items, first extra item: 'hello'
E         Use -v to get the full diff

tests/test_basics.py:88: AssertionError
_______________________________________________________________ test_clean_shutdown ________________________________________________________________

    def test_clean_shutdown():
        env = dict(os.environ)
        env['PYTHONPATH'] = '..:.'
        c = subprocess.Popen([sys.executable, '-c', 'import shutdown'],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             env=env)
        stdout, stderr = c.communicate()
        assert stdout == b''
>       assert stderr == b''
E       AssertionError: assert b'Traceback (...'shutdown\'\n' == b''
E         Use -v to get the full diff

tests/test_shutdown.py:15: AssertionError
============================================================= short test summary info ==============================================================
FAILED tests/test_advanced.py::test_custom_state - ModuleNotFoundError: No module named 'pluginbase._internalspace._sp8cf9ccbd2c645f151f331651bb4...
FAILED tests/test_advanced.py::test_plugin_resources - ModuleNotFoundError: No module named 'pluginbase._internalspace._sp7bb7d8da1d24ae5a5205609...
FAILED tests/test_basics.py::test_cleanup - ImportError: cannot import name 'hello' from 'pluginbase._internalspace._spff350f7f1d735bef78c28587b3...
FAILED tests/test_basics.py::test_persist - ImportError: cannot import name 'hello' from 'pluginbase._internalspace._sp1f2dd722ad6c6e260b703039fb...
FAILED tests/test_basics.py::test_list_plugins - AssertionError: assert [] == ['hello', 'hello2']
FAILED tests/test_shutdown.py::test_clean_shutdown - AssertionError: assert b'Traceback (...'shutdown\'\n' == b''
ERROR tests/test_basics.py::test_basic_plugin - RuntimeError: This plugin source already exists.
ERROR tests/test_basics.py::test_fetching_plugin_source - RuntimeError: This plugin source already exists.
ERROR tests/test_basics.py::test_load_plugin - RuntimeError: This plugin source already exists.
=========================================================== 6 failed, 3 errors in 0.25s ============================================================

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.