class_docstr: Provides a stateful method that returns the number of potential extra
  empty lines needed before and after the currently processed line.
  
  Note: this tracker works on lines that haven't been split yet.  It assumes
  the prefix of the first leaf consists of optional newlines.  Those newlines
  are consumed by `maybe_empty_lines()` and included in the computation.
class_docstr_tok: ["Provides","a","stateful","method","that","returns","the","number","of","potential","extra","empty","lines","needed","before","and","after","the","currently","processed","line",".","Note",":","this","tracker","works","on","lines","that","have","n't","been","split","yet",".","It","assumes","the","prefix","of","the","first","leaf","consists","of","optional","newlines",".","Those","newlines","are","consumed","by","`","maybe_empty_lines","(",")","`","and","included","in","the","computation","."]
docstr: Return the number of extra empty lines before and after the `current_line`.
  
  This is for separating `def`, `async def` and `class` with extra empty
  lines (two on module-level).
code: def maybe_empty_lines(self, current_line: Line) -> LinesBlock:
      """Return the number of extra empty lines before and after the `current_line`.
  
      This is for separating `def`, `async def` and `class` with extra empty
      lines (two on module-level).
      """
      form_feed = (
          Preview.allow_form_feeds in self.mode
          and current_line.depth == 0
          and bool(current_line.leaves)
          and "\f\n" in current_line.leaves[0].prefix
      )
      before, after = self._maybe_empty_lines(current_line)
      previous_after = (
          self.previous_block.after if self.previous_block else 0
      )
      before = (
          # Black should not insert empty lines at the beginning
          # of the file
          0
          if self.previous_line is None
          else before - previous_after
      )
      if (
          Preview.module_docstring_newlines in current_line.mode
          and self.previous_block
          and self.previous_block.previous_block is None
          and len(self.previous_block.original_line.leaves) == 1
          and self.previous_block.original_line.is_docstring
          and not (current_line.is_class or current_line.is_def)
      ):
          before = 1
  
      block = LinesBlock(
          mode=self.mode,
          previous_block=self.previous_block,
          original_line=current_line,
          before=before,
          after=after,
          form_feed=form_feed,
      )
  
      # Maintain the semantic_leading_comment state.
      if current_line.is_comment:
          if self.previous_line is None or (
              not self.previous_line.is_decorator
              # `or before` means this comment already has an empty line before
              and (not self.previous_line.is_comment or before)
              and (self.semantic_leading_comment is None or before)
          ):
              self.semantic_leading_comment = block
      # `or before` means this decorator already has an empty line before
      elif not current_line.is_decorator or before:
          self.semantic_leading_comment = None
  
      self.previous_line = current_line
      self.previous_block = block
      return block
  
imports: import itertools
  import math
  from dataclasses import dataclass, field
  from typing import Callable, Dict, Iterator, List, Optional, Sequence, Tuple, TypeVar, Union, cast
  from black.brackets import COMMA_PRIORITY, DOT_PRIORITY, BracketTracker
  from black.mode import Mode, Preview
  from black.nodes import BRACKETS, CLOSING_BRACKETS, OPENING_BRACKETS, STANDALONE_COMMENT, TEST_DESCENDANTS, child_towards, is_docstring, is_import, is_multiline_string, is_one_sequence_between, is_type_comment, is_type_ignore_comment, is_with_or_async_with_stmt, make_simple_prefix, replace_child, syms, whitespace
  from black.strings import str_width
  from blib2to3.pgen2 import token
  from blib2to3.pytree import Leaf, Node
label_desc: Use image node_id 1 for calling the EmptyLineTracker obj's underlying member method code with example usage: obj.maybe_empty_lines(current_line) and returns: block