code_annotations package#

Subpackages#

Submodules#

code_annotations.annotation_errors module#

List possible annotation error types.

code_annotations.annotation_errors.AnnotationErrorType#

alias of AnnotationError

code_annotations.annotation_errors.add_error_type(message, symbol, description)#

Create an AnnotationErrorType instance and add it to TYPES.

code_annotations.base module#

Click command to do static annotation searching via Stevedore plugins.

class code_annotations.base.AnnotationConfig(config_file_path, report_path_override=None, verbosity=1, source_path_override=None)#

Bases: object

Configuration shared among all Code Annotations commands.

class code_annotations.base.BaseSearch(config)#

Bases: object

Base class for searchers.

check_group(annotations)#

Perform several linting checks on a group of annotations.

The following checks are performed:

  • Choice fields should have a valid value

  • Annotation tokens are valid

  • There is no duplicate

  • All non-optional tokens are present

check_results(all_results)#

Spin through all search results, confirm that they all match configuration.

If errors are found they are added to self.errors.

Parameters:

all_results – Dict of annotations found in search()

Returns:

Boolean indicating whether or not any errors were found

format_file_results(all_results, results)#

Add all extensions’ search results for a file to the overall results.

Parameters:
  • all_results – Aggregated results to add the results to

  • results – Results of search() on a single file

Returns:

None, modifies all_results

iter_groups(annotations)#

Iterate on groups of annotations.

Annotations are considered as a group when they all have the same line_number and optional extra[‘object_id’]. The line number points to the beginning of the annotation group. The object_id is set mostly for annotations parsed from a safelist.

Yields:

annotations (annotation list)

report(all_results, report_prefix='')#

Generate the YAML report of all search results.

Parameters:
  • all_results – Dict of found annotations, indexed by filename

  • report_prefix – Prefix to add to report filename

Returns:

Filename of generated report

abstract search()#

Walk the source tree, send known file types to extensions.

Returns:

annotations} for all files with found annotations.

Return type:

Dict of {filename

code_annotations.cli module#

Command line interface for code annotation tools.

code_annotations.exceptions module#

Custom exceptions for code_annotations.

exception code_annotations.exceptions.ConfigurationException#

Bases: Exception

Exception specific to code annotation configuration problems.

code_annotations.find_django module#

Annotation searcher for Django model comment searching Django introspection.

class code_annotations.find_django.DjangoSearch(config)#

Bases: BaseSearch

Handles Django model comment searching for annotations.

check_coverage()#

Perform checking of coverage percentage based on stats collected in setup and search.

Returns:

Bool indicating whether or not the number of annotated models covers a percentage

of total models needing annotations greater than or equal to the configured coverage_target.

static get_model_id(model)#

Construct the django standard model identifier in “app_label.ModelClassName” notation.

Parameters:

model (django.db.models.Model) – A model for which to create an identifier.

Returns:

identifier string for the given model.

Return type:

str

static get_models_requiring_annotations()#

Determine all local and non-local models via django model introspection.

Note that non-local models returned may contain 1st party models (authored by edX). This is a compromise in accuracy in order to simplify the generation of this list, and also to ease the transition from zero to 100% annotations in edX satellite repositories.

Returns:

2-tuple where the first item is a set of local models, and the second item is a set of non-local models.

Return type:

tuple

static is_non_local(model)#

Determine if the given model is non-local to the current IDA.

Non-local models are all installed models which are not “local”, by definition. “Local” models are installed models which are defined in code which physically lives in the current codebase, where “current codebase” ostensibly refers to the code providing the currently active django project.

Parameters:

model (django.db.models.Model) – A model to check.

Returns:

True if the given model is non-local.

Return type:

bool

list_local_models()#

Dump a list of models in the local code tree that need annotations to stdout.

static requires_annotations(model)#

Return true if the given model actually requires annotations, according to PLAT-2344.

search()#

Introspect the configured Django model docstrings for annotations.

Returns:

Dict of all found annotations keyed by filename

seed_safelist()#

Seed a new safelist file with all non-local models that need to be vetted.

static setup_django()#

Prepare to make django library function calls.

On behalf of the current Django project in the current working directory, setup/load the django framework, specified settings, and apps therein. This should be called before calling any django submodule functions which expect apps to be loaded.

This function is idempotent.

code_annotations.find_static module#

Annotation searcher for static comment searching via Stevedore plugins.

class code_annotations.find_static.StaticSearch(config)#

Bases: BaseSearch

Handles static code searching for annotations.

search()#

Walk the source tree, send known file types to extensions.

Returns:

Dict of all found annotations keyed by filename

search_extension(ext, file_handle, file_extensions_map, filename_extension)#

Execute a search on the given file using the given extension.

Parameters:
  • ext – Extension to execute the search on

  • file_handle – An open file handle search

  • file_extensions_map – Dict mapping of extension names to configured filename extensions

  • filename_extension – The filename extension of the file being searched

Returns:

Tuple of (extension name, list of found annotation dicts)

code_annotations.generate_docs module#

Contains functionality for turning YAML reports into human-readable documentation.

class code_annotations.generate_docs.ReportRenderer(config, report_files)#

Bases: object

Generates human readable documentation from YAML reports.

render()#

Perform the rendering of all documentation using the configured Jinja2 templates.

code_annotations.helpers module#

Helpers for code_annotations scripts.

class code_annotations.helpers.VerboseEcho#

Bases: object

Helper to handle verbosity-dependent logging.

echo(output, verbosity_level=0, **kwargs)#

Echo the given output, if over the verbosity threshold.

Parameters:
  • output – Text to output

  • verbosity_level – Only output if our verbosity level is >= this.

  • kwargs – Any additional keyword args to pass to click.echo

echo_v(output, **kwargs)#

Echo the given output if verbosity level is >= 1.

Parameters:
  • output – Text to output

  • kwargs – Any additional keyword args to pass to click.echo

echo_vv(output, **kwargs)#

Echo the given output if verbosity level is >= 2.

Parameters:
  • output – Text to output

  • kwargs – Any additional keyword args to pass to click.echo

echo_vvv(output, **kwargs)#

Echo the given output if verbosity level is >= 3.

Parameters:
  • output – Text to output

  • kwargs – Any additional keyword args to pass to click.echo

pprint(data, indent=4, verbosity_level=0)#

Pretty-print some data with the given verbosity level.

set_verbosity(verbosity)#

Override the default verbosity level.

Parameters:
  • verbosity – The verbosity level to set to

  • kwargs – Any additional keyword args to pass to click.echo

verbosity = 1#
code_annotations.helpers.clean_abs_path(filename_to_clean, parent_path)#

Safely strips the parent path from the given filename, leaving only the relative path.

Parameters:
  • filename_to_clean – Input filename

  • parent_path – Path to remove from the input

Returns:

Updated path

code_annotations.helpers.clean_annotation(token, data)#

Clean annotation token and data by stripping all trailing/prefix empty spaces.

Parameters:
  • token (str) –

  • data (str) –

Returns:

Tuple of cleaned token, data

Return type:

(str, str)

code_annotations.helpers.fail(msg)#

Log the message and exit.

Parameters:

msg – Message to log

code_annotations.helpers.get_annotation_regex(annotation_regexes)#

Return the full regex to search inside comments for configured annotations.

A successful match against the regex will return two groups of interest: ‘token’ and ‘data’.

This regular expression supports annotation tokens that span multiple lines. To do so, prefix each line after the first by at least two leading spaces. E.g:

Unfortunately, the indenting spaces will find their way to the content of the “token” group.

Parameters:

annotation_regexes – List of re.escaped annotation tokens to search for.

Returns:

Regex ready for searching comments for annotations.

Module contents#

Extensible tools for parsing annotations in codebases.