1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

# Copyright 2013 The Distro Tracker Developers 

# See the COPYRIGHT file at the top-level directory of this distribution and 

# at https://deb.li/DTAuthors 

# 

# This file is part of Distro Tracker. It is subject to the license terms 

# in the LICENSE file found in the top-level directory of this 

# distribution and at https://deb.li/DTLicense. No part of Distro Tracker, 

# including this file, may be copied, modified, propagated, or distributed 

# except according to the terms contained in the LICENSE file. 

 

""" 

A module which defines functions to allow other parts of Distro Tracker to hook 

into the vendor-specific functionality. 

""" 

from django.conf import settings 

 

 

class InvalidPluginException(Exception): 

pass 

 

 

class PluginProcessingError(RuntimeError): 

pass 

 

 

def get_callable(name): 

""" 

Returns a callable object from the vendor-provided module based on the 

string name given as the parameter. 

If no callable object with the given name is found in the vendor module 

an exception is raised. 

 

:param name: The name of the callable which should be returned 

:type name: string 

""" 

import importlib 

if (not hasattr(settings, 'DISTRO_TRACKER_VENDOR_RULES') or 

not settings.DISTRO_TRACKER_VENDOR_RULES): 

raise InvalidPluginException("No vendor specific module set.") 

 

vendor_module = \ 

importlib.import_module(settings.DISTRO_TRACKER_VENDOR_RULES) 

 

function = getattr(vendor_module, name, None) 

45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true if not function: 

raise InvalidPluginException("{name} not found in {module}".format( 

name=name, module=settings.DISTRO_TRACKER_VENDOR_RULES)) 

48 ↛ 49line 48 didn't jump to line 49, because the condition on line 48 was never true if not callable(function): 

raise InvalidPluginException("{name} is not callable.".format( 

name=name)) 

 

return function 

 

 

def call(name, *args, **kwargs): 

""" 

Function which executes the vendor-specific function with the given name by 

passing it the given arguments. 

 

It returns a tuple ``(result, implemented)`` where the values represent: 

 

- result -- the corresponding function's return value. If the function was 

not found, ``None`` is given. 

- implemented -- a Boolean indicating whether the package implements the 

given function. This way clients can differentiate between functions with 

no return value and non-implemented functions. 

 

:param name: The name of the vendor-specific function that should be 

called. 

""" 

try: 

func = get_callable(name) 

except (ImportError, InvalidPluginException): 

return None, False 

 

return func(*args, **kwargs), True