Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/django/utils/deconstruct.py: 35%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

23 statements  

1from importlib import import_module 

2 

3from django.utils.version import get_docs_version 

4 

5 

6def deconstructible(*args, path=None): 

7 """ 

8 Class decorator that allows the decorated class to be serialized 

9 by the migrations subsystem. 

10 

11 The `path` kwarg specifies the import path. 

12 """ 

13 

14 def decorator(klass): 

15 def __new__(cls, *args, **kwargs): 

16 # We capture the arguments to make returning them trivial 

17 obj = super(klass, cls).__new__(cls) 

18 obj._constructor_args = (args, kwargs) 

19 return obj 

20 

21 def deconstruct(obj): 

22 """ 

23 Return a 3-tuple of class import path, positional arguments, 

24 and keyword arguments. 

25 """ 

26 # Fallback version 

27 if path and type(obj) is klass: 

28 module_name, _, name = path.rpartition(".") 

29 else: 

30 module_name = obj.__module__ 

31 name = obj.__class__.__name__ 

32 # Make sure it's actually there and not an inner class 

33 module = import_module(module_name) 

34 if not hasattr(module, name): 

35 raise ValueError( 

36 "Could not find object %s in %s.\n" 

37 "Please note that you cannot serialize things like inner " 

38 "classes. Please move the object into the main module " 

39 "body to use migrations.\n" 

40 "For more information, see " 

41 "https://docs.djangoproject.com/en/%s/topics/migrations/" 

42 "#serializing-values" % (name, module_name, get_docs_version()) 

43 ) 

44 return ( 

45 ( 

46 path 

47 if path and type(obj) is klass 

48 else f"{obj.__class__.__module__}.{name}" 

49 ), 

50 obj._constructor_args[0], 

51 obj._constructor_args[1], 

52 ) 

53 

54 klass.__new__ = staticmethod(__new__) 

55 klass.deconstruct = deconstruct 

56 

57 return klass 

58 

59 if not args: 

60 return decorator 

61 return decorator(*args)