class_docstr: Checker for PEP 257, NumPy and Google conventions.
  
  D10x: Missing docstrings
  D20x: Whitespace issues
  D30x: Docstring formatting
  D40x: Docstring content issues
class_docstr_tok: ["Checker","for","PEP","257",",","NumPy","and","Google","conventions",".","D10x",":","Missing","docstrings","D20x",":","Whitespace","issues","D30x",":","Docstring","formatting","D40x",":","Docstring","content","issues"]
docstr: D20{3,4}: Class docstring should have 1 blank line around them.
  
  Insert a blank line before and after all docstrings (one-line or
  multi-line) that document a class -- generally speaking, the class's
  methods are separated from each other by a single blank line, and the
  docstring needs to be offset from the first method by a blank line;
  for symmetry, put a blank line between the class header and the
  docstring.
docstr_tok: ["D20","{","3,4","}",":","Class","docstring","should","have","1","blank","line","around","them",".","Insert","a","blank","line","before","and","after","all","docstrings","(","one-line","or","multi-line",")","that","document","a","class","--","generally","speaking",",","the","class's","methods","are","separated","from","each","other","by","a","single","blank","line",",","and","the","docstring","needs","to","be","offset","from","the","first","method","by","a","blank","line",";","for","symmetry",",","put","a","blank","line","between","the","class","header","and","the","docstring","."]
code: def check_blank_before_after_class(self, class_, docstring):
      """D20{3,4}: Class docstring should have 1 blank line around them.
  
      Insert a blank line before and after all docstrings (one-line or
      multi-line) that document a class -- generally speaking, the class's
      methods are separated from each other by a single blank line, and the
      docstring needs to be offset from the first method by a blank line;
      for symmetry, put a blank line between the class header and the
      docstring.
  
      """
      # NOTE: this gives false-positive in this case
      # class Foo:
      #
      #     """Docstring."""
      #
      #
      # # comment here
      # def foo(): pass
      if docstring:
          before, _, after = class_.source.partition(docstring)
          blanks_before = list(map(is_blank, before.split("\n")[:-1]))
          blanks_after = list(map(is_blank, after.split("\n")[1:]))
          blanks_before_count = sum(
              takewhile(bool, reversed(blanks_before))
          )
          blanks_after_count = sum(takewhile(bool, blanks_after))
          if blanks_before_count != 0:
              yield violations.D211(blanks_before_count)
          if blanks_before_count != 1:
              yield violations.D203(blanks_before_count)
          if not all(blanks_after) and blanks_after_count != 1:
              yield violations.D204(blanks_after_count)
  
imports: import ast
  import string
  import tokenize
  from collections import namedtuple
  from itertools import chain, takewhile
  from re import compile
  from textwrap import dedent
  from .None import violations
  from .config import IllegalConfiguration
  from .parser import AllError, Class, Definition, Function, Method, Module, NestedClass, NestedFunction, Package, ParseError, Parser, StringIO
  from .utils import common_prefix_length, is_blank, log, pairwise, strip_non_alphanumeric
  from .wordlists import IMPERATIVE_BLACKLIST, IMPERATIVE_VERBS, stem
label_desc: Use image node_id 7 for calling the ConventionChecker obj's underlying member method code with example usage: obj.check_blank_before_after_class(class_, docstring) without return types