Test Failed
Pull Request — master (#15)
by
unknown
02:15
created

LocalizedFileFieldForm.clean()   F

Complexity

Conditions 28

Size

Total Lines 64

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 812

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 28
c 1
b 0
f 1
dl 0
loc 64
rs 2.995
ccs 0
cts 0
cp 0
crap 812

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 LocalizedFileFieldForm.clean() 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 1
from typing import List
0 ignored issues
show
Configuration introduced by
The import typing could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
2
3 1
from django import forms
0 ignored issues
show
Configuration introduced by
The import django could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
4 1
from django.conf import settings
0 ignored issues
show
Configuration introduced by
The import django.conf could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
5
from django.core.exceptions import ValidationError
0 ignored issues
show
Configuration introduced by
The import django.core.exceptions could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
6 1
from django.forms.widgets import FILE_INPUT_CONTRADICTION
0 ignored issues
show
Configuration introduced by
The import django.forms.widgets could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
7 1
8
from .value import LocalizedValue, LocalizedStringValue, \
9
    LocalizedFileValue
10 1
from .widgets import LocalizedFieldWidget, LocalizedCharFieldWidget, \
11
    LocalizedFileWidget
12
13
14 1
class LocalizedFieldForm(forms.MultiValueField):
15 1
    """Form for a localized field, allows editing
16
    the field in multiple languages."""
17 1
18
    widget = LocalizedFieldWidget
19
    field_class = forms.fields.CharField
20 1
    value_class = LocalizedValue
21
22 1
    def __init__(self, *args, **kwargs):
23 1
        """Initializes a new instance of :see:LocalizedFieldForm."""
24
25 1
        fields = []
26 1
27
        for lang_code, _ in settings.LANGUAGES:
28 1
            field_options = {'required': False}
29 1
30
            if lang_code == settings.LANGUAGE_CODE:
31 1
                field_options['required'] = kwargs.get('required', True)
32
33
            field_options['label'] = lang_code
34
            fields.append(self.field_class(**field_options))
0 ignored issues
show
Coding Style introduced by
Usage of * or ** arguments should usually be done with care.

Generally, there is nothing wrong with usage of * or ** arguments. For readability of the code base, we suggest to not over-use these language constructs though.

For more information, we can recommend this blog post from Ned Batchelder including its comments which also touches this aspect.

Loading history...
35
36
        super(LocalizedFieldForm, self).__init__(
37 1
            fields,
38 1
            require_all_fields=False,
39
            *args, **kwargs
40 1
        )
41
        # set 'required' attribute for each widget separately
42
        for f, w in zip(self.fields, self.widget.widgets):
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFieldForm does not seem to have a member named fields.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
Bug introduced by
The Class LocalizedFieldWidget does not seem to have a member named widgets.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
43
            w.is_required = f.required
44
45
    def compress(self, value: List[str]) -> value_class:
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'value_class'
Loading history...
46
        """Compresses the values from individual fields
47
        into a single :see:LocalizedValue instance.
48
49
        Arguments:
50
            value:
51
                The values from all the widgets.
52
53 1
        Returns:
54
            A :see:LocalizedValue containing all
55 1
            the value in several languages.
56 1
        """
57
58 1
        localized_value = self.value_class()
59
60
        for (lang_code, _), value in zip(settings.LANGUAGES, value):
61
            localized_value.set(lang_code, value)
62
63
        return localized_value
64
65
66
class LocalizedCharFieldForm(LocalizedFieldForm):
67
    """Form for a localized char field, allows editing
68
    the field in multiple languages."""
69
70
    widget = LocalizedCharFieldWidget
71
    value_class = LocalizedStringValue
72
73
74
class LocalizedTextFieldForm(LocalizedFieldForm):
75
    """Form for a localized text field, allows editing
76
    the field in multiple languages."""
77
78
    value_class = LocalizedStringValue
79
80
81
class LocalizedFileFieldForm(LocalizedFieldForm, forms.FileField):
82
    """Form for a localized file field, allows editing
83
    the field in multiple languages."""
84
85
    widget = LocalizedFileWidget
86
    field_class = forms.fields.FileField
87
    value_class = LocalizedFileValue
88
89
    def clean(self, value, initial=None):
90
        """
91
        Most part of this method is a copy of 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
92
        django.forms.MultiValueField.clean, with the exception of initial
93
        value handling (this need for correct processing FileField's).
94
        All original comments saved.
95
        """
96
        if initial is None:
97
            initial = [None for x in range(0, len(value))]
98
        else:
99
            if not isinstance(initial, list):
100
                initial = self.widget.decompress(initial)
101
102
        clean_data = []
103
        errors = []
104
        if not value or isinstance(value, (list, tuple)):
105
            if (not value or not [v for v in value if
106
                                  v not in self.empty_values]) \
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named empty_values.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
107
                    and (not initial or not [v for v in initial if
108
                                             v not in self.empty_values]):
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named empty_values.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
109
                if self.required:
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named required.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
110
                    raise ValidationError(self.error_messages['required'],
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named error_messages.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
111
                                          code='required')
112
        else:
113
            raise ValidationError(self.error_messages['invalid'],
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named error_messages.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
114
                                  code='invalid')
115
        for i, field in enumerate(self.fields):
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named fields.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
116
            try:
117
                field_value = value[i]
118
            except IndexError:
119
                field_value = None
120
            try:
121
                field_initial = initial[i]
122
            except IndexError:
123
                field_initial = None
124
            if field_value in self.empty_values and \
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named empty_values.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
125
                            field_initial in self.empty_values:
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named empty_values.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
126
                if self.require_all_fields:
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named require_all_fields.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
127
                    # Raise a 'required' error if the MultiValueField is
128
                    # required and any field is empty.
129
                    if self.required:
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named required.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
130
                        raise ValidationError(self.error_messages['required'],
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named error_messages.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
131
                                              code='required')
132
                elif field.required:
133
                    # Otherwise, add an 'incomplete' error to the list of
134
                    # collected errors and skip field cleaning, if a required
135
                    # field is empty.
136
                    if field.error_messages['incomplete'] not in errors:
137
                        errors.append(field.error_messages['incomplete'])
138
                    continue
139
            try:
140
                clean_data.append(field.clean(field_value, field_initial))
141
            except ValidationError as e:
142
                # Collect all validation errors in a single list, which we'll
143
                # raise at the end of clean(), rather than raising a single
144
                # exception for the first error we encounter. Skip duplicates.
145
                errors.extend(m for m in e.error_list if m not in errors)
146
        if errors:
147
            raise ValidationError(errors)
148
149
        out = self.compress(clean_data)
150
        self.validate(out)
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named validate.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
151
        self.run_validators(out)
0 ignored issues
show
Bug introduced by
The Instance of LocalizedFileFieldForm does not seem to have a member named run_validators.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
152
        return out
153
154
    def bound_data(self, data, initial):
155
        bound_data = []
156
        if initial is None:
157
            initial = [None for x in range(0, len(data))]
158
        else:
159
            if not isinstance(initial, list):
160
                initial = self.widget.decompress(initial)
161
        for d, i in zip(data, initial):
162
            if d in (None, FILE_INPUT_CONTRADICTION):
163
                bound_data.append(i)
164
            else:
165
                bound_data.append(d)
166
        return bound_data
167