class_docstr: Abstract class that serves as a base class for anything that
  draws an igraph.Graph.
class_docstr_tok: ["Abstract","class","that","serves","as","a","base","class","for","anything","that","draws","an","igraph.Graph","."]
docstr: Helper method that ensures that I{layout} is an instance
  of L{Layout}. If it is not, the method will try to convert
  it to a L{Layout} according to the following rules:
  
    - If I{layout} is a string, it is assumed to be a name
      of an igraph layout, and it will be passed on to the
      C{layout} method of the given I{graph} if I{graph} is
      not C{None}.
  
    - If I{layout} is C{None} and I{graph} has a "layout"
      attribute, call this same function with the value of that
      attribute.
  
    - If I{layout} is C{None} and I{graph} does not have a "layout"
      attribute, the C{layout} method of I{graph} will be invoked
      with no parameters, which will call the default layout algorithm.
  
    - Otherwise, I{layout} will be passed on to the constructor
      of L{Layout}. This handles lists of lists, lists of tuples
      and such.
  
  If I{layout} is already a L{Layout} instance, it will still
  be copied and a copy will be returned. This is because graph
  drawers are allowed to transform the layout for their purposes,
  and we don't want the transformation to propagate back to the
  caller.
docstr_tok: ["Helper","method","that","ensures","that","I","{","layout","}","is","an","instance","of","L","{","Layout","}",".","If","it","is","not",",","the","method","will","try","to","convert","it","to","a","L","{","Layout","}","according","to","the","following","rules",":","-","If","I","{","layout","}","is","a","string",",","it","is","assumed","to","be","a","name","of","an","igraph","layout",",","and","it","will","be","passed","on","to","the","C","{","layout","}","method","of","the","given","I","{","graph","}","if","I","{","graph","}","is","not","C","{","None","}",".","-","If","I","{","layout","}","is","C","{","None","}","and","I","{","graph","}","has","a","``","layout","''","attribute",",","call","this","same","function","with","the","value","of","that","attribute",".","-","If","I","{","layout","}","is","C","{","None","}","and","I","{","graph","}","does","not","have","a","``","layout","''","attribute",",","the","C","{","layout","}","method","of","I","{","graph","}","will","be","invoked","with","no","parameters",",","which","will","call","the","default","layout","algorithm",".","-","Otherwise",",","I","{","layout","}","will","be","passed","on","to","the","constructor","of","L","{","Layout","}",".","This","handles","lists","of","lists",",","lists","of","tuples","and","such",".","If","I","{","layout","}","is","already","a","L","{","Layout","}","instance",",","it","will","still","be","copied","and","a","copy","will","be","returned",".","This","is","because","graph","drawers","are","allowed","to","transform","the","layout","for","their","purposes",",","and","we","do","n't","want","the","transformation","to","propagate","back","to","the","caller","."]
code: def ensure_layout(layout, graph=None):
      """Helper method that ensures that I{layout} is an instance
      of L{Layout}. If it is not, the method will try to convert
      it to a L{Layout} according to the following rules:
  
        - If I{layout} is a string, it is assumed to be a name
          of an igraph layout, and it will be passed on to the
          C{layout} method of the given I{graph} if I{graph} is
          not C{None}.
  
        - If I{layout} is C{None} and I{graph} has a "layout"
          attribute, call this same function with the value of that
          attribute.
  
        - If I{layout} is C{None} and I{graph} does not have a "layout"
          attribute, the C{layout} method of I{graph} will be invoked
          with no parameters, which will call the default layout algorithm.
  
        - Otherwise, I{layout} will be passed on to the constructor
          of L{Layout}. This handles lists of lists, lists of tuples
          and such.
  
      If I{layout} is already a L{Layout} instance, it will still
      be copied and a copy will be returned. This is because graph
      drawers are allowed to transform the layout for their purposes,
      and we don't want the transformation to propagate back to the
      caller.
      """
      from igraph.layout import Layout  # avoid circular imports
  
      if isinstance(layout, Layout):
          layout = Layout(layout.coords)
      elif isinstance(layout, str):
          layout = graph.layout(layout)
      elif (
          (layout is None)
          and hasattr(graph, "attributes")
          and ("layout" in graph.attributes())
      ):
          layout = AbstractGraphDrawer.ensure_layout(
              graph["layout"], graph=graph
          )
      elif layout is None:
          layout = graph.layout(layout)
      else:
          layout = Layout(layout)
  
      return layout
  
imports: from abc import ABCMeta, abstractmethod
  from math import atan2, pi
  from .text import TextAlignment
  from .utils import get_bezier_control_points_for_curved_edge, evaluate_cubic_bezier
label_desc: Use image node_id 2 for calling the AbstractGraphDrawer obj's underlying member method code with example usage: obj.ensure_layout(layout, graph) and returns: layout