From b3aaf6d5ca4fa53cc78456b2df01ab4d11cec84a Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 10 Aug 2011 23:19:33 +0200 Subject: [PATCH] Refactored package finding --- flask/app.py | 34 +++++----------------------------- flask/helpers.py | 37 +++++++++++++++++++++++++++++++++++++ tests/flask_tests.py | 8 ++++---- 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/flask/app.py b/flask/app.py index 14b6d138..52a54b29 100644 --- a/flask/app.py +++ b/flask/app.py @@ -24,7 +24,8 @@ from werkzeug.exceptions import HTTPException, InternalServerError, \ MethodNotAllowed, BadRequest from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \ - locked_cached_property, _tojson_filter, _endpoint_from_view_func + locked_cached_property, _tojson_filter, _endpoint_from_view_func, \ + find_package from .wrappers import Request, Response from .config import ConfigAttribute, Config from .ctx import RequestContext @@ -561,35 +562,10 @@ class Flask(_PackageBoundObject): .. versionadded:: 0.8 """ - root_mod = sys.modules[self.import_name.split('.')[0]] - # we're not using root_mod.__file__ here since the module could be - # virtual. We're trusting the _PackageBoundObject to have calculated - # the proper name. - package_path = self.root_path - if hasattr(root_mod, '__path__'): - package_path = os.path.dirname(package_path) - - # leave the egg wrapper folder or the actual .egg on the filesystem - if os.path.basename(package_path).endswith('.egg'): - package_path = os.path.dirname(package_path) - - site_parent, site_folder = os.path.split(package_path) - py_prefix = os.path.abspath(sys.prefix) - if package_path.startswith(py_prefix): - base_dir = py_prefix - elif site_folder == 'site-packages': - parent, folder = os.path.split(site_parent) - # Windows like installations - if folder.lower() == 'lib': - base_dir = parent - # UNIX like installations - elif os.path.basename(parent).lower() == 'lib': - base_dir = os.path.dirname(parent) - else: - base_dir = site_parent - else: + prefix, package_path = find_package(self.import_name) + if prefix is None: return os.path.join(package_path, 'instance') - return os.path.join(base_dir, 'share', self.name + '-instance') + return os.path.join(prefix, 'var', self.name + '-instance') def open_instance_resource(self, resource, mode='rb'): """Opens a resource from the application's instance folder diff --git a/flask/helpers.py b/flask/helpers.py index 89fc82cb..d3ce50b8 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -474,6 +474,43 @@ def get_package_path(name): return os.getcwd() +def find_package(import_name): + """Finds a package and returns the prefix (or None if the package is + not installed) as well as the folder that contains the package or + module as a tuple. + """ + root_mod = sys.modules[import_name.split('.')[0]] + package_path = getattr(root_mod, '__file__', None) + if package_path is None: + package_path = os.getcwd() + else: + package_path = os.path.abspath(os.path.dirname(package_path)) + if hasattr(root_mod, '__path__'): + package_path = os.path.dirname(package_path) + + # leave the egg wrapper folder or the actual .egg on the filesystem + test_package_path = package_path + if os.path.basename(test_package_path).endswith('.egg'): + test_package_path = os.path.dirname(test_package_path) + + site_parent, site_folder = os.path.split(test_package_path) + py_prefix = os.path.abspath(sys.prefix) + if test_package_path.startswith(py_prefix): + return py_prefix, package_path + elif site_folder.lower() == 'site-packages': + parent, folder = os.path.split(site_parent) + # Windows like installations + if folder.lower() == 'lib': + base_dir = parent + # UNIX like installations + elif os.path.basename(parent).lower() == 'lib': + base_dir = os.path.dirname(parent) + else: + base_dir = site_parent + return base_dir, package_path + return None, package_path + + class locked_cached_property(object): """A decorator that converts a function into a lazy property. The function wrapped is called the first time to retrieve the result diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 4b0150af..4404f931 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -1038,7 +1038,7 @@ class InstanceTestCase(unittest.TestCase): try: mod.app = flask.Flask(mod.__name__) self.assertEqual(mod.app.instance_path, - os.path.join(expected_prefix, 'share', + os.path.join(expected_prefix, 'var', 'myapp-instance')) finally: sys.modules['myapp'] = None @@ -1055,7 +1055,7 @@ class InstanceTestCase(unittest.TestCase): try: mod.app = flask.Flask(mod.__name__) self.assertEqual(mod.app.instance_path, - os.path.join(expected_prefix, 'share', + os.path.join(expected_prefix, 'var', 'myapp-instance')) finally: sys.modules['myapp'] = None @@ -1072,7 +1072,7 @@ class InstanceTestCase(unittest.TestCase): try: mod.app = flask.Flask(mod.__name__) self.assertEqual(mod.app.instance_path, - os.path.join(expected_prefix, 'share', + os.path.join(expected_prefix, 'var', 'myapp-instance')) finally: sys.modules['myapp'] = None @@ -1089,7 +1089,7 @@ class InstanceTestCase(unittest.TestCase): try: mod.app = flask.Flask(mod.__name__) self.assertEqual(mod.app.instance_path, - os.path.join(expected_prefix, 'share', + os.path.join(expected_prefix, 'var', 'myapp-instance')) finally: sys.modules['myapp'] = None