@rule(desc='Building local distributions')
async def build_local_dists(request: LocalDistsPexRequest) -> LocalDistsPex:
    transitive_targets = (await Get(TransitiveTargets, TransitiveTargetsRequest(request.addresses)))
    applicable_targets = [tgt for tgt in transitive_targets.closure if PythonDistributionFieldSet.is_applicable(tgt)]
    python_dist_field_sets = [PythonDistributionFieldSet.create(target) for target in applicable_targets]
    dists = (await MultiGet([Get(BuiltPackage, PackageFieldSet, field_set) for field_set in python_dist_field_sets]))
    provided_files = set()
    wheels = []
    all_contents = (await MultiGet((Get(DigestContents, Digest, dist.digest) for dist in dists)))
    for (dist, contents, tgt) in zip(dists, all_contents, applicable_targets):
        artifacts = set(((a.relpath or '') for a in dist.artifacts))
        wheel = next((art for art in artifacts if art.endswith('.whl')), None)
        if wheel:
            wheel_content = next((content for content in contents if (content.path == wheel)))
            wheels.append(wheel)
            buf = BytesIO()
            buf.write(wheel_content.content)
            buf.seek(0)
            with zipfile.ZipFile(buf) as zf:
                provided_files.update(zf.namelist())
        else:
            logger.warning(f'''Encountered a dependency on the {tgt.alias} target at {tgt.address.spec}, but this target does not produce a Python wheel artifact. Therefore this target's code will be used directly from sources, without a distribution being built, and therefore any native extensions in it will not be built.

See {doc_url('python-distributions')} for details on how to set up a {tgt.alias} target to produce a wheel.''')
    dists_digest = (await Get(Digest, MergeDigests([dist.digest for dist in dists])))
    wheels_digest = (await Get(Digest, DigestSubset(dists_digest, PathGlobs(['**/*.whl']))))
    dists_pex = (await Get(Pex, PexRequest(output_filename='local_dists.pex', requirements=PexRequirements(wheels), interpreter_constraints=request.interpreter_constraints, additional_inputs=wheels_digest, internal_only=True)))
    source_roots = list(reversed(sorted(request.sources.source_roots)))
    remaining_sources = set(request.sources.source_files.files)
    unrooted_files_set = set(request.sources.source_files.unrooted_files)
    for source in request.sources.source_files.files:
        if (source not in unrooted_files_set):
            for source_root in source_roots:
                if (source.startswith(source_root) and (os.path.relpath(source, source_root) in provided_files)):
                    remaining_sources.remove(source)
    remaining_sources_snapshot = (await Get(Snapshot, DigestSubset(request.sources.source_files.snapshot.digest, PathGlobs(sorted(remaining_sources)))))
    subtracted_sources = PythonSourceFiles(SourceFiles(remaining_sources_snapshot, request.sources.source_files.unrooted_files), request.sources.source_roots)
    return LocalDistsPex(dists_pex, subtracted_sources)
@rule(desc='Building local distributions')
async def build_local_dists(request: LocalDistsPexRequest) -> LocalDistsPex:
    transitive_targets = (await Get(TransitiveTargets, TransitiveTargetsRequest(request.addresses)))
    applicable_targets = [tgt for tgt in transitive_targets.closure if PythonDistributionFieldSet.is_applicable(tgt)]
    python_dist_field_sets = [PythonDistributionFieldSet.create(target) for target in applicable_targets]
    dists = (await MultiGet([Get(BuiltPackage, PackageFieldSet, field_set) for field_set in python_dist_field_sets]))
    provided_files = set()
    wheels = []
    all_contents = (await MultiGet((Get(DigestContents, Digest, dist.digest) for dist in dists)))
    for (dist, contents, tgt) in zip(dists, all_contents, applicable_targets):
        artifacts = set(((a.relpath or ) for a in dist.artifacts))
        wheel = next((art for art in artifacts if art.endswith('.whl')), None)
        if wheel:
            wheel_content = next((content for content in contents if (content.path == wheel)))
            wheels.append(wheel)
            buf = BytesIO()
            buf.write(wheel_content.content)
            buf.seek(0)
            with zipfile.ZipFile(buf) as zf:
                provided_files.update(zf.namelist())
        else:
            logger.warning(f'Encountered a dependency on the {tgt.alias} target at {tgt.address.spec}, but this target does not produce a Python wheel artifact. Therefore this target's code will be used directly from sources, without a distribution being built, and therefore any native extensions in it will not be built.

See {doc_url('python-distributions')} for details on how to set up a {tgt.alias} target to produce a wheel.')
    dists_digest = (await Get(Digest, MergeDigests([dist.digest for dist in dists])))
    wheels_digest = (await Get(Digest, DigestSubset(dists_digest, PathGlobs(['**/*.whl']))))
    dists_pex = (await Get(Pex, PexRequest(output_filename='local_dists.pex', requirements=PexRequirements(wheels), interpreter_constraints=request.interpreter_constraints, additional_inputs=wheels_digest, internal_only=True)))
    source_roots = list(reversed(sorted(request.sources.source_roots)))
    remaining_sources = set(request.sources.source_files.files)
    unrooted_files_set = set(request.sources.source_files.unrooted_files)
    for source in request.sources.source_files.files:
        if (source not in unrooted_files_set):
            for source_root in source_roots:
                if (source.startswith(source_root) and (os.path.relpath(source, source_root) in provided_files)):
                    remaining_sources.remove(source)
    remaining_sources_snapshot = (await Get(Snapshot, DigestSubset(request.sources.source_files.snapshot.digest, PathGlobs(sorted(remaining_sources)))))
    subtracted_sources = PythonSourceFiles(SourceFiles(remaining_sources_snapshot, request.sources.source_files.unrooted_files), request.sources.source_roots)
    return LocalDistsPex(dists_pex, subtracted_sources)