Browse Source

Instance paths are now moved into virtualenv/share/appname-instance if installed

pull/302/head
Armin Ronacher 14 years ago
parent
commit
175d43b2f9
  1. 41
      flask/app.py
  2. 4
      flask/helpers.py
  3. 57
      tests/flask_tests.py

41
flask/app.py

@ -447,6 +447,23 @@ class Flask(_PackageBoundObject):
error_handlers = property(_get_error_handlers, _set_error_handlers) error_handlers = property(_get_error_handlers, _set_error_handlers)
del _get_error_handlers, _set_error_handlers del _get_error_handlers, _set_error_handlers
@locked_cached_property
def name(self):
"""The name of the application. This is usually the import name
with the difference that it's guessed from the run file if the
import name is main. This name is used as a display name when
Flask needs the name of the application. It can be set and overriden
to change the value.
.. versionadded:: 0.8
"""
if self.import_name == '__main__':
fn = getattr(sys.modules['__main__'], '__file__', None)
if fn is None:
return 'unknown'
return os.path.splitext(os.path.basename(fn))[0]
return self.import_name
@property @property
def propagate_exceptions(self): def propagate_exceptions(self):
"""Returns the value of the `PROPAGATE_EXCEPTIONS` configuration """Returns the value of the `PROPAGATE_EXCEPTIONS` configuration
@ -545,14 +562,26 @@ class Flask(_PackageBoundObject):
.. versionadded:: 0.8 .. versionadded:: 0.8
""" """
root_mod = sys.modules[self.import_name.split('.')[0]] root_mod = sys.modules[self.import_name.split('.')[0]]
instance_path = None # 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__'): if hasattr(root_mod, '__path__'):
package_dir = os.path.dirname(root_mod.__file__) package_path = os.path.dirname(package_path)
instance_path = os.path.join(package_dir, os.path.pardir) 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)
if folder.lower() == 'lib':
base_dir = parent
else:
base_dir = site_parent
else: else:
instance_path = os.path.dirname(root_mod.__file__) return os.path.join(package_path, 'instance')
basedir = os.path.normpath(os.path.abspath(instance_path)) return os.path.join(base_dir, 'share', self.name + '-instance')
return os.path.join(basedir, 'instance')
def open_instance_resource(self, resource, mode='rb'): def open_instance_resource(self, resource, mode='rb'):
"""Opens a resource from the application's instance folder """Opens a resource from the application's instance folder

4
flask/helpers.py

@ -466,7 +466,7 @@ def send_from_directory(directory, filename, **options):
return send_file(filename, conditional=True, **options) return send_file(filename, conditional=True, **options)
def _get_package_path(name): def get_package_path(name):
"""Returns the path to a package or cwd if that cannot be found.""" """Returns the path to a package or cwd if that cannot be found."""
try: try:
return os.path.abspath(os.path.dirname(sys.modules[name].__file__)) return os.path.abspath(os.path.dirname(sys.modules[name].__file__))
@ -512,7 +512,7 @@ class _PackageBoundObject(object):
self.template_folder = template_folder self.template_folder = template_folder
#: Where is the app root located? #: Where is the app root located?
self.root_path = _get_package_path(self.import_name) self.root_path = get_package_path(self.import_name)
self._static_folder = None self._static_folder = None
self._static_url_path = None self._static_url_path = None

57
tests/flask_tests.py

@ -1005,7 +1005,10 @@ class BasicFunctionalityTestCase(unittest.TestCase):
rv = c.post('/foo', data={}, follow_redirects=True) rv = c.post('/foo', data={}, follow_redirects=True)
self.assertEqual(rv.data, 'success') self.assertEqual(rv.data, 'success')
def test_basic_instance_paths(self):
class InstanceTestCase(unittest.TestCase):
def test_uninstalled_module_paths(self):
here = os.path.abspath(os.path.dirname(__file__)) here = os.path.abspath(os.path.dirname(__file__))
app = flask.Flask(__name__) app = flask.Flask(__name__)
self.assertEqual(app.instance_path, os.path.join(here, 'instance')) self.assertEqual(app.instance_path, os.path.join(here, 'instance'))
@ -1020,9 +1023,60 @@ class BasicFunctionalityTestCase(unittest.TestCase):
else: else:
self.fail('Expected value error') self.fail('Expected value error')
def test_uninstalled_package_paths(self):
from blueprintapp import app from blueprintapp import app
here = os.path.abspath(os.path.dirname(__file__))
self.assertEqual(app.instance_path, os.path.join(here, 'instance')) self.assertEqual(app.instance_path, os.path.join(here, 'instance'))
def test_installed_module_paths(self):
import types
expected_prefix = os.path.abspath('foo')
mod = types.ModuleType('myapp')
mod.__file__ = os.path.join(expected_prefix, 'lib',
'site-packages', 'myapp.py')
sys.modules['myapp'] = mod
try:
mod.app = flask.Flask(mod.__name__)
self.assertEqual(mod.app.instance_path,
os.path.join(expected_prefix, 'share',
'myapp-instance'))
finally:
sys.modules['myapp'] = None
def test_installed_package_paths(self):
import types
expected_prefix = os.path.abspath('foo')
package_path = os.path.join(expected_prefix, 'lib',
'site-packages', 'myapp')
mod = types.ModuleType('myapp')
mod.__path__ = [package_path]
mod.__file__ = os.path.join(package_path, '__init__.py')
sys.modules['myapp'] = mod
try:
mod.app = flask.Flask(mod.__name__)
self.assertEqual(mod.app.instance_path,
os.path.join(expected_prefix, 'share',
'myapp-instance'))
finally:
sys.modules['myapp'] = None
def test_prefix_installed_paths(self):
import types
expected_prefix = os.path.abspath(sys.prefix)
package_path = os.path.join(expected_prefix, 'lib',
'site-packages', 'myapp')
mod = types.ModuleType('myapp')
mod.__path__ = [package_path]
mod.__file__ = os.path.join(package_path, '__init__.py')
sys.modules['myapp'] = mod
try:
mod.app = flask.Flask(mod.__name__)
self.assertEqual(mod.app.instance_path,
os.path.join(expected_prefix, 'share',
'myapp-instance'))
finally:
sys.modules['myapp'] = None
class JSONTestCase(unittest.TestCase): class JSONTestCase(unittest.TestCase):
@ -2114,6 +2168,7 @@ def suite():
suite.addTest(unittest.makeSuite(SubdomainTestCase)) suite.addTest(unittest.makeSuite(SubdomainTestCase))
suite.addTest(unittest.makeSuite(ViewTestCase)) suite.addTest(unittest.makeSuite(ViewTestCase))
suite.addTest(unittest.makeSuite(DeprecationsTestCase)) suite.addTest(unittest.makeSuite(DeprecationsTestCase))
suite.addTest(unittest.makeSuite(InstanceTestCase))
if flask.json_available: if flask.json_available:
suite.addTest(unittest.makeSuite(JSONTestCase)) suite.addTest(unittest.makeSuite(JSONTestCase))
if flask.signals_available: if flask.signals_available:

Loading…
Cancel
Save