Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
pip._internal.req.req_file Namespace Reference

Data Structures

class  OptionParsingError
 
class  ParsedLine
 
class  ParsedRequirement
 
class  RequirementsFileParser
 

Functions

Generator[ParsedRequirement, None, Noneparse_requirements (str filename, PipSession session, Optional["PackageFinder"] finder=None, Optional[optparse.Values] options=None, bool constraint=False)
 
ReqFileLines preprocess (str content)
 
ParsedRequirement handle_requirement_line (ParsedLine line, Optional[optparse.Values] options=None)
 
None handle_option_line (Values opts, str filename, int lineno, Optional["PackageFinder"] finder=None, Optional[optparse.Values] options=None, Optional[PipSession] session=None)
 
Optional[ParsedRequirementhandle_line (ParsedLine line, Optional[optparse.Values] options=None, Optional["PackageFinder"] finder=None, Optional[PipSession] session=None)
 
LineParser get_line_parser (Optional["PackageFinder"] finder)
 
Tuple[str, str] break_args_options (str line)
 
optparse.OptionParser build_parser ()
 
ReqFileLines join_lines (ReqFileLines lines_enum)
 
ReqFileLines ignore_comments (ReqFileLines lines_enum)
 
ReqFileLines expand_env_variables (ReqFileLines lines_enum)
 
Tuple[str, str] get_file_content (str url, PipSession session)
 

Variables

 ReqFileLines = Iterable[Tuple[int, str]]
 
 LineParser = Callable[[str], Tuple[str, Values]]
 
 SCHEME_RE = re.compile(r"^(http|https|file):", re.I)
 
 COMMENT_RE = re.compile(r"(^|\s+)#.*$")
 
 ENV_VAR_RE = re.compile(r"(?P<var>\$\{(?P<name>[A-Z0-9_]+)\})")
 
list SUPPORTED_OPTIONS
 
list SUPPORTED_OPTIONS_REQ
 
list SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ]
 
 logger = logging.getLogger(__name__)
 

Detailed Description

Requirements file parsing

Function Documentation

◆ break_args_options()

Tuple[str, str] break_args_options ( str  line)
Break up the line into an args and options string.  We only want to shlex
(and then optparse) the options, not the args.  args can contain markers
which are corrupted by shlex.

Definition at line 416 of file req_file.py.

416def break_args_options(line: str) -> Tuple[str, str]:
417 """Break up the line into an args and options string. We only want to shlex
418 (and then optparse) the options, not the args. args can contain markers
419 which are corrupted by shlex.
420 """
421 tokens = line.split(" ")
422 args = []
423 options = tokens[:]
424 for token in tokens:
425 if token.startswith("-") or token.startswith("--"):
426 break
427 else:
428 args.append(token)
429 options.pop(0)
430 return " ".join(args), " ".join(options)
431
432
for i

References i.

Referenced by pip._internal.req.req_file.get_line_parser().

Here is the caller graph for this function:

◆ build_parser()

optparse.OptionParser build_parser ( )
Return a parser for parsing requirement lines

Definition at line 438 of file req_file.py.

438def build_parser() -> optparse.OptionParser:
439 """
440 Return a parser for parsing requirement lines
441 """
442 parser = optparse.OptionParser(add_help_option=False)
443
444 option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ
445 for option_factory in option_factories:
446 option = option_factory()
447 parser.add_option(option)
448
449 # By default optparse sys.exits on parsing errors. We want to wrap
450 # that in our own exception.
451 def parser_exit(self: Any, msg: str) -> "NoReturn":
452 raise OptionParsingError(msg)
453
454 # NOTE: mypy disallows assigning to a method
455 # https://github.com/python/mypy/issues/2427
456 parser.exit = parser_exit # type: ignore
457
458 return parser
459
460

References i.

Referenced by pip._internal.req.req_file.get_line_parser().

Here is the caller graph for this function:

◆ expand_env_variables()

ReqFileLines expand_env_variables ( ReqFileLines  lines_enum)
Replace all environment variables that can be retrieved via `os.getenv`.

The only allowed format for environment variables defined in the
requirement file is `${MY_VARIABLE_1}` to ensure two things:

1. Strings that contain a `$` aren't accidentally (partially) expanded.
2. Ensure consistency across platforms for requirement files.

These points are the result of a discussion on the `github pull
request #3514 <https://github.com/pypa/pip/pull/3514>`_.

Valid characters in variable names follow the `POSIX standard
<http://pubs.opengroup.org/onlinepubs/9699919799/>`_ and are limited
to uppercase letter, digits and the `_` (underscore).

Definition at line 503 of file req_file.py.

503def expand_env_variables(lines_enum: ReqFileLines) -> ReqFileLines:
504 """Replace all environment variables that can be retrieved via `os.getenv`.
505
506 The only allowed format for environment variables defined in the
507 requirement file is `${MY_VARIABLE_1}` to ensure two things:
508
509 1. Strings that contain a `$` aren't accidentally (partially) expanded.
510 2. Ensure consistency across platforms for requirement files.
511
512 These points are the result of a discussion on the `github pull
513 request #3514 <https://github.com/pypa/pip/pull/3514>`_.
514
515 Valid characters in variable names follow the `POSIX standard
516 <http://pubs.opengroup.org/onlinepubs/9699919799/>`_ and are limited
517 to uppercase letter, digits and the `_` (underscore).
518 """
519 for line_number, line in lines_enum:
520 for env_var, var_name in ENV_VAR_RE.findall(line):
521 value = os.getenv(var_name)
522 if not value:
523 continue
524
525 line = line.replace(env_var, value)
526
527 yield line_number, line
528
529

References i.

Referenced by pip._internal.req.req_file.preprocess().

Here is the caller graph for this function:

◆ get_file_content()

Tuple[str, str] get_file_content ( str  url,
PipSession  session 
)
Gets the content of a file; it may be a filename, file: URL, or
http: URL.  Returns (location, content).  Content is unicode.
Respects # -*- coding: declarations on the retrieved files.

:param url:         File path or url.
:param session:     PipSession instance.

Definition at line 530 of file req_file.py.

530def get_file_content(url: str, session: PipSession) -> Tuple[str, str]:
531 """Gets the content of a file; it may be a filename, file: URL, or
532 http: URL. Returns (location, content). Content is unicode.
533 Respects # -*- coding: declarations on the retrieved files.
534
535 :param url: File path or url.
536 :param session: PipSession instance.
537 """
538 scheme = get_url_scheme(url)
539
540 # Pip has special support for file:// URLs (LocalFSAdapter).
541 if scheme in ["http", "https", "file"]:
542 resp = session.get(url)
543 raise_for_status(resp)
544 return resp.url, resp.text
545
546 # Assume this is a bare path.
547 try:
548 with open(url, "rb") as f:
549 content = auto_decode(f.read())
550 except OSError as exc:
551 raise InstallationError(f"Could not open requirements file: {exc}")
552 return url, content

References i.

Referenced by RequirementsFileParser._parse_file().

Here is the caller graph for this function:

◆ get_line_parser()

LineParser get_line_parser ( Optional["PackageFinder"]  finder)

Definition at line 392 of file req_file.py.

392def get_line_parser(finder: Optional["PackageFinder"]) -> LineParser:
393 def parse_line(line: str) -> Tuple[str, Values]:
394 # Build new parser for each line since it accumulates appendable
395 # options.
396 parser = build_parser()
397 defaults = parser.get_default_values()
398 defaults.index_url = None
399 if finder:
401
402 args_str, options_str = break_args_options(line)
403
404 try:
405 options = shlex.split(options_str)
406 except ValueError as e:
407 raise OptionParsingError(f"Could not split options: {options_str}") from e
408
409 opts, _ = parser.parse_args(options, defaults)
410
411 return args_str, opts
412
413 return parse_line
414
415

References pip._internal.req.req_file.break_args_options(), pip._internal.req.req_file.build_parser(), and i.

Referenced by pip._internal.req.req_file.parse_requirements().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_line()

Optional[ParsedRequirement] handle_line ( ParsedLine  line,
Optional[optparse.Values]   options = None,
Optional["PackageFinder"]   finder = None,
Optional[PipSession]   session = None 
)
Handle a single parsed requirements line; This can result in
creating/yielding requirements, or updating the finder.

:param line:        The parsed line to be processed.
:param options:     CLI options.
:param finder:      The finder - updated by non-requirement lines.
:param session:     The session - updated by non-requirement lines.

Returns a ParsedRequirement object if the line is a requirement line,
otherwise returns None.

For lines that contain requirements, the only options that have an effect
are from SUPPORTED_OPTIONS_REQ, and they are scoped to the
requirement. Other options from SUPPORTED_OPTIONS may be present, but are
ignored.

For lines that do not contain requirements, the only options that have an
effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may
be present, but are ignored. These lines may contain multiple options
(although our docs imply only one is supported), and all our parsed and
affect the finder.

Definition at line 278 of file req_file.py.

283) -> Optional[ParsedRequirement]:
284 """Handle a single parsed requirements line; This can result in
285 creating/yielding requirements, or updating the finder.
286
287 :param line: The parsed line to be processed.
288 :param options: CLI options.
289 :param finder: The finder - updated by non-requirement lines.
290 :param session: The session - updated by non-requirement lines.
291
292 Returns a ParsedRequirement object if the line is a requirement line,
293 otherwise returns None.
294
295 For lines that contain requirements, the only options that have an effect
296 are from SUPPORTED_OPTIONS_REQ, and they are scoped to the
297 requirement. Other options from SUPPORTED_OPTIONS may be present, but are
298 ignored.
299
300 For lines that do not contain requirements, the only options that have an
301 effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may
302 be present, but are ignored. These lines may contain multiple options
303 (although our docs imply only one is supported), and all our parsed and
304 affect the finder.
305 """
306
308 parsed_req = handle_requirement_line(line, options)
309 return parsed_req
310 else:
311 handle_option_line(
312 line.opts,
315 finder,
316 options,
317 session,
318 )
319 return None
320
321

References pip._internal.req.req_file.handle_option_line(), pip._internal.req.req_file.handle_requirement_line(), and i.

Referenced by pip._internal.req.req_file.parse_requirements().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_option_line()

None handle_option_line ( Values  opts,
str  filename,
int  lineno,
Optional["PackageFinder"]   finder = None,
Optional[optparse.Values]   options = None,
Optional[PipSession]   session = None 
)

Definition at line 208 of file req_file.py.

215) -> None:
216 if opts.hashes:
218 "%s line %s has --hash but no requirement, and will be ignored.",
219 filename,
220 lineno,
221 )
222
223 if options:
224 # percolate options upward
230 )
231
232 # set finder options
233 if finder:
234 find_links = finder.find_links
235 index_urls = finder.index_urls
237 if opts.no_index is True:
238 no_index = True
239 index_urls = []
240 if opts.index_url and not no_index:
241 index_urls = [opts.index_url]
242 if opts.extra_index_urls and not no_index:
245 # FIXME: it would be nice to keep track of the source
246 # of the find_links: support a find-links local path
247 # relative to a requirements file.
248 value = opts.find_links[0]
249 req_dir = os.path.dirname(os.path.abspath(filename))
250 relative_to_reqs_file = os.path.join(req_dir, value)
251 if os.path.exists(relative_to_reqs_file):
252 value = relative_to_reqs_file
253 find_links.append(value)
254
255 if session:
256 # We need to update the auth urls in session
257 session.update_index_urls(index_urls)
258
259 search_scope = SearchScope(
260 find_links=find_links,
261 index_urls=index_urls,
262 no_index=no_index,
263 )
264 finder.search_scope = search_scope
265
266 if opts.pre:
268
271
272 if session:
273 for host in opts.trusted_hosts or []:
274 source = f"line {lineno} of {filename}"
275 session.add_trusted_host(host, source=source)
276
277

References i.

Referenced by pip._internal.req.req_file.handle_line().

Here is the caller graph for this function:

◆ handle_requirement_line()

ParsedRequirement handle_requirement_line ( ParsedLine  line,
Optional[optparse.Values]   options = None 
)

Definition at line 168 of file req_file.py.

171) -> ParsedRequirement:
172 # preserve for the nested code path
173 line_comes_from = "{} {} (line {})".format(
174 "-c" if line.constraint else "-r",
177 )
178
180
182 # For editable requirements, we don't support per-requirement
183 # options, so just return the parsed requirement.
184 return ParsedRequirement(
185 requirement=line.requirement,
186 is_editable=line.is_editable,
187 comes_from=line_comes_from,
188 constraint=line.constraint,
189 )
190 else:
191 # get the options that apply to requirements
192 req_options = {}
193 for dest in SUPPORTED_OPTIONS_REQ_DEST:
194 if dest in line.opts.__dict__ and line.opts.__dict__[dest]:
195 req_options[dest] = line.opts.__dict__[dest]
196
197 line_source = f"line {line.lineno} of {line.filename}"
198 return ParsedRequirement(
199 requirement=line.requirement,
200 is_editable=line.is_editable,
201 comes_from=line_comes_from,
202 constraint=line.constraint,
203 options=req_options,
204 line_source=line_source,
205 )
206
207

References i.

Referenced by pip._internal.req.req_file.handle_line().

Here is the caller graph for this function:

◆ ignore_comments()

ReqFileLines ignore_comments ( ReqFileLines  lines_enum)
Strips comments and filter empty lines.

Definition at line 492 of file req_file.py.

492def ignore_comments(lines_enum: ReqFileLines) -> ReqFileLines:
493 """
494 Strips comments and filter empty lines.
495 """
496 for line_number, line in lines_enum:
497 line = COMMENT_RE.sub("", line)
498 line = line.strip()
499 if line:
500 yield line_number, line
501
502

References i.

Referenced by pip._internal.req.req_file.preprocess().

Here is the caller graph for this function:

◆ join_lines()

ReqFileLines join_lines ( ReqFileLines  lines_enum)
Joins a line ending in '\' with the previous line (except when following
comments).  The joined line takes on the index of the first line.

Definition at line 461 of file req_file.py.

461def join_lines(lines_enum: ReqFileLines) -> ReqFileLines:
462 """Joins a line ending in '\' with the previous line (except when following
463 comments). The joined line takes on the index of the first line.
464 """
465 primary_line_number = None
466 new_line: List[str] = []
467 for line_number, line in lines_enum:
468 if not line.endswith("\\") or COMMENT_RE.match(line):
469 if COMMENT_RE.match(line):
470 # this ensures comments are always matched later
471 line = " " + line
472 if new_line:
473 new_line.append(line)
474 assert primary_line_number is not None
475 yield primary_line_number, "".join(new_line)
476 new_line = []
477 else:
478 yield line_number, line
479 else:
480 if not new_line:
481 primary_line_number = line_number
483
484 # last line contains \
485 if new_line:
486 assert primary_line_number is not None
487 yield primary_line_number, "".join(new_line)
488
489 # TODO: handle space after '\'.
490
491

References i.

Referenced by pip._internal.req.req_file.preprocess().

Here is the caller graph for this function:

◆ parse_requirements()

Generator[ParsedRequirement, None, None] parse_requirements ( str  filename,
PipSession  session,
Optional["PackageFinder"]   finder = None,
Optional[optparse.Values]   options = None,
bool   constraint = False 
)
Parse a requirements file and yield ParsedRequirement instances.

:param filename:    Path or url of requirements file.
:param session:     PipSession instance.
:param finder:      Instance of pip.index.PackageFinder.
:param options:     cli options.
:param constraint:  If true, parsing a constraint file rather than
    requirements file.

Definition at line 129 of file req_file.py.

135) -> Generator[ParsedRequirement, None, None]:
136 """Parse a requirements file and yield ParsedRequirement instances.
137
138 :param filename: Path or url of requirements file.
139 :param session: PipSession instance.
140 :param finder: Instance of pip.index.PackageFinder.
141 :param options: cli options.
142 :param constraint: If true, parsing a constraint file rather than
143 requirements file.
144 """
145 line_parser = get_line_parser(finder)
146 parser = RequirementsFileParser(session, line_parser)
147
148 for parsed_line in parser.parse(filename, constraint):
149 parsed_req = handle_line(
150 parsed_line, options=options, finder=finder, session=session
151 )
152 if parsed_req is not None:
153 yield parsed_req
154
155

References pip._internal.req.req_file.get_line_parser(), pip._internal.req.req_file.handle_line(), and i.

Here is the call graph for this function:

◆ preprocess()

ReqFileLines preprocess ( str  content)
Split, filter, and join lines, and return a line iterator

:param content: the content of the requirements file

Definition at line 156 of file req_file.py.

156def preprocess(content: str) -> ReqFileLines:
157 """Split, filter, and join lines, and return a line iterator
158
159 :param content: the content of the requirements file
160 """
161 lines_enum: ReqFileLines = enumerate(content.splitlines(), start=1)
162 lines_enum = join_lines(lines_enum)
163 lines_enum = ignore_comments(lines_enum)
164 lines_enum = expand_env_variables(lines_enum)
165 return lines_enum
166
167

References pip._internal.req.req_file.expand_env_variables(), i, pip._internal.req.req_file.ignore_comments(), and pip._internal.req.req_file.join_lines().

Referenced by RequirementsFileParser._parse_file().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ COMMENT_RE

COMMENT_RE = re.compile(r"(^|\s+)#.*$")

Definition at line 46 of file req_file.py.

◆ ENV_VAR_RE

ENV_VAR_RE = re.compile(r"(?P<var>\$\{(?P<name>[A-Z0-9_]+)\})")

Definition at line 52 of file req_file.py.

◆ LineParser

LineParser = Callable[[str], Tuple[str, Values]]

Definition at line 43 of file req_file.py.

◆ logger

logger = logging.getLogger(__name__)

Definition at line 81 of file req_file.py.

◆ ReqFileLines

ReqFileLines = Iterable[Tuple[int, str]]

Definition at line 41 of file req_file.py.

◆ SCHEME_RE

SCHEME_RE = re.compile(r"^(http|https|file):", re.I)

Definition at line 45 of file req_file.py.

◆ SUPPORTED_OPTIONS

◆ SUPPORTED_OPTIONS_REQ

list SUPPORTED_OPTIONS_REQ
Initial value:

Definition at line 72 of file req_file.py.

◆ SUPPORTED_OPTIONS_REQ_DEST

list SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ]

Definition at line 79 of file req_file.py.