Merge pull request #3 from chfw/dev

support dict as pluggable payload
This commit is contained in:
jaska 2018-06-12 23:57:38 +01:00 committed by GitHub
commit b8a9f6a809
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 156 additions and 48 deletions

View File

@ -11,3 +11,7 @@ targets:
- "docs/source/conf.py": "docs/source/myconf.py.jj2"
- "docs/source/index.rst": "docs/source/index.rst.jj2"
- test.sh: test.sh.jj2
- "lml/_version.py": _version.py.jj2
- output: CHANGELOG.rst
configuration: changelog.yml
template: CHANGELOG.rst.jj2

View File

@ -1,13 +1,29 @@
Change log
===========
================================================================================
0.0.2 - 23.10.2017
0.0.3 - 12/06/2018
--------------------------------------------------------------------------------
#. pyexcel `#103 <https://github.com/pyexcel/pyexcel/issues/103>`_, include
Added
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#. `dict` can be a pluggable type in addition to `function`, `class`
#. get primary tag of your tag, helping you find out which category of plugins
your tag points to
0.0.2 - 23/10/2017
--------------------------------------------------------------------------------
Updated
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#. `pyexcel#103 <https://github.com/pyexcel/pyexcel/issues/103>`_: include
LICENSE in tar ball
0.0.1 - 30/05/2017
--------------------------------------------------------------------------------
first release
Added
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#. First release

View File

@ -1,12 +1,13 @@
================================================================================
lml - Load me later. A lazy loading plugin management system.
lml - Load me later. A lazy plugin management system.
================================================================================
.. image:: https://api.travis-ci.org/chfw/lml.svg?branch=master
.. image:: https://api.travis-ci.org/chfw/lml.svg
:target: http://travis-ci.org/chfw/lml
.. image:: https://codecov.io/gh/chfw/lml/branch/master/graph/badge.svg
:target: https://codecov.io/gh/chfw/lml
.. image:: https://codecov.io/github/chfw/lml/coverage.png
:target: https://codecov.io/github/chfw/lml
.. image:: https://readthedocs.org/projects/lml/badge/?version=latest
:target: http://lml.readthedocs.org/en/latest/
@ -54,4 +55,3 @@ License
================================================================================
New BSD

22
changelog.yml Normal file
View File

@ -0,0 +1,22 @@
name: lml
organisation: chfw
releases:
- changes:
- action: Added
details:
- "`dict` can be a pluggable type in addition to `function`, `class`"
- get primary tag of your tag, helping you find out which category of plugins your tag points to
date: 12/06/2018
version: 0.0.3
- changes:
- action: Updated
details:
- "`pyexcel#103 <https://github.com/pyexcel/pyexcel/issues/103>`_: include LICENSE in tar ball"
date: 23/10/2017
version: 0.0.2
- changes:
- action: Added
details:
- First release
date: 30/05/2017
version: 0.0.1

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
DESCRIPTION = (
'Load me later. A lazy loading plugin management system.' +
'Load me later. A loading plugin management system.' +
''
)
extensions = [
@ -17,9 +17,9 @@ source_suffix = '.rst'
master_doc = 'index'
project = u'lml'
copyright = u'2017 Onni Software Ltd.'
version = '0.0.2'
release = '0.0.2'
copyright = u'2017-2018 Onni Software Ltd.'
version = '0.0.3'
release = '0.0.3'
exclude_patterns = []
pygments_style = 'sphinx'
html_theme = 'default'

View File

@ -1,4 +1,4 @@
`lml` - Load me later. A lazy loading plugin management system.
`lml` - Load me later. A loading plugin management system.
================================================================================

12
lml.yml
View File

@ -1,13 +1,13 @@
name: "lml"
full_name: "Load me later. A lazy loading plugin management system."
full_name: "Load me later. A lazy plugin management system."
organisation: "chfw"
author: "C.W."
contact: "wangc_2011@hotmail.com"
company: "Onni Software Ltd."
version: "0.0.2"
current_version: "0.0.2"
release: "0.0.2"
copyright_year: 2017
version: "0.0.3"
current_version: "0.0.3"
release: "0.0.3"
copyright_year: 2017-2018
license: New BSD
dependencies: []
description: "Load me later. A lazy loading plugin management system."
description: "Load me later. A loading plugin management system."

View File

@ -4,10 +4,12 @@
Load me later. A lazy loading plugin management system.
:copyright: (c) 2017 by Onni Software Ltd.
:copyright: (c) 2017-2018 by Onni Software Ltd.
:license: New BSD License, see LICENSE for more details
"""
import logging
from lml._version import __version__ # flake8: noqa
from lml._version import __author__ # flake8: noqa
try:
from logging import NullHandler

2
lml/_version.py Normal file
View File

@ -0,0 +1,2 @@
__version__ = '0.0.3'
__author__ = 'C.W.'

View File

@ -6,7 +6,7 @@
and pyinstaller. :func:`~lml.loader.scan_plugins` is expected to be
called in the main package of yours at an earliest time of convenience.
:copyright: (c) 2017 by Onni Software Ltd.
:copyright: (c) 2017-2018 by Onni Software Ltd.
:license: New BSD License, see LICENSE for more details
"""
import pkgutil

View File

@ -22,7 +22,7 @@
can be overridden to help its matching :class:`~lml.plugin.PluginManager`
to look itself up.
:copyright: (c) 2017 by Onni Software Ltd.
:copyright: (c) 2017-2018 by Onni Software Ltd.
:license: New BSD License, see LICENSE for more details
"""
import logging
@ -204,6 +204,7 @@ class PluginManager(object):
def __init__(self, plugin_type):
self.plugin_name = plugin_type
self.registry = defaultdict(list)
self.tag_groups = dict()
self._logger = logging.getLogger(
self.__class__.__module__ + '.' + self.__class__.__name__)
_register_class(self)
@ -273,7 +274,7 @@ class PluginManager(object):
if __key in self.registry:
for plugin_info in self.registry[__key]:
cls = self.dynamic_load_library(plugin_info)
module_name = _get_me_pypi_package_name(cls.__module__)
module_name = _get_me_pypi_package_name(cls)
if library and module_name != library:
continue
else:
@ -316,10 +317,19 @@ class PluginManager(object):
plugin_info:
a instance of plugin info
"""
self._logger.debug("register " + plugin_cls.__name__)
for key in plugin_info.tags():
self._logger.debug("register %s",
_show_me_your_name(plugin_cls))
primary_tag = None
for index, key in enumerate(plugin_info.tags()):
plugin_info.cls = plugin_cls
self.registry[key.lower()].append(plugin_info)
if index == 0:
primary_tag = key.lower()
self.tag_groups[key.lower()] = primary_tag
def get_primary_key(self, key):
__key = key.lower()
return self.tag_groups.get(__key, None)
def _register_class(cls):
@ -335,7 +345,7 @@ def _register_class(cls):
plugin_info.absolute_import_path)
else:
log.debug("load cached plugin info: %s",
plugin_info.cls.__name__)
_show_me_your_name(plugin_info.cls))
cls.load_me_later(plugin_info)
del CACHED_PLUGIN_INFO[cls.plugin_name]
@ -348,7 +358,8 @@ def _register_a_plugin(plugin_info, plugin_cls):
manager.register_a_plugin(plugin_cls, plugin_info)
else:
# let's cache it and wait the manager to be registered
log.debug("caching %s", plugin_cls.__name__)
log.debug("caching %s",
_show_me_your_name(plugin_cls.__name__))
CACHED_PLUGIN_INFO[plugin_info.plugin_type].append(plugin_info)
@ -365,6 +376,17 @@ def _load_me_later(plugin_info):
CACHED_PLUGIN_INFO[plugin_info.plugin_type].append(plugin_info)
def _get_me_pypi_package_name(module_name):
root_module_name = module_name.split('.')[0]
return root_module_name.replace('_', '-')
def _get_me_pypi_package_name(module):
try:
module_name = module.__module__
root_module_name = module_name.split('.')[0]
return root_module_name.replace('_', '-')
except AttributeError:
return None
def _show_me_your_name(cls_func_or_data_type):
try:
return cls_func_or_data_type.__name__
except AttributeError:
return str(type(cls_func_or_data_type))

View File

@ -4,7 +4,7 @@
json utils for dump plugin info class
:copyright: (c) 2017 by Onni Software Ltd.
:copyright: (c) 2017-2018 by Onni Software Ltd.
:license: New BSD License, see LICENSE for more details
"""
import sys

View File

@ -1,4 +1,6 @@
# Template by setupmobans
#!/usr/bin/env python3
# Template by pypi-mobans
import os
import sys
import codecs
@ -9,23 +11,20 @@ PY26 = PY2 and sys.version_info[1] < 7
NAME = 'lml'
AUTHOR = 'C.W.'
VERSION = '0.0.2'
VERSION = '0.0.3'
EMAIL = 'wangc_2011@hotmail.com'
LICENSE = 'New BSD'
DESCRIPTION = (
'Load me later. A lazy loading plugin management system.' +
''
'Load me later. A loading plugin management system.'
)
URL = 'https://github.com/chfw/lml'
DOWNLOAD_URL = '%s/archive/0.0.2.tar.gz' % URL
FILES = ['README.rst', 'CHANGELOG.rst']
DOWNLOAD_URL = '%s/archive/0.0.3.tar.gz' % URL
FILES = ['README.rst', 'CHANGELOG.rst']
KEYWORDS = [
'python'
]
CLASSIFIERS = [
'Topic :: Office/Business',
'Topic :: Utilities',
'Topic :: Software Development :: Libraries',
'Programming Language :: Python',
'Intended Audience :: Developers',
@ -39,6 +38,7 @@ CLASSIFIERS = [
INSTALL_REQUIRES = [
]
SETUP_COMMANDS = {}
PACKAGES = find_packages(exclude=['ez_setup', 'examples', 'tests'])
@ -46,11 +46,12 @@ EXTRAS_REQUIRE = {}
# You do not need to read beyond this line
PUBLISH_COMMAND = '{0} setup.py sdist bdist_wheel upload -r pypi'.format(
sys.executable)
GS_COMMAND = ('gs lml v0.0.2 ' +
"Find 0.0.2 in changelog for more details")
GS_COMMAND = ('gs lml v0.0.3 ' +
"Find 0.0.3 in changelog for more details")
NO_GS_MESSAGE = ('Automatic github release is disabled. ' +
'Please install gease to enable it.')
UPLOAD_FAILED_MSG = ('Upload failed. please run "%s" yourself.')
UPLOAD_FAILED_MSG = (
'Upload failed. please run "%s" yourself.' % PUBLISH_COMMAND)
HERE = os.path.abspath(os.path.dirname(__file__))
@ -75,6 +76,8 @@ class PublishCommand(Command):
try:
self.status('Removing previous builds...')
rmtree(os.path.join(HERE, 'dist'))
rmtree(os.path.join(HERE, 'build'))
rmtree(os.path.join(HERE, 'lml.egg-info'))
except OSError:
pass
@ -91,6 +94,11 @@ class PublishCommand(Command):
sys.exit()
SETUP_COMMANDS.update({
'publish': PublishCommand
})
def has_gease():
"""
test if github release command is installed
@ -115,7 +123,8 @@ def read_files(*files):
def read(afile):
"""Read a file into setup"""
with codecs.open(afile, 'r', 'utf-8') as opened_file:
the_relative_file = os.path.join(HERE, afile)
with codecs.open(the_relative_file, 'r', 'utf-8') as opened_file:
content = filter_out_test_code(opened_file)
content = "".join(list(content))
return content
@ -164,7 +173,5 @@ if __name__ == '__main__':
include_package_data=True,
zip_safe=False,
classifiers=CLASSIFIERS,
cmdclass={
'publish': PublishCommand,
}
cmdclass=SETUP_COMMANDS
)

View File

@ -1,6 +1,6 @@
from mock import patch
from lml.plugin import PluginManager, PLUG_IN_MANAGERS
from lml.plugin import PluginInfo
from lml.plugin import PluginInfo, _show_me_your_name
from lml.plugin import CACHED_PLUGIN_INFO
from nose.tools import eq_, raises
@ -140,5 +140,38 @@ def test_register_a_plugin_function_2():
assert non_existent_plugin in CACHED_PLUGIN_INFO
def test_primary_key():
manager = PluginManager("test plugin2")
@PluginInfo('test plugin2', tags=['primary key', 'key 1', 'key 2'])
class MyPlugin(object):
pass
pk = manager.get_primary_key('key 1')
eq_(pk, 'primary key')
def test_dict_as_plugin_payload():
manager = PluginManager("test plugin3")
plugin = PluginInfo('test plugin3', tags=['primary key', 'key 1', 'key 2'])
plugin(dict(B=1))
instance = manager.load_me_now('key 1')
eq_(instance, dict(B=1))
def test_show_me_your_name():
class Test(object):
pass
name = _show_me_your_name(Test)
eq_(name, 'Test')
name2 = _show_me_your_name(dict(A=1))
assert 'dict' in name2
def make_me_a_plugin_info(plugin_name):
return PluginInfo(plugin_name, 'abs_path', custom='property')