Skip to content

[pantsng] Pythonic access to the rust source partition logic.#23160

Merged
benjyw merged 3 commits intopantsbuild:mainfrom
benjyw:ng_source_partition
Mar 11, 2026
Merged

[pantsng] Pythonic access to the rust source partition logic.#23160
benjyw merged 3 commits intopantsbuild:mainfrom
benjyw:ng_source_partition

Conversation

@benjyw
Copy link
Copy Markdown
Contributor

@benjyw benjyw commented Mar 8, 2026

Provides convenient Pythonic access to a partition
of source files and the config that applies to them.

Partitions never cross multiple source roots, even if
a single config applies to all source roots.

@benjyw benjyw requested review from sureshjoshi and tdyas March 8, 2026 22:49
@benjyw benjyw changed the title Python wrappers around the rust source partition logic. [pantsng] Pythonic access to the rust source partition logic. Mar 8, 2026
@benjyw benjyw added the release-notes:not-required [CI] PR doesn't require mention in release notes label Mar 8, 2026
@benjyw
Copy link
Copy Markdown
Contributor Author

benjyw commented Mar 8, 2026

AI disclosure: I asked Claude to generate the unit tests. It did an OK job, but I did substantial manual editing to make the tests more concise and readable.

return tuple(str(path) for path in self.paths)

def commondir(self) -> str:
ret = os.path.commonpath(self.paths)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can throw in a couple of circumstances. I think the only relevant one here is empty tuple - what’s the downstream effect?

I don’t think we’re worried about abs vs relative paths, nor about paths on different drives I’m guessing? Unless someone has some mount shenanigans

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change to handle empty tuple, might as well be robust.

All these paths are expected to be relative to the repo root.

@@ -0,0 +1,122 @@
# Copyright 2025 Pants project contributors (see CONTRIBUTORS.md).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2026?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started writing it in 2025, so I think that is the applicable date? TBH dates in copyright notices are mostly meaningless. Copyright notices themselves are mostly meaningless...

def path_strs(self) -> tuple[str, ...]:
return tuple(str(path) for path in self.paths)

def commondir(self) -> str:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Maybe common_dir instead? I'm not a fan of running words together in identifiers.
  • Can this value be precomputed or just refer to source_root?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was copying commonpath, but yeah, can change it.

It can be precomputed, but probably better to let it evaluate lazily, so I've made it a @memoized_method.


def commondir(self) -> str:
ret = os.path.commonpath(self.paths)
if os.path.isfile(ret):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is filesystem access here okay? Shouldn't this be found with PathMetadataRequest?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this is a little sloppy (even if probably fine in practice since the race condition of same path being a file and then a dir would be weird). I think I can actually get rid of this check entirely, since we expect the paths to be files, and the only way the commonpath can be a file is if the input args were a single file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, no, I can imagine a backend for which "sources" are directories, and I wouldn't want this to break. Will replace it with a rule.

Copy link
Copy Markdown
Contributor

@tdyas tdyas Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I'd recommend that rule use path_metadata_request so that the rule invalidates correctly on changes if it is examining metadata.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that is what I meant by switching it to a rule (a classmethod can't await path_metadata_request)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, done and the test rewritten to accommodate.

@benjyw
Copy link
Copy Markdown
Contributor Author

benjyw commented Mar 10, 2026

PTAL, thanks!

# The args were a single file, so the commonpath is that file. We want its enclosing dir.
common_dir = os.path.dirname(commonpath)
else:
common_dir = commonpath
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PathMetadataKind.SYMLINK can also be true here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what to do in that case. We would need to know if it's a symlink to a file or to a directory.

I guess we can chase symlinks? I will leave it as a TODO for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, it's easy to chase symlinks since we have symlink_target right there, so I will do it and add a test.

@benjyw benjyw requested a review from sureshjoshi March 10, 2026 20:49
@benjyw benjyw merged commit 3dcbfd3 into pantsbuild:main Mar 11, 2026
25 checks passed
@benjyw benjyw deleted the ng_source_partition branch March 11, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes:not-required [CI] PR doesn't require mention in release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants