summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchfw <wangc_2011@hotmail.com>2018-07-17 07:03:30 (GMT)
committerchfw <wangc_2011@hotmail.com>2018-07-17 07:03:30 (GMT)
commit3032acb19b28117f035dbbe5be963d7816cf0e1f (patch)
treef25e4b3242cfa06596ed7f84df36d038f970857b
parent90fd0a5cae3026845a10ffc9ad901eb0625cab57 (diff)
downloadpython-lml-3032acb19b28117f035dbbe5be963d7816cf0e1f.zip
python-lml-3032acb19b28117f035dbbe5be963d7816cf0e1f.tar.gz
python-lml-3032acb19b28117f035dbbe5be963d7816cf0e1f.tar.bz2
:sparkles: provide more flexible way of finding plugins. #4
-rw-r--r--.moban.d/docs/source/custom_index.rst.jj2 (renamed from .moban.d/docs/source/index.rst.jj2)0
-rw-r--r--.moban.yml2
-rw-r--r--CHANGELOG.rst9
-rw-r--r--changelog.yml6
-rw-r--r--docs/source/conf.py165
-rw-r--r--lml.yml4
-rw-r--r--lml/_version.py4
-rw-r--r--lml/loader.py56
-rw-r--r--setup.py2
9 files changed, 221 insertions, 27 deletions
diff --git a/.moban.d/docs/source/index.rst.jj2 b/.moban.d/docs/source/custom_index.rst.jj2
index 70c8800..70c8800 100644
--- a/.moban.d/docs/source/index.rst.jj2
+++ b/.moban.d/docs/source/custom_index.rst.jj2
diff --git a/.moban.yml b/.moban.yml
index 216b88e..5735ebb 100644
--- a/.moban.yml
+++ b/.moban.yml
@@ -9,7 +9,7 @@ targets:
- MANIFEST.in: MANIFEST.in.jj2
- requirements.txt: requirements.txt.jj2
- "docs/source/conf.py": "docs/source/myconf.py.jj2"
- - "docs/source/index.rst": "docs/source/index.rst.jj2"
+ - "docs/source/index.rst": "docs/source/custom_index.rst.jj2"
- test.sh: test.sh.jj2
- "lml/_version.py": _version.py.jj2
- output: CHANGELOG.rst
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 4bdc70f..e357dd4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,15 @@
Change log
================================================================================
+0.0.4 - pending release
+--------------------------------------------------------------------------------
+
+Added
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+#. `#4 <https://github.com/chfw/lml/issues/4>`_: to find plugin names with
+ different naming patterns
+
0.0.3 - 12/06/2018
--------------------------------------------------------------------------------
diff --git a/changelog.yml b/changelog.yml
index 0d1b8ec..585112f 100644
--- a/changelog.yml
+++ b/changelog.yml
@@ -4,6 +4,12 @@ releases:
- changes:
- action: Added
details:
+ - "`#4`: to find plugin names with different naming patterns"
+ date: pending release
+ version: 0.0.4
+- 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
diff --git a/docs/source/conf.py b/docs/source/conf.py
index bb41cb7..3b3ca1c 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -3,39 +3,174 @@ DESCRIPTION = (
'Load me later. A loading plugin management system.' +
''
)
+# -*- coding: utf-8 -*-
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- Project information -----------------------------------------------------
+
+project = u'lml'
+copyright = u'2017-2018 Onni Software Ltd.'
+author = u'C.W.'
+
+# The short X.Y version
+version = u'0.0.3'
+# The full version, including alpha/beta/rc tags
+release = u'0.0.4'
+
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
- 'sphinx.ext.napoleon',
- 'sphinxcontrib.spelling'
]
+# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
+
+# The master toctree document.
master_doc = 'index'
-project = u'lml'
-copyright = u'2017-2018 Onni Software Ltd.'
-version = '0.0.3'
-release = '0.0.3'
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = 'en'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
+
+# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
-html_theme = 'default'
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself. Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+# html_sidebars = {}
+
+
+# -- Options for HTMLHelp output ---------------------------------------------
+
+# Output file base name for HTML help builder.
htmlhelp_basename = 'lmldoc'
-latex_elements = {}
+
+
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
latex_documents = [
- ('index', 'lml.tex',
- 'lml Documentation',
- 'Onni Software Ltd.', 'manual'),
+ (master_doc, 'lml.tex', u'lml Documentation',
+ u'Onni Software Ltd.', 'manual'),
]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'lml',
- 'lml Documentation',
- [u'Onni Software Ltd.'], 1)
+ (master_doc, 'lml', u'lml Documentation',
+ [author], 1)
+]
+
+
+# -- Options for Texinfo output ----------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'lml', u'lml Documentation',
+ author, 'lml', 'One line description of project.',
+ 'Miscellaneous'),
]
+
+# -- Extension configuration -------------------------------------------------
+# -- Options for intersphinx extension ---------------------------------------
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'https://docs.python.org/': None}
+# TODO: html_theme not configurable upstream
+html_theme = 'default'
+
+# TODO: DESCRIPTION not configurable upstream
texinfo_documents = [
('index', 'lml',
'lml Documentation',
@@ -43,3 +178,5 @@ texinfo_documents = [
DESCRIPTION,
'Miscellaneous'),
]
+intersphinx_mapping.update({
+})
diff --git a/lml.yml b/lml.yml
index 97f5318..f4d8521 100644
--- a/lml.yml
+++ b/lml.yml
@@ -4,8 +4,8 @@ organisation: "chfw"
author: "C.W."
contact: "wangc_2011@hotmail.com"
company: "Onni Software Ltd."
-version: "0.0.3"
-current_version: "0.0.3"
+version: "0.0.4"
+current_version: "0.0.4"
release: "0.0.3"
copyright_year: 2017-2018
license: New BSD
diff --git a/lml/_version.py b/lml/_version.py
index f4af5d3..b5e9002 100644
--- a/lml/_version.py
+++ b/lml/_version.py
@@ -1,2 +1,2 @@
-__version__ = '0.0.3'
-__author__ = 'C.W.'
+__version__ = "0.0.4"
+__author__ = "C.W."
diff --git a/lml/loader.py b/lml/loader.py
index f5840f4..9ebb9ec 100644
--- a/lml/loader.py
+++ b/lml/loader.py
@@ -9,6 +9,7 @@
:copyright: (c) 2017-2018 by Onni Software Ltd.
:license: New BSD License, see LICENSE for more details
"""
+import re
import pkgutil
import logging
from itertools import chain
@@ -18,7 +19,8 @@ from lml.utils import do_import
log = logging.getLogger(__name__)
-def scan_plugins(prefix, path, black_list=None, white_list=None):
+def scan_plugins(prefix, pyinstaller_path, black_list=None, white_list=None,
+ plugin_name_patterns=None):
"""
Implicitly discover plugins via pkgutil and pyinstaller path
@@ -36,7 +38,43 @@ def scan_plugins(prefix, path, black_list=None, white_list=None):
will be auto-loaded: robotchef_britishcuisine, robotchef_chinesecuisine,
etc.
- path:string
+ pyinstaller_path:string
+ used in pyinstaller only. When your end developer would package
+ your main library and its plugins using pyinstaller, this path
+ helps pyinstaller to find the plugins.
+
+ black_list:list
+ a list of module names that should be skipped.
+
+ white_list:list
+ a list of modules that comes with your main module. If you have a
+ built-in module, the module name should be inserted into the list.
+
+ For example, robot_cuisine is a built-in module inside robotchef. It
+ is listed in white_list.
+ """
+ __plugin_name_patterns = "%s.+"
+ scan_plugins_regex(plugin_name_patterns=__plugin_name_patterns,
+ pyinstaller_path=pyinstaller_path,
+ black_list=black_list,
+ white_list=white_list)
+
+
+def scan_plugins_regex(plugin_name_patterns=None, pyinstaller_path=None,
+ black_list=None, white_list=None):
+
+ """
+ Implicitly discover plugins via pkgutil and pyinstaller path using
+ regular expression
+
+ Parameters
+ -----------------
+
+ plugin_name_patterns: python regular expression
+ it is used to match all your plugins, either it is a prefix,
+ a suffix, some text in the middle or all.
+
+ pyinstaller_path:string
used in pyinstaller only. When your end developer would package
your main library and its plugins using pyinstaller, this path
helps pyinstaller to find the plugins.
@@ -59,11 +97,13 @@ def scan_plugins(prefix, path, black_list=None, white_list=None):
white_list = []
# scan pkgutil.iter_modules
- module_names = (module_info[1] for module_info in pkgutil.iter_modules()
- if module_info[2] and module_info[1].startswith(prefix))
+ module_names = (
+ module_info[1] for module_info in pkgutil.iter_modules()
+ if module_info[2] and re.match(plugin_name_patterns, module_info[1]))
# scan pyinstaller
- module_names_from_pyinstaller = scan_from_pyinstaller(prefix, path)
+ module_names_from_pyinstaller = scan_from_pyinstaller(
+ plugin_name_patterns, pyinstaller_path)
all_modules = chain(module_names,
module_names_from_pyinstaller,
@@ -89,7 +129,7 @@ def scan_plugins(prefix, path, black_list=None, white_list=None):
# see: https://github.com/pyinstaller/pyinstaller/issues/1905
# load modules using iter_modules()
# (should find all plug ins in normal build, but not pyinstaller)
-def scan_from_pyinstaller(prefix, path):
+def scan_from_pyinstaller(plugin_name_patterns, path):
"""
Discover plugins from pyinstaller
"""
@@ -99,5 +139,7 @@ def scan_from_pyinstaller(prefix, path):
table_of_content |= a_toc
for module_name in table_of_content:
- if module_name.startswith(prefix) and '.' not in module_name:
+ if '.' in module_name:
+ continue
+ if re.match(plugin_name_patterns, module_name):
yield module_name
diff --git a/setup.py b/setup.py
index 43c7d14..77c1814 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@ PY26 = PY2 and sys.version_info[1] < 7
NAME = 'lml'
AUTHOR = 'C.W.'
-VERSION = '0.0.3'
+VERSION = '0.0.4'
EMAIL = 'wangc_2011@hotmail.com'
LICENSE = 'New BSD'
DESCRIPTION = (