record()   F
last analyzed

Complexity

Conditions 17

Size

Total Lines 84

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
dl 0
loc 84
rs 2.004
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like record() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/python
2
# -*- coding: UTF-8 -*-
3
from niprov.plogging import log
4
from niprov.dependencies import Dependencies
5
from niprov.config import Configuration
6
from capturing import OutputCapture
7
8
9
def record(command, new=None, parents=None, transient=False, args=None, 
10
    kwargs=None, user=None, opts=None, dependencies=Dependencies()):
11
    """Execute a command and log it as provenance for the newly created file.
12
13
    Args:
14
        command (list or str or callable): Command to be executed. Either a 
15
            string of executable system code, a list of components thereof, or 
16
            a python function object. 
17
        new (list or str, optional): Override path to the new file(s), i.e. if 
18
            they cannot be parsed from the command.
19
        parents (list or str, optional): Override paths to parent file(s), i.e. 
20
            if they cannot be parsed from the command.
21
        transient (bool, optional): Set this to True to indicate that the file 
22
            is only temporary and future checks should not expect it to be 
23
            physically present. Defaults to False, assuming that the file 
24
            remains.
25
        args (list, optional): Positional arguments to be passed to command.
26
        kwargs (dict, optional): Keyword arguments to be passed to command.
27
        opts (Configuration): General settings for niprov. 
28
            See :py:mod:`niprov.config`
29
30
    Returns:
31
        dict: New provenance
32
    """
33
    externals = dependencies.getExternals()
34
    listener = dependencies.getListener()
35
    opts = dependencies.reconfigureOrGetConfiguration(opts)
36
37
    # initialize mutable defaults:
38
    if new is None:
39
        new = []
40
    if parents is None:
41
        parents = []
42
    if args is None:
43
        args = []
44
    if kwargs is None:
45
        kwargs = {}
46
47
    # initialize singular/plural ducktyping
48
    if isinstance(new, basestring):
49
        new = [new]
50
    if isinstance(parents, basestring):
51
        parents = [parents]
52
    if isinstance(command, basestring):
53
        command = command.split()
54
55
    # gather tranformation provenance
56
    provenance = {}
57
    if isinstance(command, (list, tuple)): #command bash command list
58
        listener.receivedBashCommand(command)
59
        transformation = command[0]
60
        code = ' '.join(command)
61
        script = None
62
        parsingNew = len(new) == 0
63
        parsingParents = len(parents) == 0
64
        for c in range(len(command)):
65
            if command[c] in ['-out','-o'] and parsingNew:
66
                new.append(command[c+1])
67
            if command[c] in ['-in','-i'] and parsingParents:
68
                parents.append(command[c+1])
69
    else:                                   #command is python code
70
        transformation = command.func_name
71
        script = command.func_code.co_filename
72
        code = None
73
        provenance['args'] = args
74
        provenance['kwargs'] = kwargs
75
    listener.interpretedRecording(new, transformation, parents)
76
77
    # run transformation
78
    if opts.dryrun:
79
        output = None
80
    else:
81
        if isinstance(command, (list, tuple)):
82
            result = externals.run(command)
83
            output = result.output
84
        else:
85
            with OutputCapture() as captured:
86
                command(*args, **kwargs)
87
            output = captured.output
88
89
    # defer the rest to log()
90
    return log(new, transformation, parents, code=code, transient=transient,
91
        logtext=output, script=script, user=user, provenance=provenance, 
92
        opts=opts)
93
94
95