nodes: 0, module; 1, function_definition; 2, function_name:append; 3, parameters; 4, block; 5, identifier:self; 6, identifier:newconfig; 7, expression_statement; 8, comment:# Check for commands where we accept multiple statements (no test_url); 9, for_statement; 10, comment:# Check for single statement commands;; 11, comment:# we do not overwrite existing values.; 12, for_statement; 13, comment:# HEADS UP: PHP → Python port.; 14, if_statement; 15, for_statement; 16, if_statement; 17, comment:""" Append another site config to current instance.
  
          All ``newconfig`` attributes are appended one by one to ours.
          Order matters, eg. current instance values will come first when
          merging.
  
          Thus, if you plan to use some sort of global site config with
          more generic directives, append it last for specific directives
          to be tried first.
  
          .. note:: this method is also aliased to :meth:`merge`.
          """; 18, identifier:attr_name; 19, tuple; 20, comment:# Append to ordered set. We keep ordering, but no duplicates.; 21, block; 22, identifier:attr_name; 23, tuple; 24, block; 25, comparison_operator:self.parser == 'libxml'; 26, block; 27, identifier:attr_name; 28, tuple; 29, comment:# Find/replace strings are lists, we extend.; 30, block; 31, attribute; 32, comment:# This will ease replacements in the extractor.; 33, block; 34, else_clause; 35, string; 36, string; 37, string; 38, string; 39, comment:# `language` is fixed in reset() and; 40, comment:# not supported in siteconfig syntax.; 41, string; 42, string; 43, string; 44, string; 45, string; 46, string; 47, string; 48, expression_statement; 49, for_statement; 50, expression_statement; 51, string; 52, string; 53, string; 54, string; 55, if_statement; 56, attribute; 57, string; 58, expression_statement; 59, string; 60, string; 61, expression_statement; 62, identifier:self; 63, identifier:find_string; 64, expression_statement; 65, block; 66, string_content:title; 67, string_content:body; 68, string_content:author; 69, string_content:date; 70, string_content:strip; 71, string_content:strip_id_or_class; 72, string_content:strip_image_src; 73, string_content:single_page_link; 74, string_content:single_page_link_in_feed; 75, string_content:next_page_link; 76, string_content:http_header; 77, assignment; 78, identifier:val; 79, call; 80, comment:# Too bad ordered set has no .union() method.; 81, block; 82, call; 83, string_content:parser; 84, string_content:tidy; 85, string_content:prune; 86, string_content:autodetect_on_failure; 87, comparison_operator:getattr(self, attr_name) is None; 88, block; 89, identifier:self; 90, identifier:parser; 91, string_content:libxml; 92, assignment; 93, string_content:find_string; 94, string_content:replace_string; 95, call; 96, assignment; 97, expression_statement; 98, identifier:current_set; 99, call; 100, identifier:getattr; 101, argument_list; 102, expression_statement; 103, identifier:setattr; 104, argument_list; 105, call; 106, None; 107, if_statement; 108, attribute; 109, string; 110, attribute; 111, argument_list; 112, attribute; 113, call; 114, assignment; 115, identifier:getattr; 116, argument_list; 117, identifier:newconfig; 118, identifier:attr_name; 119, call; 120, identifier:self; 121, identifier:attr_name; 122, identifier:current_set; 123, identifier:getattr; 124, argument_list; 125, comparison_operator:getattr(newconfig, attr_name) is None; 126, block; 127, else_clause; 128, identifier:self; 129, identifier:parser; 130, string_content:lxml; 131, call; 132, identifier:extend; 133, call; 134, identifier:self; 135, identifier:replace_patterns; 136, identifier:zip; 137, argument_list; 138, attribute; 139, None; 140, identifier:self; 141, identifier:attr_name; 142, attribute; 143, argument_list; 144, identifier:self; 145, identifier:attr_name; 146, call; 147, None; 148, expression_statement; 149, block; 150, identifier:getattr; 151, argument_list; 152, identifier:getattr; 153, argument_list; 154, attribute; 155, attribute; 156, identifier:self; 157, identifier:replace_patterns; 158, identifier:current_set; 159, identifier:add; 160, identifier:val; 161, identifier:getattr; 162, argument_list; 163, call; 164, expression_statement; 165, identifier:self; 166, identifier:attr_name; 167, identifier:newconfig; 168, identifier:attr_name; 169, identifier:self; 170, identifier:find_string; 171, identifier:self; 172, identifier:replace_string; 173, identifier:newconfig; 174, identifier:attr_name; 175, identifier:setattr; 176, argument_list; 177, call; 178, identifier:self; 179, identifier:attr_name; 180, subscript; 181, identifier:setattr; 182, argument_list; 183, attribute; 184, identifier:attr_name; 185, identifier:self; 186, identifier:attr_name; 187, call; 188, identifier:self; 189, identifier:defaults; 190, identifier:getattr; 191, argument_list; 192, identifier:newconfig; 193, identifier:attr_name
code: def append(self, newconfig):
          """ Append another site config to current instance.
  
          All ``newconfig`` attributes are appended one by one to ours.
          Order matters, eg. current instance values will come first when
          merging.
  
          Thus, if you plan to use some sort of global site config with
          more generic directives, append it last for specific directives
          to be tried first.
  
          .. note:: this method is also aliased to :meth:`merge`.
          """
  
          # Check for commands where we accept multiple statements (no test_url)
          for attr_name in (
              'title', 'body', 'author', 'date',
              # `language` is fixed in reset() and
              # not supported in siteconfig syntax.
              'strip', 'strip_id_or_class', 'strip_image_src',
              'single_page_link', 'single_page_link_in_feed',
              'next_page_link', 'http_header'
          ):
              # Append to ordered set. We keep ordering, but no duplicates.
              current_set = getattr(self, attr_name)
              for val in getattr(newconfig, attr_name):
                  # Too bad ordered set has no .union() method.
                  current_set.add(val)
              setattr(self, attr_name, current_set)
  
          # Check for single statement commands;
          # we do not overwrite existing values.
          for attr_name in (
              'parser', 'tidy', 'prune', 'autodetect_on_failure'
          ):
              if getattr(self, attr_name) is None:
                  if getattr(newconfig, attr_name) is None:
                      setattr(self, attr_name, self.defaults[attr_name])
                  else:
                      setattr(self, attr_name, getattr(newconfig, attr_name))
  
          # HEADS UP: PHP → Python port.
          if self.parser == 'libxml':
              self.parser = 'lxml'
  
          for attr_name in ('find_string', 'replace_string', ):
              # Find/replace strings are lists, we extend.
              getattr(self, attr_name).extend(getattr(newconfig, attr_name))
  
          if self.find_string:
              # This will ease replacements in the extractor.
              self.replace_patterns = zip(
                  self.find_string, self.replace_string)
  
          else:
              self.replace_patterns = None