From 1ed28ef2b4d1693485b1543c97f47c6910fb9efd Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 12 Jun 2016 21:59:37 +0200 Subject: [PATCH 1/5] Refactor plugin loading --- patacrep/build.py | 8 ++------ patacrep/files.py | 17 +++++++++++++++++ patacrep/tools/convert/__main__.py | 7 +------ test/test_content/test_content.py | 8 ++------ test/test_song/test_parser.py | 4 +--- 5 files changed, 23 insertions(+), 21 deletions(-) diff --git a/patacrep/build.py b/patacrep/build.py index 3998244d..a1ece8a5 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -80,15 +80,11 @@ class Songbook: ) # Loading custom plugins - self._config['_content_plugins'] = files.load_plugins( + self._config['_content_plugins'] = files.load_plugins_content( datadirs=self._config['_datadir'], - root_modules=['content'], - keyword='CONTENT_PLUGINS', ) - self._config['_song_plugins'] = files.load_plugins( + self._config['_song_plugins'] = files.load_plugins_songs( datadirs=self._config['_datadir'], - root_modules=['songs'], - keyword='SONG_RENDERERS', )['tsg'] # Configuration set diff --git a/patacrep/files.py b/patacrep/files.py index bc51557d..8a3963ec 100644 --- a/patacrep/files.py +++ b/patacrep/files.py @@ -93,6 +93,22 @@ def iter_modules(path, prefix): LOGGER.debug("[plugins] Could not load module {}: {}".format(name, str(error))) continue +def load_plugins_content(datadirs=()): + """Load the content plugins, and return a dictionary of those plugins.""" + return load_plugins( + datadirs=datadirs, + root_modules=('content',), + keyword='CONTENT_PLUGINS', + ) + +def load_plugins_songs(datadirs=()): + """Load the song renderer plugins, and return a dictionary of those plugins.""" + return load_plugins( + datadirs=datadirs, + root_modules=('songs',), + keyword='SONG_RENDERERS', + ) + def load_plugins(datadirs, root_modules, keyword): """Load all plugins, and return a dictionary of those plugins. @@ -102,6 +118,7 @@ def load_plugins(datadirs, root_modules, keyword): Arguments: - datadirs: List of directories in which plugins are to be searched. + The plugins will also be searched in the patacrep modules. - root_modules: the submodule in which plugins are to be searched, as a list of modules (e.g. ["some", "deep", "module"] for "some.deep.module"). diff --git a/patacrep/tools/convert/__main__.py b/patacrep/tools/convert/__main__.py index 65b82d8b..ac6c0843 100644 --- a/patacrep/tools/convert/__main__.py +++ b/patacrep/tools/convert/__main__.py @@ -35,12 +35,7 @@ def main(args=None): dest = args[2] song_files = args[3:] - # todo : what is the datadir argument used for? - renderers = files.load_plugins( - datadirs=[], - root_modules=['songs'], - keyword='SONG_RENDERERS', - ) + renderers = files.load_plugins_songs() if dest not in renderers: LOGGER.error( diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index dbf6926a..3c675889 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -108,15 +108,11 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): ) # Load the plugins - config['_content_plugins'] = files.load_plugins( + config['_content_plugins'] = files.load_plugins_content( datadirs=config['_datadir'], - root_modules=['content'], - keyword='CONTENT_PLUGINS', ) - config['_song_plugins'] = files.load_plugins( + config['_song_plugins'] = files.load_plugins_songs( datadirs=config['_datadir'], - root_modules=['songs'], - keyword='SONG_RENDERERS', )['tsg'] return config diff --git a/test/test_song/test_parser.py b/test/test_song/test_parser.py index 39f4a05c..e4c0da35 100644 --- a/test/test_song/test_parser.py +++ b/test/test_song/test_parser.py @@ -81,10 +81,8 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): cls.config['_datadir'] = [] cls.config['_datadir'].append('datadir') - cls.song_plugins = files.load_plugins( + cls.song_plugins = files.load_plugins_songs( datadirs=cls.config['_datadir'], - root_modules=['songs'], - keyword='SONG_RENDERERS', ) with cls.chdir(): for source in sorted(glob.glob('*.*.source')): From 9c9e4609a87d40257f8b3e7517857fdde1d214fb Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 12 Jun 2016 22:09:34 +0200 Subject: [PATCH 2/5] Automatically load content plugins --- patacrep/build.py | 4 ---- patacrep/content/__init__.py | 2 +- patacrep/files.py | 6 ++++-- test/test_content/test_content.py | 3 --- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/patacrep/build.py b/patacrep/build.py index a1ece8a5..1cc4a42a 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -79,10 +79,6 @@ class Songbook: copy.deepcopy(self._config['authors']) ) - # Loading custom plugins - self._config['_content_plugins'] = files.load_plugins_content( - datadirs=self._config['_datadir'], - ) self._config['_song_plugins'] = files.load_plugins_songs( datadirs=self._config['_datadir'], )['tsg'] diff --git a/patacrep/content/__init__.py b/patacrep/content/__init__.py index a65b0525..9b0655af 100755 --- a/patacrep/content/__init__.py +++ b/patacrep/content/__init__.py @@ -259,7 +259,7 @@ def process_content(content, config=None): included in the .tex file. """ contentlist = ContentList() - plugins = config.get('_content_plugins', {}) + plugins = files.load_plugins_content(config['_datadir']) if not content: content = [{'song': None}] elif isinstance(content, dict): diff --git a/patacrep/files.py b/patacrep/files.py index 8a3963ec..bad0f90f 100644 --- a/patacrep/files.py +++ b/patacrep/files.py @@ -1,6 +1,7 @@ """File system utilities.""" from contextlib import contextmanager +from functools import lru_cache import logging import os import pkgutil @@ -96,7 +97,7 @@ def iter_modules(path, prefix): def load_plugins_content(datadirs=()): """Load the content plugins, and return a dictionary of those plugins.""" return load_plugins( - datadirs=datadirs, + datadirs=tuple(datadirs), root_modules=('content',), keyword='CONTENT_PLUGINS', ) @@ -104,11 +105,12 @@ def load_plugins_content(datadirs=()): def load_plugins_songs(datadirs=()): """Load the song renderer plugins, and return a dictionary of those plugins.""" return load_plugins( - datadirs=datadirs, + datadirs=tuple(datadirs), root_modules=('songs',), keyword='SONG_RENDERERS', ) +@lru_cache() def load_plugins(datadirs, root_modules, keyword): """Load all plugins, and return a dictionary of those plugins. diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index 3c675889..0a28ea69 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -108,9 +108,6 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): ) # Load the plugins - config['_content_plugins'] = files.load_plugins_content( - datadirs=config['_datadir'], - ) config['_song_plugins'] = files.load_plugins_songs( datadirs=config['_datadir'], )['tsg'] From 95434c5c02acd86e17de142d0e832335ccb73f74 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 12 Jun 2016 22:17:21 +0200 Subject: [PATCH 3/5] Automatically load song rendered plugins --- patacrep/build.py | 4 ---- patacrep/content/song.py | 2 +- test/test_content/test_content.py | 5 ----- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/patacrep/build.py b/patacrep/build.py index 1cc4a42a..73efbbcc 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -79,10 +79,6 @@ class Songbook: copy.deepcopy(self._config['authors']) ) - self._config['_song_plugins'] = files.load_plugins_songs( - datadirs=self._config['_datadir'], - )['tsg'] - # Configuration set self._config['render'] = content.render self._config['content'] = content.process_content( diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 4f81cc12..074ae394 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -87,7 +87,7 @@ def parse(keyword, argument, config): contentlist = argument if isinstance(contentlist, str): contentlist = [contentlist] - plugins = config['_song_plugins'] + plugins = files.load_plugins_songs(config['_datadir'])['tsg'] if '_langs' not in config: config['_langs'] = set() songlist = ContentList() diff --git a/test/test_content/test_content.py b/test/test_content/test_content.py index 0a28ea69..770d4e1a 100644 --- a/test/test_content/test_content.py +++ b/test/test_content/test_content.py @@ -107,9 +107,4 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): outputdir ) - # Load the plugins - config['_song_plugins'] = files.load_plugins_songs( - datadirs=config['_datadir'], - )['tsg'] - return config From 3fb5e50b36f924f56aab0b1377495369d4118d15 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 12 Jun 2016 22:18:21 +0200 Subject: [PATCH 4/5] useless import --- patacrep/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patacrep/build.py b/patacrep/build.py index 73efbbcc..a66619d7 100644 --- a/patacrep/build.py +++ b/patacrep/build.py @@ -10,7 +10,7 @@ from subprocess import Popen, PIPE, call, check_call import yaml -from patacrep import authors, content, encoding, errors, files, pkg_datapath, utils +from patacrep import authors, content, encoding, errors, pkg_datapath, utils from patacrep.index import process_sxd from patacrep.templates import TexBookRenderer, iter_bookoptions From 5a89a4a8743b6d763a110ccabdfb72d79964e7c7 Mon Sep 17 00:00:00 2001 From: Oliverpool Date: Sun, 12 Jun 2016 22:25:00 +0200 Subject: [PATCH 5/5] Better function names --- patacrep/content/__init__.py | 2 +- patacrep/content/song.py | 2 +- patacrep/files.py | 4 ++-- patacrep/tools/convert/__main__.py | 2 +- test/test_song/test_parser.py | 12 ++++-------- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/patacrep/content/__init__.py b/patacrep/content/__init__.py index 9b0655af..eaaeaa59 100755 --- a/patacrep/content/__init__.py +++ b/patacrep/content/__init__.py @@ -259,7 +259,7 @@ def process_content(content, config=None): included in the .tex file. """ contentlist = ContentList() - plugins = files.load_plugins_content(config['_datadir']) + plugins = files.load_content_plugins(config['_datadir']) if not content: content = [{'song': None}] elif isinstance(content, dict): diff --git a/patacrep/content/song.py b/patacrep/content/song.py index 074ae394..3063a700 100755 --- a/patacrep/content/song.py +++ b/patacrep/content/song.py @@ -87,7 +87,7 @@ def parse(keyword, argument, config): contentlist = argument if isinstance(contentlist, str): contentlist = [contentlist] - plugins = files.load_plugins_songs(config['_datadir'])['tsg'] + plugins = files.load_renderer_plugins(config['_datadir'])['tsg'] if '_langs' not in config: config['_langs'] = set() songlist = ContentList() diff --git a/patacrep/files.py b/patacrep/files.py index bad0f90f..1ad296d5 100644 --- a/patacrep/files.py +++ b/patacrep/files.py @@ -94,7 +94,7 @@ def iter_modules(path, prefix): LOGGER.debug("[plugins] Could not load module {}: {}".format(name, str(error))) continue -def load_plugins_content(datadirs=()): +def load_content_plugins(datadirs=()): """Load the content plugins, and return a dictionary of those plugins.""" return load_plugins( datadirs=tuple(datadirs), @@ -102,7 +102,7 @@ def load_plugins_content(datadirs=()): keyword='CONTENT_PLUGINS', ) -def load_plugins_songs(datadirs=()): +def load_renderer_plugins(datadirs=()): """Load the song renderer plugins, and return a dictionary of those plugins.""" return load_plugins( datadirs=tuple(datadirs), diff --git a/patacrep/tools/convert/__main__.py b/patacrep/tools/convert/__main__.py index ac6c0843..3916b6ae 100644 --- a/patacrep/tools/convert/__main__.py +++ b/patacrep/tools/convert/__main__.py @@ -35,7 +35,7 @@ def main(args=None): dest = args[2] song_files = args[3:] - renderers = files.load_plugins_songs() + renderers = files.load_renderer_plugins() if dest not in renderers: LOGGER.error( diff --git a/test/test_song/test_parser.py b/test/test_song/test_parser.py index e4c0da35..6123470a 100644 --- a/test/test_song/test_parser.py +++ b/test/test_song/test_parser.py @@ -60,7 +60,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): with self.chdir(): with open_read(destname) as expectfile: with logging_reduced(): - song = self.song_plugins[out_format][in_format](sourcename, self.config) + song = self.song_renderer[out_format][in_format](sourcename, self.config) expected = expectfile.read().strip().replace( "@TEST_FOLDER@", files.path2posix(resource_filename(__name__, "")), @@ -76,14 +76,10 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): # Setting datadir # Load the default songbook config cls.config = config_model('default')['en'] + cls.config['_datadir'] = ['datadir'] - if '_datadir' not in cls.config: - cls.config['_datadir'] = [] - cls.config['_datadir'].append('datadir') + cls.song_renderer = files.load_renderer_plugins() - cls.song_plugins = files.load_plugins_songs( - datadirs=cls.config['_datadir'], - ) with cls.chdir(): for source in sorted(glob.glob('*.*.source')): [*base, in_format, _] = source.split('.') @@ -126,7 +122,7 @@ class FileTest(unittest.TestCase, metaclass=dynamic.DynamicTest): """Test that `base` parsing fails.""" sourcename = "{}.{}.source".format(base, in_format) with self.chdir('errors'): - parser = self.song_plugins[out_format][in_format] + parser = self.song_renderer[out_format][in_format] self.assertRaises(errors.SongSyntaxError, parser, sourcename, self.config) test_parse_failure.__doc__ = (