From 9506802558ebe228822f512241ab786ac22753b4 Mon Sep 17 00:00:00 2001 From: Joey Curtin Date: Thu, 28 Mar 2013 13:58:42 -0400 Subject: [PATCH] added importlib.py with test and moved settings around as well as utils --- pelican/__init__.py | 5 ++- pelican/contents.py | 2 +- pelican/rstdirectives.py | 3 +- pelican/settings/__init__.py | 6 +++ pelican/{settings.py => settings/base.py} | 9 ++++- pelican/settings/conf.py | 24 +++++++++++ pelican/tests/test_importlib.py | 49 +++++++++++++++++++++++ pelican/tests/test_utils.py | 3 ++ pelican/{utils.py => utils/__init__.py} | 0 pelican/utils/importlib.py | 39 ++++++++++++++++++ 10 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 pelican/settings/__init__.py rename pelican/{settings.py => settings/base.py} (98%) create mode 100644 pelican/settings/conf.py create mode 100644 pelican/tests/test_importlib.py rename pelican/{utils.py => utils/__init__.py} (100%) create mode 100644 pelican/utils/importlib.py diff --git a/pelican/__init__.py b/pelican/__init__.py index a2bdefa4..b02a666e 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -62,7 +62,8 @@ class Pelican(object): # if it's a string, then import it if isinstance(plugin, six.string_types): logger.debug("Loading plugin `{0}' ...".format(plugin)) - plugin = __import__(plugin, globals(), locals(), 'module') + # http://stackoverflow.com/questions/1971356/haystack-whoosh-index-generation-error#answer-2683624 + plugin = __import__(plugin, globals(), locals(), 'module'.encode('ascii')) logger.debug("Registering plugin `{0}'".format(plugin.__name__)) plugin.register() @@ -247,6 +248,7 @@ def parse_arguments(): action='store_true', help="Relaunch pelican each time a modification occurs" " on the content files.") + return parser.parse_args() @@ -284,6 +286,7 @@ def main(): args = parse_arguments() init(args.verbosity) pelican = get_instance(args) + try: if args.autoreload: diff --git a/pelican/contents.py b/pelican/contents.py index 38300914..f9b98644 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -14,7 +14,7 @@ from datetime import datetime from pelican import signals -from pelican.settings import _DEFAULT_CONFIG +from pelican.settings.base import _DEFAULT_CONFIG from pelican.utils import (slugify, truncate_html_words, memoized, strftime, python_2_unicode_compatible, deprecated_attribute, path_to_url) diff --git a/pelican/rstdirectives.py b/pelican/rstdirectives.py index fb4a6c93..163978ae 100644 --- a/pelican/rstdirectives.py +++ b/pelican/rstdirectives.py @@ -9,7 +9,8 @@ from pygments.lexers import get_lexer_by_name, TextLexer import re INLINESTYLES = False -DEFAULT = HtmlFormatter(noclasses=INLINESTYLES) +# import ipdb;ipdb.set_trace() +DEFAULT = HtmlFormatter(noclasses=INLINESTYLES, linenos=True) VARIANTS = { 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True), } diff --git a/pelican/settings/__init__.py b/pelican/settings/__init__.py new file mode 100644 index 00000000..f7ea536e --- /dev/null +++ b/pelican/settings/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from pelican.settings.base import \ + read_settings, get_settings_from_module, get_settings_from_file, \ + configure_settings, DEFAULT_THEME, _DEFAULT_CONFIG + +from pelican.settings.conf import settings as conf diff --git a/pelican/settings.py b/pelican/settings/base.py similarity index 98% rename from pelican/settings.py rename to pelican/settings/base.py index da770775..ad103d41 100644 --- a/pelican/settings.py +++ b/pelican/settings/base.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six @@ -11,6 +10,8 @@ import logging from os.path import isabs +from pelican.settings.conf import load_settings_into_global_conf + logger = logging.getLogger(__name__) @@ -111,7 +112,10 @@ def read_settings(path=None, override=None): if override: local_settings.update(override) - return configure_settings(local_settings) + + settings = configure_settings(local_settings) + load_settings_into_global_conf(settings) + return settings def get_settings_from_module(module=None, default_settings=_DEFAULT_CONFIG): @@ -256,3 +260,4 @@ def configure_settings(settings): settings[PATH_KEY] = _DEFAULT_CONFIG[PATH_KEY] return settings + diff --git a/pelican/settings/conf.py b/pelican/settings/conf.py new file mode 100644 index 00000000..4fa9bfc4 --- /dev/null +++ b/pelican/settings/conf.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +__all__ = ['load_settings_into_global_conf'] + +class settings(object): + """ + Just a wrapper to the object interface. + We're generating a module so we can import from it: + + >>> from pelican.conf import settings + >>> settings.PATH + "/Users/jbcurtin/workspace/blog/content" + >>> from pelican.conf.settings import PATH + >>> PATH + "/Users/jbcurtin/workspace/blog/content" + + """ + pass + +def load_settings_into_global_conf(new_settings): + for key, value in new_settings.iteritems(): + # for key,value in read_settings(args.settings, override=get_config(args)).iteritems(): + setattr(settings, key, value) + + return settings \ No newline at end of file diff --git a/pelican/tests/test_importlib.py b/pelican/tests/test_importlib.py new file mode 100644 index 00000000..53c09018 --- /dev/null +++ b/pelican/tests/test_importlib.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals, print_function +import codecs +import logging +import shutil +import os +import datetime +import time +import unittest +import sys +import shutil + +from pelican.utils.importlib import import_module + +# runtest with: +# cd ~/pelican/pelican/tests && python -m unittest discover . 'test_importlib*' && cd - +class TestImportLib(unittest.TestCase): + + def setUp(self): + if not os.path.exists('/tmp/pytest'): + os.makedirs('/tmp/pytest') + with codecs.open('/tmp/pytest/__init__.py','wb+', 'utf-8') as stream: + stream.write('# -*- coding: utf-8 -*-') + + with codecs.open('/tmp/pytest/injected_module.py', 'wb+', 'utf-8') as stream: + stream.write('''# -*- coding: utf-8 -*- +class Awesome(object): + """ + This is pretty awesome. + """ + def cute(self): + return True + +sauce = Awesome() +''') + sys.path.append('/tmp') + + def tearDown(self): + shutil.rmtree('/tmp/pytest') + + def test_import_lib(self): + assert os.path.exists('/tmp/pytest/injected_module.py') + assert '/tmp' in sys.path + + module = import_module('pytest.injected_module') + assert hasattr(module, 'Awesome') + assert hasattr(module, 'sauce') + assert module.sauce.cute() + diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index 78e888eb..ac4dfff9 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -153,3 +153,6 @@ class TestUtils(LoggedTestCase): f.close() utils.clean_output_dir(test_directory) self.assertTrue(not os.path.exists(test_directory)) + + def test_import_lib(self): + import ipdb;ipdb.set_trace() diff --git a/pelican/utils.py b/pelican/utils/__init__.py similarity index 100% rename from pelican/utils.py rename to pelican/utils/__init__.py diff --git a/pelican/utils/importlib.py b/pelican/utils/importlib.py new file mode 100644 index 00000000..b626a3c5 --- /dev/null +++ b/pelican/utils/importlib.py @@ -0,0 +1,39 @@ +# Taken from Python 2.7 with permission from/by the original author. +# Taken from django source: +# -*- coding: utf-8 -*- +# https://github.com/django/django/blob/a84d79f572fbe7512b999c6b3cd7667cbe3138ff/django/utils/importlib.py +import sys + +def _resolve_name(name, package, level): + """Return the absolute name of the module to be imported.""" + if not hasattr(package, 'rindex'): + raise ValueError("'package' not set to a string") + dot = len(package) + for x in range(level, 1, -1): + try: + dot = package.rindex('.', 0, dot) + except ValueError: + raise ValueError("attempted relative import beyond top-level " + "package") + return "%s.%s" % (package[:dot], name) + + +def import_module(name, package=None): + """Import a module. + + The 'package' argument is required when performing a relative import. It + specifies the package to use as the anchor point from which to resolve the + relative import to an absolute import. + + """ + if name.startswith('.'): + if not package: + raise TypeError("relative imports require the 'package' argument") + level = 0 + for character in name: + if character != '.': + break + level += 1 + name = _resolve_name(name[level:], package, level) + __import__(name) + return sys.modules[name] \ No newline at end of file