coalib.bears package — coala 0.11.0.rc1 documentation

# coalib.bears package

## Submodules

## coalib.bears.BEAR_KIND module

## coalib.bears.Bear module

class `coalib.bears.Bear.` `Bear`(section: coalib.settings.Section.Section, message_queue, timeout=0)

  Bases: `pyprint.Printer.Printer`, `coalib.output.printers.LogPrinter.LogPrinterMixin`

  A bear contains the actual subroutine that is responsible for checking source code for certain specifications. However it can actually do whatever it wants with the files it gets. If you are missing some Result type, feel free to contact us and/or help us extending the coalib.

  This is the base class for every bear. If you want to write an bear, you will probably want to look at the GlobalBear and LocalBear classes that inherit from this class. In any case you’ll want to overwrite at least the run method. You can send debug/warning/error messages through the debug(), warn(), err() functions. These will send the appropriate messages so that they are outputted. Be aware that if you use err(), you are expected to also terminate the bear run-through immediately.

  Settings are available at all times through self.section.

  To indicate which languages your bear supports, just give it the `LANGUAGES` value which should be a set of string(s):

      >>> from dependency_management.requirements.PackageRequirement import (
      ... PackageRequirement)
      >>> from dependency_management.requirements.PipRequirement import (
      ... PipRequirement)
      >>> class SomeBear(Bear):
      ...     LANGUAGES = {'C', 'CPP','C#', 'D'}

  To indicate the requirements of the bear, assign `REQUIREMENTS` a set with instances of `PackageRequirements`.

      >>> class SomeBear(Bear):
      ...     REQUIREMENTS = {
      ...         PackageRequirement('pip', 'coala_decorators', '0.2.1')}

  If your bear uses requirements from a manager we have a subclass from, you can use the subclass, such as `PipRequirement`, without specifying manager:

      >>> class SomeBear(Bear):
      ...     REQUIREMENTS = {PipRequirement('coala_decorators', '0.2.1')}

  To specify additional attributes to your bear, use the following:

      >>> class SomeBear(Bear):
      ...     AUTHORS = {'Jon Snow'}
      ...     AUTHORS_EMAILS = {'jon_snow@gmail.com'}
      ...     MAINTAINERS = {'Catelyn Stark'}
      ...     MAINTAINERS_EMAILS = {'catelyn_stark@gmail.com'}
      ...     LICENSE = 'AGPL-3.0'
      ...     ASCIINEMA_URL = 'https://asciinema.org/a/80761'

  If the maintainers are the same as the authors, they can be omitted:

      >>> class SomeBear(Bear):
      ...     AUTHORS = {'Jon Snow'}
      ...     AUTHORS_EMAILS = {'jon_snow@gmail.com'}
      >>> SomeBear.maintainers
      {'Jon Snow'}
      >>> SomeBear.maintainers_emails
      {'jon_snow@gmail.com'}

  If your bear needs to include local files, then specify it giving strings containing relative file paths to the INCLUDE_LOCAL_FILES set:

      >>> class SomeBear(Bear):
      ...     INCLUDE_LOCAL_FILES = {'checkstyle.jar', 'google_checks.xml'}

  To keep track easier of what a bear can do, simply tell it to the CAN_FIX and the CAN_DETECT sets. Possible values:

      >>> CAN_DETECT = {'Syntax', 'Formatting', 'Security', 'Complexity', 'Smell',
      ... 'Unused Code', 'Redundancy', 'Variable Misuse', 'Spelling',
      ... 'Memory Leak', 'Documentation', 'Duplication', 'Commented Code',
      ... 'Grammar', 'Missing Import', 'Unreachable Code', 'Undefined Element',
      ... 'Code Simplification'}
      >>> CAN_FIX = {'Syntax', ...}

  Specifying something to CAN_FIX makes it obvious that it can be detected too, so it may be omitted:

      >>> class SomeBear(Bear):
      ...     CAN_DETECT = {'Syntax', 'Security'}
      ...     CAN_FIX = {'Redundancy'}
      >>> list(sorted(SomeBear.can_detect))
      ['Redundancy', 'Security', 'Syntax']

  Every bear has a data directory which is unique to that particular bear:

      >>> class SomeBear(Bear): pass
      >>> class SomeOtherBear(Bear): pass
      >>> SomeBear.data_dir == SomeOtherBear.data_dir
      False

  BEAR_DEPS contains bear classes that are to be executed before this bear gets executed. The results of these bears will then be passed to the run method as a dict via the dependency_results argument. The dict will have the name of the Bear as key and the list of its results as results:

      >>> class SomeBear(Bear): pass
      >>> class SomeOtherBear(Bear):
      ...     BEAR_DEPS = {SomeBear}
      >>> SomeOtherBear.BEAR_DEPS
      {<class 'coalib.bears.Bear.SomeBear'>}

  Every bear resides in some directory which is specified by the source_location attribute:

      >>> class SomeBear(Bear): pass
      >>> SomeBear.source_location
      '...Bear.py'

  Every linter bear makes use of an executable tool for its operations. The SEE_MORE attribute provides a link to the main page of the linter tool:

      >>> class PyLintBear(Bear):
      ...     SEE_MORE = 'https://www.pylint.org/'
      >>> PyLintBear.SEE_MORE
      'https://www.pylint.org/'

  In the future, bears will not survive without aspects. aspects are defined as part of the `class` statement’s parameter list. According to the classic `CAN_DETECT` and `CAN_FIX` attributes, aspects can either be only `'detect'`-able or also `'fix'`-able:

      >>> from coalib.bearlib.aspects.Metadata import CommitMessage

      >>> class aspectsCommitBear(Bear, aspects={
      ...         'detect': [CommitMessage.Shortlog.ColonExistence],
      ...         'fix': [CommitMessage.Shortlog.TrailingPeriod],
      ... }):
      ...     pass

      >>> aspectsCommitBear.aspects['detect']
      [<aspectclass 'Root.Metadata.CommitMessage.Shortlog.ColonExistence'>]
      >>> aspectsCommitBear.aspects['fix']
      [<aspectclass 'Root.Metadata.CommitMessage.Shortlog.TrailingPeriod'>]

  `ASCIINEMA_URL` = ''
  `AUTHORS` = set()
  `AUTHORS_EMAILS` = set()
  `BEAR_DEPS` = set()
  `CAN_DETECT` = set()
  `CAN_FIX` = set()
  `INCLUDE_LOCAL_FILES` = set()
  `LANGUAGES` = set()
  `LICENSE` = ''
  `MAINTAINERS` = set()
  `MAINTAINERS_EMAILS` = set()
  `PLATFORMS` = {'any'}
  `REQUIREMENTS` = set()
  `SEE_MORE` = ''
  `can_detect` = set()
  classmethod `check_prerequisites`()

    Checks whether needed runtime prerequisites of the bear are satisfied.

    This function gets executed at construction.

    Section value requirements shall be checked inside the `run` method. >>> from dependency_management.requirements.PipRequirement import ( ... PipRequirement) >>> class SomeBear(Bear): ... REQUIREMENTS = {PipRequirement(‘pip’)}

        >>> SomeBear.check_prerequisites()
        True

        >>> class SomeOtherBear(Bear):
        ...     REQUIREMENTS = {PipRequirement('really_bad_package')}

        >>> SomeOtherBear.check_prerequisites()
        'really_bad_package is not installed. You can install it using ...'

        >>> class anotherBear(Bear):
        ...     REQUIREMENTS = {PipRequirement('bad_package', '0.0.1')}

        >>> anotherBear.check_prerequisites()
        'bad_package 0.0.1 is not installed. You can install it using ...'

    Returns: | True if prerequisites are satisfied, else False or a string that serves a more detailed description of what’s missing.

  `data_dir` = '/home/coyote/.local/share/coala-bears/Bear'
  `download_cached_file`(url, filename)

    Downloads the file if needed and caches it for the next time. If a download happens, the user will be informed.

    Take a sane simple bear:

        >>> from queue import Queue
        >>> bear = Bear(Section("a section"), Queue())

    We can now carelessly query for a neat file that doesn’t exist yet:

        >>> from os import remove
        >>> if exists(join(bear.data_dir, "a_file")):
        ...     remove(join(bear.data_dir, "a_file"))
        >>> file = bear.download_cached_file("https://github.com/", "a_file")

    If we download it again, it’ll be much faster as no download occurs:

        >>> newfile = bear.download_cached_file("https://github.com/", "a_file")
        >>> newfile == file
        True

    Parameters: | url – The URL to download the file from. filename – The filename it should get, e.g. “test.txt”.
    Returns: | A full path to the file ready for you to use!

  `execute`(*args, **kwargs)
  `get_config_dir`()

    Gives the directory where the configuration file is.

    Returns: | Directory of the config file.

  classmethod `get_metadata`()

    Returns: | Metadata for the run function. However parameters like `self` or parameters implicitly used by coala (e.g. filename for local bears) are already removed.

  classmethod `get_non_optional_settings`(recurse=True)

    This method has to determine which settings are needed by this bear. The user will be prompted for needed settings that are not available in the settings file so don’t include settings where a default value would do.

    Note: This function also queries settings from bear dependencies in recursive manner. Though circular dependency chains are a challenge to achieve, this function would never return on them!

    Parameters: | recurse – Get the settings recursively from its dependencies.
    Returns: | A dictionary of needed settings as keys and a tuple of help text and annotation as values.

  static `kind`()

    Returns: | The kind of the bear

  `log_message`(log_message, timestamp=None, **kwargs)
  `maintainers` = set()
  `maintainers_emails` = set()
  classmethod `missing_dependencies`(lst)

    Checks if the given list contains all dependencies.

    Parameters: | lst – A list of all already resolved bear classes (not instances).
    Returns: | A set of missing dependencies.

  `name` = 'Bear'
  `new_result`

    Returns a partial for creating a result with this bear already bound.

  `run`(*args, *, dependency_results=None, **kwargs)
  `run_bear_from_section`(args, kwargs)
  static `setup_dependencies`()

    This is a user defined function that can download and set up dependencies (via download_cached_file or arbitrary other means) in an OS independent way.

  `source_location` = '/home/coyote/projects/coala/coalib/bears/Bear.py'

## coalib.bears.GlobalBear module

class `coalib.bears.GlobalBear.` `GlobalBear`(file_dict, section, message_queue, timeout=0)

  Bases: `coalib.bears.Bear.Bear`

  A GlobalBear analyzes semantic facts across several files.

  The results of a GlobalBear will be presented grouped by the origin Bear. Therefore Results spanning across multiple files are allowed and will be handled correctly.

  If you are inspecting a single file at a time, you should consider using a LocalBear.

  static `kind`()
  `run`(*args, *, dependency_results=None, **kwargs)

    Handles all files in file_dict.

    Parameters: | dependency_results – The dictionary of {bear name: result list}.
    Returns: | A list of Result type.

    See `coalib.bears.Bear` for run method description.

## coalib.bears.LocalBear module

class `coalib.bears.LocalBear.` `LocalBear`(section: coalib.settings.Section.Section, message_queue, timeout=0)

  Bases: `coalib.bears.Bear.Bear`

  A LocalBear is a Bear that analyzes only one file at once. It therefore can not analyze semantical facts over multiple files.

  This has the advantage that it can be highly parallelized. In addition, the results from multiple bears for one file can be shown together for that file, which is better to grasp for the user. coala takes care of all that.

  Examples for LocalBear’s could be:

  - A SpaceConsistencyBear that checks every line for trailing whitespaces, tabs, etc.
  - A VariableNameBear that checks variable names and constant names for certain conditions
  classmethod `get_metadata`()
  static `kind`()
  `run`(filename, file, *args, *, dependency_results=None, **kwargs)

    Handles the given file.

    Parameters: | filename – The filename of the file file – The file contents as string array
    Returns: | A list of Result

## coalib.bears.meta module

class `coalib.bears.meta.` `bearclass`(clsname, bases, clsattrs, *varargs, *, aspects=None)

  Bases: `type`

  Metaclass for `coalib.bears.Bear.Bear` and therefore all bear classes.

  Pushing bears into the future... ;)

  `aspects` = defaultdict(<function bearclass.<lambda>>, {})

## Module contents