Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_execute_interpreter_stdin_program():
with temporary_dir() as pex_chroot:
pex_builder = PEXBuilder(path=pex_chroot)
pex_builder.freeze()
process = PEX(pex_chroot).run(args=['-', 'one', 'two'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
blocking=False)
stdout, stderr = process.communicate(input=b'import sys; print(" ".join(sys.argv))')
assert 0 == process.returncode
assert b'- one two\n' == stdout
assert b'' == stderr
def add_wheel(builder, content):
with temporary_content(content) as project:
dist = WheelBuilder(project, interpreter=builder.interpreter).bdist()
builder.add_dist_location(dist)
def add_sources(builder, content):
with temporary_content(content) as project:
for path in content.keys():
builder.add_source(os.path.join(project, path), path)
with nested(temporary_dir(), temporary_dir()) as (root, cache):
pex_info1 = PexInfo.default()
pex_info1.zip_safe = False
pex1 = os.path.join(root, 'pex1.pex')
builder1 = PEXBuilder(interpreter=interpreter, pex_info=pex_info1)
add_requirements(builder1, cache)
add_wheel(builder1, content1)
add_sources(builder1, content2)
builder1.build(pex1)
pex_info2 = PexInfo.default()
pex_info2.pex_path = pex1
pex2 = os.path.join(root, 'pex2')
builder2 = PEXBuilder(path=pex2, interpreter=interpreter, pex_info=pex_info2)
add_requirements(builder2, cache)
add_wheel(builder2, content3)
builder2.set_script('foobaz')
builder2.freeze()
assert 42 == PEX(pex2, interpreter=interpreter).run(env=dict(PEX_VERBOSE='9'))
def test_pex_builder_deterministic_timestamp():
pb = PEXBuilder()
with temporary_dir() as td:
target = os.path.join(td, 'foo.pex')
pb.build(target, deterministic_timestamp=True)
with zipfile.ZipFile(target) as zf:
assert all(zinfo.date_time == (1980, 1, 1, 0, 0, 0) for zinfo in zf.infolist())
def test_execute_interpreter_file_program():
with temporary_dir() as pex_chroot:
pex_builder = PEXBuilder(path=pex_chroot)
pex_builder.freeze()
with tempfile.NamedTemporaryFile() as fp:
fp.write(b'import sys; print(" ".join(sys.argv))')
fp.flush()
process = PEX(pex_chroot).run(args=[fp.name, 'one', 'two'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
blocking=False)
stdout, stderr = process.communicate()
assert 0 == process.returncode
assert '{} one two\n'.format(fp.name).encode('utf-8') == stdout
assert b'' == stderr
def pex_builder_wrapper(**kwargs):
init_subsystem(PexBuilderWrapper.Factory)
return PexBuilderWrapper.Factory.create(PEXBuilder(**kwargs))
def builder(shebang):
pb = PEXBuilder()
pb.set_shebang(shebang)
return pb
identity = PythonInterpreter.from_binary(options.python).identity
else:
# Convert "CPython 2.7" to "CPython 2 7 0"
python_version = options.python_version.replace('.', ' ').split()
if len(python_version) == 3:
python_version.append('0')
identity = PythonIdentity.from_id_string(' '.join(python_version))
interpreter = PythonInterpreter(
options.python,
identity,
extras={})
compile_folder = safe_mkdtemp()
pex_builder = PEXBuilder(
path=output if options.directory else compile_folder,
interpreter=interpreter,
)
if options.python_shebang is not None:
pex_builder.set_shebang(options.python_shebang)
# Set whether this PEX as zip-safe, meaning everything will stayed zipped up
# and we'll rely on python's zip-import mechanism to load modules from
# the PEX. This may not work in some situations (e.g. native
# libraries, libraries that want to find resources via the FS).
pex_builder.info.zip_safe = options.zip_safe
# Set the starting point for this PEX.
pex_builder.info.entry_point = options.entry_point
# Note that we rebuild a chroot from scratch, instead of using the REQUIREMENTS_PEX
# and PYTHON_SOURCES products, because those products are already-built pexes, and there's
# no easy way to merge them into a single pex file (for example, they each have a __main__.py,
# metadata, and so on, which the merging code would have to handle specially).
interpreter = self.context.products.get_data(PythonInterpreter)
with temporary_dir() as tmpdir:
# Create the pex_info for the binary.
build_properties = PexInfo.make_build_properties()
if self.get_options().include_run_information:
run_info_dict = self.context.run_tracker.run_info.get_as_dict()
build_properties.update(run_info_dict)
pex_info = binary_tgt.pexinfo.copy()
pex_info.build_properties = build_properties
pex_builder = PexBuilderWrapper.Factory.create(
builder=PEXBuilder(path=tmpdir, interpreter=interpreter, pex_info=pex_info, copy=True),
log=self.context.log)
if binary_tgt.shebang:
self.context.log.info('Found Python binary target {} with customized shebang, using it: {}'
.format(binary_tgt.name, binary_tgt.shebang))
pex_builder.set_shebang(binary_tgt.shebang)
else:
self.context.log.debug(f'No customized shebang found for {binary_tgt.name}')
# Find which targets provide sources and which specify requirements.
source_tgts = []
req_tgts = []
constraint_tgts = []
for tgt in binary_tgt.closure(exclude_scopes=Scopes.COMPILE):
if has_python_sources(tgt) or has_resources(tgt):
source_tgts.append(tgt)
def _resolve_requirements_for_versioned_target_closure(self, interpreter, vt):
reqs_pex_path = os.path.realpath(os.path.join(self.workdir, str(interpreter.identity),
vt.cache_key.hash))
if not os.path.isdir(reqs_pex_path):
req_libs = [t for t in vt.target.closure() if has_python_requirements(t)]
with safe_concurrent_creation(reqs_pex_path) as safe_path:
pex_builder = PexBuilderWrapper.Factory.create(
builder=PEXBuilder(safe_path, interpreter=interpreter, copy=True),
log=self.context.log)
pex_builder.add_requirement_libs_from(req_libs)
pex_builder.freeze()
return PEX(reqs_pex_path, interpreter=interpreter)
if self.extra_requirements():
extra_reqs = [PythonRequirement(req_str) for req_str in self.extra_requirements()]
addr = Address.parse('{}_extra_reqs'.format(self.__class__.__name__))
self.context.build_graph.inject_synthetic_target(
addr, PythonRequirementLibrary, requirements=extra_reqs)
# Add the extra requirements first, so they take precedence over any colliding version
# in the target set's dependency closure.
pexes = [self.resolve_requirements([self.context.build_graph.get_target(addr)])] + pexes
extra_pex_paths = [pex.path() for pex in pexes if pex]
if extra_pex_paths:
pex_info.merge_pex_path(':'.join(extra_pex_paths))
with safe_concurrent_creation(path) as safe_path:
builder = PEXBuilder(safe_path, interpreter, pex_info=pex_info)
# Add target interpreter compatibilities to pex info.
for rt in relevant_targets:
if has_python_sources(rt):
for constraint in rt.compatibility:
builder.add_interpreter_constraint(constraint)
builder.freeze()
return WrappedPEX(PEX(os.path.realpath(path), interpreter), interpreter)