parser.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # MODIFIED - Replace/Update with care
  2. import os
  3. import warnings
  4. import re
  5. from .requirement import Requirement
  6. def parse(req_str_or_file):
  7. """
  8. Parse a requirements file into a list of Requirements
  9. See: pip/req.py:parse_requirements() and
  10. https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format
  11. :param req_str_or_file: a string or file like object containing requirements
  12. :returns: a *generator* of Requirement objects
  13. """
  14. filename = getattr(req_str_or_file, 'name', None)
  15. reqstr = req_str_or_file
  16. try:
  17. # Python 2.x compatibility
  18. if not isinstance(req_str_or_file, basestring):
  19. reqstr = req_str_or_file.read()
  20. except NameError:
  21. # Python 3.x only
  22. if not isinstance(req_str_or_file, str):
  23. reqstr = req_str_or_file.read()
  24. # To deal with lines broken via a backslash
  25. initial_zero_based_line_idx = 0
  26. accumulator_line_parts = []
  27. for zero_based_line_idx, original_line in enumerate(reqstr.splitlines()):
  28. if original_line.endswith('\\'):
  29. accumulator_line_parts.append(original_line.rstrip('\\'))
  30. continue
  31. # Construct a full line from pieces broken by backslashes
  32. accumulator_line_parts.append(original_line)
  33. original_line_idxs = (initial_zero_based_line_idx, zero_based_line_idx)
  34. initial_zero_based_line_idx = zero_based_line_idx + 1
  35. line = ' '.join(accumulator_line_parts)
  36. accumulator_line_parts = []
  37. line = line.strip()
  38. if line == '':
  39. continue
  40. elif not line or line.startswith('#'):
  41. # comments are lines that start with # only
  42. continue
  43. elif line.startswith('--trusted-host'):
  44. # unsupported
  45. continue
  46. elif line.startswith('-r') or line.startswith('--requirement'):
  47. new_filename = line.split()[1]
  48. new_file_path = os.path.join(os.path.dirname(filename or '.'),
  49. new_filename)
  50. with open(new_file_path) as f:
  51. for requirement in parse(f):
  52. yield requirement
  53. elif line.startswith('-f') or line.startswith('--find-links') or \
  54. line.startswith('-i') or line.startswith('--index-url') or \
  55. line.startswith('--extra-index-url') or \
  56. line.startswith('--no-index'):
  57. warnings.warn('Private repos not supported. Skipping.')
  58. continue
  59. elif line.startswith('-Z') or line.startswith('--always-unzip'):
  60. warnings.warn('Unused option --always-unzip. Skipping.')
  61. continue
  62. elif line.startswith('-'):
  63. warnings.warn('Line starts with an option (%s). Skipping.' % \
  64. line.split()[0])
  65. continue
  66. else:
  67. req = Requirement.parse(line)
  68. req.provenance = (
  69. filename,
  70. original_line_idxs[0] + 1,
  71. original_line_idxs[1] + 1,
  72. )
  73. yield req