Hi all! Is there a way to depend on a single pytho...
# general
s
Hi all! Is there a way to depend on a single python class and not on the whole python module? I'm trying to find a way to do this with some codegen hack, but it doesn't seem to work
To be more specific I want --changed-since show me the changed dependency only if specific class definition ast has changed, but ignore it if anything in the file has changed but the class
b
Really dumb question - can the class be moved to a separate file? That would solve both problems for you
s
Yeah, I understand that would solve the problem, but it's pretty ugly in my case. There will be >100 independent very simple 4 line classes in a single file. If I put every class in a separate file it would be difficult to import them, because you have to know the location
b
Got it. As far as I’m aware, Pants doesn’t have a way to go deeper than file-level as source targets are defined as paths to files
👍 1
👆 1
s
Yeah, I found that you can disable automatically inferred dependency, so I thought maybe I could take this file and split it into multiple modules with codegen, but I would still have to use different module names while importing it
b
Yeah, pants doesn't do sub-file dependency inference, and, in general, it'd be hard to make it correct in the face of all possible code. For instance: this code hypothetically only imports
X
but can still interact with the "independent" class `Y`:
Copy code
class X:
    pass

class Y:
    pass

# In another file:
import inspect
# from ... import X, but can still access Y
print(inspect.getmodule(X).Y)
c
yea I agree it feels weird to support a higher granularity than what Python offers..
f
there's certainly a way to do that. The use case is totally valid. I have 10K LOC generated Python module with hundreds of functions. Having the logic refactored to produce individual modules would be ideal long-term, but I appreciate it may not be feasible with the resources available (or maybe it's not a priority, whatever is the case). I would suggest exploring this workflow: 1) You rely on dependency inference of Pants to discover the imports of every Python module. You can iterate through every discovered import with the https://www.pantsbuild.org/docs/reference-python-dump-source-analysis goal. Feel free to use alternative solutions to parse the source code and discover imported members. At this point, you know what classes every module imports. 2) You could use https://www.pantsbuild.org/docs/target-api-concepts#synthetic-targets-api to represent every class in your file with classes. Now, each module would depend on relevant synthetic targets. 3) You write a plugin that would consider a source module that imports a class (via a synthetic target) changed whenever the class contents change. Here you would need to query Git to find the files modified, get the lines modified, map the lines to a class (either naively with grep or using something fancy like rope or libcst constructing the AST). At this point, you know what source modules shall be considered changed based on the Git changed. 4) Optionally, extend the logic of how the
--changed-since
works, but I am skeptical it will be easy/possible. An arguably easier option would be to run a custom goal that would list what files have changed and then feed it further to Pants (or whatever you do with this information). It's possible that creating custom targets in the BUILD files, one for each class may actually be a better option (potentially easier to reason about), but you will need to extend the tailor goal to populate those custom targets (when running
pants tailor ::
, new classes not yet represented as build targets should be created). You can also rely on the fact that you can easily modify the BUILD files target programmatically should you decide to update the dependencies in semi-automated manner (updating dependencies on some targets for each relevant module every time there's a change in the imports of the classes). You can also only run https://www.pantsbuild.org/docs/reference-python-dump-source-analysis goal to get your imports and tell what modules import classes with Git modified lines - no need to write any plugin or custom targets. So you'd produce a list of changed files using your custom tool (could be a custom goal, but doesn't have to be!) and then you can just merge it with whatever Pants tells you has changed using the standard dependency inference you use in the codebase.
try to evaluate the amount of effort/support for the plugin vs splitting the file vs writing a custom shell script that would produce a list of changed files (without having Pants involved), hope you find a strategy that works
❤️ 1
s
Wow, thank you for the detailed answer! I will try that