ComplianceAsCode/content

View on GitHub
ssg/controls.py

Summary

Maintainability
C
1 day
Test Coverage
A
91%

File controls.py has 472 lines of code (exceeds 400 allowed). Consider refactoring.
Open

import collections
import os
import copy
from glob import glob

Severity: Minor
Found in ssg/controls.py - About 3 hrs to fix

    Function from_control_dict has 27 lines of code (exceeds 25 allowed). Consider refactoring.
    Open

        def from_control_dict(cls, control_dict, env_yaml=None, default_level=["default"]):
            cls._check_keys(control_dict)
            control = cls()
            control.id = ssg.utils.required_key(control_dict, "id")
            control.title = control_dict.get("title")
    Severity: Minor
    Found in ssg/controls.py - About 1 hr to fix

      Rename field "status"
      Open

              self.status = status
      Severity: Major
      Found in ssg/controls.py by sonar-python

      It's confusing to have a class member with the same name (case differences aside) as its enclosing class. This is particularly so when you consider the common practice of naming a class instance for the class itself.

      Best practice dictates that any field or member with the same name as the enclosing class be renamed to be more descriptive of the particular aspect of the class it represents or holds.

      Noncompliant Code Example

      class Foo:
        foo = ''
      
        def getFoo(self):
          ...
      
      foo = Foo()
      foo.getFoo() # what does this return?
      

      Compliant Solution

      class Foo:
        name = ''
      
        def getName(self):
          ...
      
      foo = Foo()
      foo.getName()
      

      Either remove or fill this block of code.
      Open

                  pass
      Severity: Major
      Found in ssg/controls.py by sonar-python

      Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

      Noncompliant Code Example

      for i in range(3):
          pass
      

      Exceptions

      When a block contains a comment, this block is not considered to be empty.

      Similar blocks of code found in 2 locations. Consider refactoring.
      Open

          def get_control(self, control_id):
              try:
                  c = self.controls_by_id[control_id]
                  return c
              except KeyError:
      Severity: Major
      Found in ssg/controls.py and 1 other location - About 2 hrs to fix
      ssg/controls.py on lines 382..390

      Duplicated Code

      Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

      Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

      When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

      Tuning

      This issue has a mass of 53.

      We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

      The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

      If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

      See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

      Refactorings

      Further Reading

      Similar blocks of code found in 2 locations. Consider refactoring.
      Open

          def get_level(self, level_id):
              try:
                  lv = self.levels_by_id[level_id]
                  return lv
              except KeyError:
      Severity: Major
      Found in ssg/controls.py and 1 other location - About 2 hrs to fix
      ssg/controls.py on lines 372..380

      Duplicated Code

      Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

      Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

      When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

      Tuning

      This issue has a mass of 53.

      We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

      The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

      If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

      See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

      Refactorings

      Further Reading

      Similar blocks of code found in 2 locations. Consider refactoring.
      Open

              try:
                  control = Control.from_control_dict(
                      subtree, self.env_yaml, default_level=self.default_level)
              except Exception as exc:
                  msg = (
      Severity: Minor
      Found in ssg/controls.py and 1 other location - About 45 mins to fix
      ssg/build_yaml.py on lines 1025..1033

      Duplicated Code

      Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:

      Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

      When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).

      Tuning

      This issue has a mass of 35.

      We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.

      The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.

      If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.

      See codeclimate-duplication's documentation for more information about tuning the mass threshold in your .codeclimate.yml.

      Refactorings

      Further Reading

      Ambiguous variable name 'l'
      Open

                      for l in eligible_levels:
      Severity: Minor
      Found in ssg/controls.py by pep8

      Never use the characters 'l', 'O', or 'I' as variable names.

      In some fonts, these characters are indistinguishable from the
      numerals one and zero. When tempted to use 'l', use 'L' instead.
      
      Okay: L = 0
      Okay: o = 123
      Okay: i = 42
      E741: l = 0
      E741: O = 123
      E741: I = 42
      
      Variables can be bound in several other contexts, including class
      and function definitions, 'global' and 'nonlocal' statements,
      exception handlers, and 'with' and 'for' statements.
      In addition, we have a special handling for function parameters.
      
      Okay: except AttributeError as o:
      Okay: with lock as L:
      Okay: foo(l=12)
      Okay: for a in foo(l=12):
      E741: except AttributeError as O:
      E741: with lock as l:
      E741: global I
      E741: nonlocal l
      E741: def foo(l):
      E741: def foo(l=12):
      E741: l = foo(l=12)
      E741: for l in range(10):
      E742: class I(object):
      E743: def l(x):

      Ambiguous variable name 'l'
      Open

              data["levels"] = [l.represent_as_dict() for l in self.levels]
      Severity: Minor
      Found in ssg/controls.py by pep8

      Never use the characters 'l', 'O', or 'I' as variable names.

      In some fonts, these characters are indistinguishable from the
      numerals one and zero. When tempted to use 'l', use 'L' instead.
      
      Okay: L = 0
      Okay: o = 123
      Okay: i = 42
      E741: l = 0
      E741: O = 123
      E741: I = 42
      
      Variables can be bound in several other contexts, including class
      and function definitions, 'global' and 'nonlocal' statements,
      exception handlers, and 'with' and 'for' statements.
      In addition, we have a special handling for function parameters.
      
      Okay: except AttributeError as o:
      Okay: with lock as L:
      Okay: foo(l=12)
      Okay: for a in foo(l=12):
      E741: except AttributeError as O:
      E741: with lock as l:
      E741: global I
      E741: nonlocal l
      E741: def foo(l):
      E741: def foo(l=12):
      E741: l = foo(l=12)
      E741: for l in range(10):
      E742: class I(object):
      E743: def l(x):

      Ambiguous variable name 'l'
      Open

                      eligible_levels = [l for l in self.get_level_with_ancestors_sequence(lv) if l not in levels.keys()]
      Severity: Minor
      Found in ssg/controls.py by pep8

      Never use the characters 'l', 'O', or 'I' as variable names.

      In some fonts, these characters are indistinguishable from the
      numerals one and zero. When tempted to use 'l', use 'L' instead.
      
      Okay: L = 0
      Okay: o = 123
      Okay: i = 42
      E741: l = 0
      E741: O = 123
      E741: I = 42
      
      Variables can be bound in several other contexts, including class
      and function definitions, 'global' and 'nonlocal' statements,
      exception handlers, and 'with' and 'for' statements.
      In addition, we have a special handling for function parameters.
      
      Okay: except AttributeError as o:
      Okay: with lock as L:
      Okay: foo(l=12)
      Okay: for a in foo(l=12):
      E741: except AttributeError as O:
      E741: with lock as l:
      E741: global I
      E741: nonlocal l
      E741: def foo(l):
      E741: def foo(l=12):
      E741: l = foo(l=12)
      E741: for l in range(10):
      E742: class I(object):
      E743: def l(x):

      Line too long (115 > 99 characters)
      Open

                      eligible_levels = [l for l in self.get_level_with_ancestors_sequence(lv) if l not in levels.keys()]
      Severity: Minor
      Found in ssg/controls.py by pep8

      Limit all lines to a maximum of 79 characters.

      There are still many devices around that are limited to 80 character
      lines; plus, limiting windows to 80 characters makes it possible to
      have several windows side-by-side.  The default wrapping on such
      devices looks ugly.  Therefore, please limit all lines to a maximum
      of 79 characters. For flowing long blocks of text (docstrings or
      comments), limiting the length to 72 characters is recommended.
      
      Reports error E501.

      There are no issues that match your filters.

      Category
      Status