-
-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the ability to infer assets from strings for Python #14049
Changes from 20 commits
289d06f
b90296a
5d2ba21
780d243
5650733
88d834f
b78201d
d66b163
8c6d018
e6a8e84
d0f15b2
fa315fa
a78b58d
06bcac0
afa8728
8bd3bac
9f77fb0
f76d980
68a809f
6973a7a
209e7ef
d588e39
8958e02
163e576
3929e8f
fe1802e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,9 @@ | ||
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
python_sources( | ||
overrides={ | ||
"parse_python_imports.py": { | ||
# This Python script is loaded as a resource, see parse_python_imports.py for more info. | ||
"dependencies": ["./scripts:import_parser"] | ||
} | ||
} | ||
) | ||
python_sources() | ||
|
||
python_tests( | ||
name="tests", | ||
overrides={"parse_python_imports_test.py": {"timeout": 120}}, | ||
overrides={"parse_python_dependencies_test.py": {"timeout": 120}}, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ | |
from pants.backend.python.util_rules.pex_environment import PythonExecutable | ||
from pants.core.util_rules.source_files import SourceFilesRequest | ||
from pants.core.util_rules.stripped_source_files import StrippedSourceFiles | ||
from pants.engine.collection import DeduplicatedCollection | ||
from pants.engine.fs import CreateDigest, Digest, FileContent, MergeDigests | ||
from pants.engine.process import Process, ProcessResult | ||
from pants.engine.rules import Get, MultiGet, collect_rules, rule | ||
|
@@ -31,21 +32,37 @@ class ParsedPythonImports(FrozenDict[str, ParsedPythonImportInfo]): | |
"""All the discovered imports from a Python source file mapped to the relevant info.""" | ||
|
||
|
||
class ParsedPythonAssets(DeduplicatedCollection[str]): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. If/when we support |
||
"""All the discovered possible assets from a Python source file.""" | ||
|
||
# N.B. Don't set `sort_input`, as the input is already sorted | ||
|
||
|
||
@dataclass(frozen=True) | ||
class ParsedPythonDependencies: | ||
imports: ParsedPythonImports | ||
assets: ParsedPythonAssets | ||
|
||
|
||
@dataclass(frozen=True) | ||
class ParsePythonImportsRequest: | ||
class ParsePythonDependenciesRequest: | ||
source: PythonSourceField | ||
interpreter_constraints: InterpreterConstraints | ||
string_imports: bool | ||
string_imports_min_dots: int | ||
assets: bool | ||
assets_min_slashes: int | ||
|
||
|
||
@rule | ||
async def parse_python_imports(request: ParsePythonImportsRequest) -> ParsedPythonImports: | ||
script = pkgutil.get_data(__name__, "scripts/import_parser.py") | ||
async def parse_python_dependencies( | ||
request: ParsePythonDependenciesRequest, | ||
) -> ParsedPythonDependencies: | ||
script = pkgutil.get_data(__name__, "scripts/dependency_parser.py") | ||
assert script is not None | ||
python_interpreter, script_digest, stripped_sources = await MultiGet( | ||
Get(PythonExecutable, InterpreterConstraints, request.interpreter_constraints), | ||
Get(Digest, CreateDigest([FileContent("__parse_python_imports.py", script)])), | ||
Get(Digest, CreateDigest([FileContent("__parse_python_dependencies.py", script)])), | ||
Get(StrippedSourceFiles, SourceFilesRequest([request.source])), | ||
) | ||
|
||
|
@@ -61,23 +78,30 @@ async def parse_python_imports(request: ParsePythonImportsRequest) -> ParsedPyth | |
Process( | ||
argv=[ | ||
python_interpreter.path, | ||
"./__parse_python_imports.py", | ||
"./__parse_python_dependencies.py", | ||
file, | ||
], | ||
input_digest=input_digest, | ||
description=f"Determine Python imports for {request.source.address}", | ||
description=f"Determine Python dependencies for {request.source.address}", | ||
env={ | ||
"STRING_IMPORTS": "y" if request.string_imports else "n", | ||
"MIN_DOTS": str(request.string_imports_min_dots), | ||
"STRING_IMPORTS_MIN_DOTS": str(request.string_imports_min_dots), | ||
"ASSETS": "y" if request.assets else "n", | ||
"ASSETS_MIN_SLASHES": str(request.assets_min_slashes), | ||
}, | ||
level=LogLevel.DEBUG, | ||
), | ||
) | ||
# See above for where we explicitly encoded as utf8. Even though utf8 is the | ||
# default for decode(), we make that explicit here for emphasis. | ||
process_output = process_result.stdout.decode("utf8") or "{}" | ||
return ParsedPythonImports( | ||
(imp, ParsedPythonImportInfo(**info)) for imp, info in json.loads(process_output).items() | ||
output = json.loads(process_output) | ||
|
||
return ParsedPythonDependencies( | ||
imports=ParsedPythonImports( | ||
(key, ParsedPythonImportInfo(**val)) for key, val in output.get("imports", {}).items() | ||
), | ||
assets=ParsedPythonAssets(output.get("assets", [])), | ||
) | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might ask where this has gone. The answer: it's being inferred 🪄