MCPcopy Index your code
hub / github.com/pex-tool/pex / apply_script_metadata

Function apply_script_metadata

pex/resolve/script_metadata.py:50–166  ·  view source on GitHub ↗
(
    scripts,  # type: Sequence[str]
    requirement_configuration=None,  # type: Optional[RequirementConfiguration]
    target_configuration=None,  # type: Optional[TargetConfiguration]
)

Source from the content-addressed store, hash-verified

48
49
50def apply_script_metadata(
51 scripts, # type: Sequence[str]
52 requirement_configuration=None, # type: Optional[RequirementConfiguration]
53 target_configuration=None, # type: Optional[TargetConfiguration]
54):
55 # type: (...) -> ScriptMetadataApplication
56
57 script_metadatas = [] # type: List[ScriptMetadata]
58 requirements = OrderedSet(
59 requirement_configuration.requirements
60 if requirement_configuration and requirement_configuration.requirements
61 else ()
62 ) # type: OrderedSet[ParsedRequirement]
63 requires_python = SpecifierSet()
64 for script in scripts:
65 with open(script, "rb") as fp:
66 # N.B.: The default encoding for python source files prior to Python 3.15 is ascii,
67 # but since utf-8 is a superset and people might forget to use encoding comment lines,
68 # this is a strictly better default to use. In fact, PEP-723 mandates this default.
69 #
70 # See:
71 # * https://packaging.python.org/en/latest/specifications/inline-script-metadata/
72 # * https://peps.python.org/pep-0263/
73 # * https://peps.python.org/pep-0686/
74 encoding = "utf-8" # type: Text
75 lines_read = 0
76 while lines_read < 2:
77 line = fp.readline()
78 lines_read += 1
79 match = re.search(
80 br"^[ \t\f]*#.*?coding[:=][ \t]*(?P<encoding>[-_.a-zA-Z0-9]+)", line
81 )
82 if match:
83 encoding = match.group("encoding").decode("ascii")
84 break
85
86 fp.seek(0, os.SEEK_SET)
87 script_metadata = ScriptMetadata.parse(fp.read().decode(encoding), source=fp.name)
88 script_metadatas.append(script_metadata)
89 requirements.update(script_metadata.dependencies)
90 requires_python &= script_metadata.requires_python
91
92 if isinstance(specifier_sets.as_range(requires_python), UnsatisfiableSpecifierSet):
93 raise Unsatisfiable(
94 dedent(
95 """\
96 The requires-python metadata of two or more of the specified scripts is in conflict.
97 Given the scripts: {scripts} and {script}
98 The resulting Python requirement is '{requires_python}' which is not satisfiable.
99 """
100 ).format(
101 scripts=", ".join(scripts[:-1]), script=scripts[-1], requires_python=requires_python
102 )
103 )
104
105 if target_configuration and requires_python:
106 interpreter_constraints = (
107 target_configuration.interpreter_configuration.interpreter_constraints.constraints

Callers 5

resolveMethod · 0.90
_create_subsetMethod · 0.90
test_script_encoding_badFunction · 0.90

Calls 14

updateMethod · 0.95
OrderedSetClass · 0.90
UnsatisfiableClass · 0.90
TargetConfigurationClass · 0.90
decodeMethod · 0.80
appendMethod · 0.80
parseMethod · 0.45

Tested by 1

test_script_encoding_badFunction · 0.72