code: def parse_decorators(self):
          
          name = []
          arguments = []
          at_arguments = False
  
          while self.current is not None:
              self.log.debug("parsing decorators, current token is %r (%s)",
                             self.current.kind, self.current.value)
              if (self.current.kind == tk.NAME and
                      self.current.value in ['def', 'class']):
                  # Done with decorators - found function or class proper
                  break
              elif self.current.kind == tk.OP and self.current.value == '@':
                  # New decorator found. Store the decorator accumulated so far:
                  self._accumulated_decorators.append(
                      Decorator(''.join(name), ''.join(arguments)))
                  # Now reset to begin accumulating the new decorator:
                  name = []
                  arguments = []
                  at_arguments = False
              elif self.current.kind == tk.OP and self.current.value == '(':
                  at_arguments = True
              elif self.current.kind == tk.OP and self.current.value == ')':
                  # Ignore close parenthesis
                  pass
              elif self.current.kind == tk.NEWLINE or self.current.kind == tk.NL:
                  # Ignore newlines
                  pass
              else:
                  # Keep accumulating current decorator's name or argument.
                  if not at_arguments:
                      name.append(self.current.value)
                  else:
                      arguments.append(self.current.value)
              self.stream.move()
  
          # Add decorator accumulated so far
          self._accumulated_decorators.append(
              Decorator(''.join(name), ''.join(arguments)))
docs: Called after first @ is found.
  
          Parse decorators into self._accumulated_decorators.
          Continue to do so until encountering the 'def' or 'class' start token.