parameters: (strs)
docstring: Yield ``Requirement`` objects for each specification in `strs`
  
      `strs` must be an instance of ``basestring``, or a (possibly-nested)
      iterable thereof.
docstring_summary: Yield ``Requirement`` objects for each specification in `strs`
docstring_tokens: Yield Requirement objects for each specification in strs
function: def parse_requirements(strs):
      """Yield ``Requirement`` objects for each specification in `strs`
  
      `strs` must be an instance of ``basestring``, or a (possibly-nested)
      iterable thereof.
      """
      # create a steppable iterator, so we can handle \-continuations
      lines = iter(yield_lines(strs))
  
      def scan_list(ITEM,TERMINATOR,line,p,groups,item_name):
  
          items = []
  
          while not TERMINATOR(line,p):
              if CONTINUE(line,p):
                  try:
                      line = next(lines)
                      p = 0
                  except StopIteration:
                      raise ValueError(
                          "\\ must not appear on the last nonblank line"
                      )
  
              match = ITEM(line,p)
              if not match:
                  raise ValueError("Expected "+item_name+" in",line,"at",line[p:])
  
              items.append(match.group(*groups))
              p = match.end()
  
              match = COMMA(line,p)
              if match:
                  p = match.end() # skip the comma
              elif not TERMINATOR(line,p):
                  raise ValueError(
                      "Expected ',' or end-of-list in",line,"at",line[p:]
                  )
  
          match = TERMINATOR(line,p)
          if match: p = match.end()   # skip the terminator, if any
          return line, p, items
  
      for line in lines:
          match = DISTRO(line)
          if not match:
              raise ValueError("Missing distribution spec", line)
          project_name = match.group(1)
          p = match.end()
          extras = []
  
          match = OBRACKET(line,p)
          if match:
              p = match.end()
              line, p, extras = scan_list(
                  DISTRO, CBRACKET, line, p, (1,), "'extra' name"
              )
  
          line, p, specs = scan_list(VERSION,LINE_END,line,p,(1,2),"version spec")
          specs = [(op,safe_version(val)) for op,val in specs]
          yield Requirement(project_name, specs, extras)
function_tokens: def parse_requirements ( strs ) : # create a steppable iterator, so we can handle \-continuations lines = iter ( yield_lines ( strs ) ) def scan_list ( ITEM , TERMINATOR , line , p , groups , item_name ) : items = [ ] while not TERMINATOR ( line , p ) : if CONTINUE ( line , p ) : try : line = next ( lines ) p = 0 except StopIteration : raise ValueError ( "\\ must not appear on the last nonblank line" ) match = ITEM ( line , p ) if not match : raise ValueError ( "Expected " + item_name + " in" , line , "at" , line [ p : ] ) items . append ( match . group ( * groups ) ) p = match . end ( ) match = COMMA ( line , p ) if match : p = match . end ( ) # skip the comma elif not TERMINATOR ( line , p ) : raise ValueError ( "Expected ',' or end-of-list in" , line , "at" , line [ p : ] ) match = TERMINATOR ( line , p ) if match : p = match . end ( ) # skip the terminator, if any return line , p , items for line in lines : match = DISTRO ( line ) if not match : raise ValueError ( "Missing distribution spec" , line ) project_name = match . group ( 1 ) p = match . end ( ) extras = [ ] match = OBRACKET ( line , p ) if match : p = match . end ( ) line , p , extras = scan_list ( DISTRO , CBRACKET , line , p , ( 1 , ) , "'extra' name" ) line , p , specs = scan_list ( VERSION , LINE_END , line , p , ( 1 , 2 ) , "version spec" ) specs = [ ( op , safe_version ( val ) ) for op , val in specs ] yield Requirement ( project_name , specs , extras )