nodes: 0, module; 1, function_definition; 2, function_name:arbitrary_object_to_string; 3, parameters; 4, block; 5, identifier:a_thing; 6, expression_statement; 7, comment:# is it None?; 8, if_statement; 9, comment:# is it already a string?; 10, if_statement; 11, if_statement; 12, comment:# does it have a to_str function?; 13, try_statement; 14, comment:# is this a type proxy?; 15, try_statement; 16, comment:# is it a built in?; 17, try_statement; 18, comment:# is it something from a loaded module?; 19, try_statement; 20, comment:# maybe it has a __name__ attribute?; 21, try_statement; 22, comment:# punt and see what happens if we just cast it to string; 23, return_statement; 24, comment:"""take a python object of some sort, and convert it into a human readable
      string.  this function is used extensively to convert things like "subject"
      into "subject_key, function -> function_key, etc."""; 25, comparison_operator:a_thing is None; 26, block; 27, call; 28, block; 29, boolean_operator; 30, block; 31, block; 32, except_clause; 33, block; 34, except_clause; 35, block; 36, except_clause; 37, block; 38, except_clause; 39, block; 40, except_clause; 41, call; 42, identifier:a_thing; 43, None; 44, return_statement; 45, identifier:isinstance; 46, argument_list; 47, return_statement; 48, attribute; 49, call; 50, try_statement; 51, return_statement; 52, tuple; 53, comment:# AttributeError - no to_str function?; 54, comment:# KeyError - DotDict has no to_str?; 55, comment:# TypeError - problem converting; 56, comment:# nope, no to_str function; 57, block; 58, return_statement; 59, tuple; 60, comment:#; 61, comment:# nope, no a_type property; 62, block; 63, return_statement; 64, tuple; 65, comment:# nope, not a builtin; 66, block; 67, if_statement; 68, identifier:AttributeError; 69, comment:# nope, not one of these; 70, block; 71, return_statement; 72, identifier:AttributeError; 73, comment:# nope, not one of these; 74, block; 75, identifier:str; 76, argument_list; 77, string; 78, identifier:a_thing; 79, attribute; 80, identifier:a_thing; 81, identifier:six; 82, identifier:PY3; 83, identifier:isinstance; 84, argument_list; 85, block; 86, except_clause; 87, call; 88, identifier:AttributeError; 89, identifier:KeyError; 90, identifier:TypeError; 91, pass_statement; 92, call; 93, identifier:AttributeError; 94, identifier:KeyError; 95, identifier:TypeError; 96, pass_statement; 97, subscript; 98, identifier:KeyError; 99, identifier:TypeError; 100, pass_statement; 101, comparison_operator:a_thing.__module__ not in ('__builtin__', 'builtins', 'exceptions'); 102, block; 103, pass_statement; 104, attribute; 105, pass_statement; 106, identifier:a_thing; 107, identifier:six; 108, identifier:string_types; 109, identifier:a_thing; 110, attribute; 111, return_statement; 112, identifier:UnicodeDecodeError; 113, block; 114, attribute; 115, argument_list; 116, identifier:arbitrary_object_to_string; 117, argument_list; 118, identifier:known_mapping_type_to_str; 119, identifier:a_thing; 120, attribute; 121, tuple; 122, if_statement; 123, return_statement; 124, identifier:a_thing; 125, identifier:__name__; 126, identifier:six; 127, identifier:binary_type; 128, call; 129, pass_statement; 130, identifier:a_thing; 131, identifier:to_str; 132, attribute; 133, identifier:a_thing; 134, identifier:__module__; 135, string; 136, string; 137, string; 138, comparison_operator:a_thing.__module__ == "__main__"; 139, block; 140, else_clause; 141, binary_operator:"%s.%s" % (module_name, a_thing.__name__); 142, attribute; 143, argument_list; 144, identifier:a_thing; 145, identifier:a_type; 146, string_content:__builtin__; 147, string_content:builtins; 148, string_content:exceptions; 149, attribute; 150, string:"__main__"; 151, expression_statement; 152, block; 153, string:"%s.%s"; 154, tuple; 155, identifier:a_thing; 156, identifier:decode; 157, string; 158, identifier:a_thing; 159, identifier:__module__; 160, assignment; 161, expression_statement; 162, identifier:module_name; 163, attribute; 164, string_content:utf-8; 165, identifier:module_name; 166, parenthesized_expression; 167, assignment; 168, identifier:a_thing; 169, identifier:__name__; 170, call; 171, identifier:module_name; 172, attribute; 173, attribute; 174, argument_list; 175, identifier:a_thing; 176, identifier:__module__; 177, call; 178, identifier:strip; 179, string; 180, attribute; 181, argument_list; 182, string_content:.; 183, subscript; 184, identifier:replace; 185, string; 186, string; 187, attribute; 188, slice; 189, string_content:/; 190, string_content:.; 191, subscript; 192, identifier:__file__; 193, unary_operator; 194, attribute; 195, string; 196, integer:3; 197, identifier:sys; 198, identifier:modules; 199, string_content:__main__
code: def arbitrary_object_to_string(a_thing):
      """take a python object of some sort, and convert it into a human readable
      string.  this function is used extensively to convert things like "subject"
      into "subject_key, function -> function_key, etc."""
      # is it None?
      if a_thing is None:
          return ''
      # is it already a string?
      if isinstance(a_thing, six.string_types):
          return a_thing
      if six.PY3 and isinstance(a_thing, six.binary_type):
          try:
              return a_thing.decode('utf-8')
          except UnicodeDecodeError:
              pass
      # does it have a to_str function?
      try:
          return a_thing.to_str()
      except (AttributeError, KeyError, TypeError):
          # AttributeError - no to_str function?
          # KeyError - DotDict has no to_str?
          # TypeError - problem converting
          # nope, no to_str function
          pass
      # is this a type proxy?
      try:
          return arbitrary_object_to_string(a_thing.a_type)
      except (AttributeError, KeyError, TypeError):
          #
          # nope, no a_type property
          pass
      # is it a built in?
      try:
          return known_mapping_type_to_str[a_thing]
      except (KeyError, TypeError):
          # nope, not a builtin
          pass
      # is it something from a loaded module?
      try:
          if a_thing.__module__ not in ('__builtin__', 'builtins', 'exceptions'):
              if a_thing.__module__ == "__main__":
                  module_name = (
                      sys.modules['__main__']
                      .__file__[:-3]
                      .replace('/', '.')
                      .strip('.')
                  )
              else:
                  module_name = a_thing.__module__
              return "%s.%s" % (module_name, a_thing.__name__)
      except AttributeError:
          # nope, not one of these
          pass
      # maybe it has a __name__ attribute?
      try:
          return a_thing.__name__
      except AttributeError:
          # nope, not one of these
          pass
      # punt and see what happens if we just cast it to string
      return str(a_thing)