Ticket #16675: importutils.diff
File importutils.diff, 5.8 KB (added by , 13 years ago) |
---|
-
django/utils/importlib.py
diff --git a/django/utils/importlib.py b/django/utils/importlib.py index ef4d0e4..fe3f546 100644
a b def import_module(name, package=None): 34 34 name = _resolve_name(name[level:], package, level) 35 35 __import__(name) 36 36 return sys.modules[name] 37 38 39 def import_attribute(name, exception_handler=None): 40 """ 41 Loads an object from an 'name', like in MIDDLEWARE_CLASSES and the likes. 42 43 Import paths should be: "mypackage.mymodule.MyObject". It then imports the 44 module up until the last dot and tries to get the attribute after that dot 45 from the imported module. 46 47 If the import path does not contain any dots, a TypeError is raised. 48 49 If the module cannot be imported, an ImportError is raised. 50 51 If the attribute does not exist in the module, a AttributeError is raised. 52 53 You can provide custom error handling using the optional exception_handler 54 argument which gets called with the exception type, the exception value and 55 the traceback object if there is an error during loading. 56 57 The exception_handler is not called if an invalid import path (one without 58 a dot in it) is provided. 59 """ 60 if '.' not in name: 61 raise TypeError("'name' argument to " 62 "'django.utils.importlib.import_attribute' must " 63 "contain at least one dot.") 64 module_name, object_name = name.rsplit('.', 1) 65 try: 66 module = import_module(module_name) 67 except: 68 if callable(exception_handler): 69 exctype, excvalue, tb = sys.exc_info() 70 return exception_handler(name, exctype, excvalue, tb) 71 else: 72 raise 73 try: 74 return getattr(module, object_name) 75 except: 76 if callable(exception_handler): 77 exctype, excvalue, tb = sys.exc_info() 78 return exception_handler(name, exctype, excvalue, tb) 79 else: 80 raise 81 82 83 def iter_import_attributes(names, exception_handler=None): 84 """ 85 Calls django.contrib.load.import_attribute on all items in the iterable 86 names and returns a generator that yields the objects to be loaded. 87 88 The exception_handler is propagated to import_attribute. 89 90 If the exception_handler does not return anything or returns None, the 91 value is ignored. 92 """ 93 for name in names: 94 next = import_attribute(name, exception_handler) 95 if next: 96 yield next -
new file tests/regressiontests/utils/importlib.py
diff --git a/tests/regressiontests/utils/importlib.py b/tests/regressiontests/utils/importlib.py new file mode 100644 index 0000000..bccd0ce
- + 1 # -*- coding: utf-8 -*- 2 from __future__ import with_statement 3 from django.contrib.auth.models import User, AnonymousUser 4 from django.test.testcases import TestCase 5 from django.utils.importlib import import_attribute, iter_import_attributes 6 7 8 class LoadTests(TestCase): 9 10 def test_import_attribute(self): 11 obj = import_attribute('django.contrib.auth.models.User') 12 self.assertEqual(obj, User) 13 14 def test_import_attribute_fail_type(self): 15 self.assertRaises(TypeError, import_attribute, 'notanimportpath') 16 17 def test_import_attribute_fail_import(self): 18 self.assertRaises(ImportError, import_attribute, 19 'django.contrib.auth.not_models.User') 20 21 def test_import_attribute_fail_attribute(self): 22 self.assertRaises(AttributeError, import_attribute, 23 'django.contrib.auth.models.NotAUser') 24 25 def test_import_attribute_exception_handler(self): 26 class MyException(Exception): pass 27 def exc_handler(*args, **kwargs): 28 raise MyException 29 self.assertRaises(MyException, import_attribute, 30 'django.contrib.auth.models.NotAUser', exc_handler) 31 self.assertRaises(MyException, import_attribute, 32 'django.contrib.auth.not_models.User', exc_handler) 33 self.assertRaises(TypeError, import_attribute, 'notanimportpath') 34 35 def test_iter_import_attributes(self): 36 import_paths = ['django.contrib.auth.models.User', 37 'django.contrib.auth.models.AnonymousUser'] 38 objs = list(iter_import_attributes(import_paths)) 39 self.assertEqual(len(objs), 2) 40 self.assertEqual(objs[0], User) 41 self.assertEqual(objs[1], AnonymousUser) 42 43 def test_iter_import_attributes_propagates_exception_handler(self): 44 class MyException(Exception): pass 45 def exc_handler(*args, **kwargs): 46 raise MyException 47 gen = iter_import_attributes(['django.contrib.auth.models.User', 48 'django.contrib.auth.models.NotAUser'], 49 exc_handler) 50 user = gen.next() 51 self.assertEqual(user, User) 52 self.assertRaises(MyException, gen.next) 53 54 def test_iter_import_attributes_ignore_exceptions(self): 55 def exc_handler(*args, **kwargs): 56 pass 57 58 import_paths = ['django.contrib.auth.models.User', 59 'django.contrib.auth.models.NotAUser', 60 'django.contrib.auth.models.AnonymousUser'] 61 objs = list(iter_import_attributes(import_paths, exc_handler)) 62 self.assertEqual(len(objs), 2) 63 self.assertEqual(objs[0], User) 64 self.assertEqual(objs[1], AnonymousUser) -
tests/regressiontests/utils/tests.py
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py index e91adc9..242b7e2 100644
a b from datetime_safe import * 20 20 from baseconv import * 21 21 from jslex import * 22 22 from ipv6 import * 23 from importlib import *