-
-
Notifications
You must be signed in to change notification settings - Fork 638
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 tool version into install_from_resolve
arg documentation
#20901
Add tool version into install_from_resolve
arg documentation
#20901
Conversation
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.
This is awesome!
- Can you add a brief sentence about this to the
docs/notes/2.22.x.md
file in the Python section? Seems like such a nice quality of life improvement to be worth calling out! - I notice that potentially two improvements to
install_from_resolve
's docs:- somewhat tangential, but maybe the link could be to
docs/python/overview/lockfiles#lockfiles-for-tools
instead of https://www.pantsbuild.org/2.20/docs/python/overview/third-party-dependencies#lockfiles - Could we extend the "If unspecified, ... default lockfile shipped with Pants." paragraph to include this version? E.g. "If unspecified, ... default lockfile shipped with Pants[, which uses {package} version {version}]." where the
[]
bit is optional.
- somewhat tangential, but maybe the link could be to
src/python/pants/option/subsystem.py
Outdated
help: ClassVar[str | Callable[[], str]] | ||
|
||
@classproperty | ||
def help_extended(cls) -> str: | ||
""" | ||
Help text to be used in `./pants help`. | ||
Subclasses may override this to add more information, | ||
but by default, the text generated by `help` is returned unchanged. | ||
""" | ||
if isinstance(cls.help, str): | ||
return cls.help | ||
|
||
return cls.help() |
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.
Exploring the design here, did you consider the option of leaving this as is and overriding help
in PythonToolRequirementsBase
?
I guess this would make a bit of fiddle to add a new help_short: ClassVar[str | ...]
(or similar) to PythonToolRequirementsBase
that its help
method uses?
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.
The challenge here is that subclasses of PythonToolRequirementBase
can override help
as well and make it a string (as you said). This would nullify any changes to help
that we make in the superclass. We can work around this by adding a new field like help_short
, but that feels more intrusive?
So I didn't want to interfere with any of the current functionality and cause breakage to any existing help text. It seemed simpler to just add in a new method and invoke that instead of messing with the existing structure.
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.
Fair enough!
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.
Hm, sorry to revisit this, but I'm a bit nervous about this approach, as it seems like we're pushing something that's somewhat of an implementation detail of PythonToolRequirementBase
/ the Python subsystems up to the top-level subsystem concept, side stepping the normal tools for this in Python (i.e. subclassing & overrides). All of these becomes available to third-party plugins, so exposing it has future-design/backwards-compatibility concerns (i.e. if we land this and then reconsider, we might have to go through deprecation cycles etc.).
I can think of a few options:
- keep this approach, with a new method on the
Subsystem
class which lets "leaf" subclasses just sethelp
while still giving superclasses flexibility for manipulating it - a new field manipulated by the Python tool helpers, that Python tool subclasses need to set
- a class method that Python tool subclasses can call when formatting their own help text
- omit this information about the default version from the subsystem help string and have it just in places that don't cause the subclassing fiddle, i.e. option help text like
install_from_resolve
.- Variant: omit it for now so we can land this PR with just the parsing & display in option text and no change to the top-level help text, and then consider how to display it elsewhere as follow-up
For 2, If we were to add a new field, I think that'd mean:
- adding an field
help_short
(or some other name) toPythonToolRequirementBase
- updating the ~40 subclasses to swap
help
-> , which would be annoying but not horrible - finessing how
PythonToolRequirementBase
sets itshelp
property to the extra-formatting version, to work better with mypy + existing classes (I think it'd have to behelp: ClassVar[str | Callable[[], str] = _real_help_classmethod
with the type annotation) - communicating the change for plugins in release notes, something like "subclasses of
PythonToolRequirementBase
andPythonToolBase
can replacehelp
with to use the default help behaviour which inserts the default tool version".
For 3, that might be something like a class method def default_version_help_text(cls) -> str
and downstream classes like Black
& ClangFormat
etc. have to call it in their help constructors f"... {cls.default_version_help_text()}"`.
I'm somewhat inclined to 4i (i.e. split this PR up so that there's a separate PR with the change to the top-level help text), so that this PR isn't blocked in this discussion and we get to see some of the benefits of your work sooner. But, I'm unsure.
What do you think @krishnan-chandra?
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.
I agree with following 4i for now, and splitting out the changes to the top-level help text into a separate PR.
On a go-forward basis, here are my thoughts:
The current content of the PR is basically the same as approach 1 -
- keep this approach, with a new method on the Subsystem class which lets "leaf" subclasses just set help while still giving superclasses flexibility for manipulating it
I understand the concern around the new method being public - I think making this method private could potentially help, although we'd have to call getattr
on a private attribute which feels a bit icky.
- a new field manipulated by the Python tool helpers, that Python tool subclasses need to set
This one might be best, especially if we make help_short
required? That would give a clear indicator of what to set for developers adding future Python tools, and would also let us catch unset values via type-checking.
- a class method that Python tool subclasses can call when formatting their own help text
For 3, that might be something like a class method def default_version_help_text(cls) -> str and downstream classes like Black & ClangFormat etc. have to call it in their help constructors f"... {cls.default_version_help_text()}"`.
While this could work, I think there's some footguns here - if you're making a new Python tool, you could very easily end up calling .help
instead of .default_version_help_text
or miss the call entirely, which seems suboptimal.
On the whole, I'd probably vote for option 2 out of all the ones you proposed.
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.
Latest commit implements 4i and removes the tool version from top-level help text. I can implement option 2 in a follow-up PR.
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.
Also created #20912 to track the follow-up task.
Oh, another thought for validation: the https://pantsbuild.org docs are generated from (If it appears in |
04d8576
to
552107f
Compare
Okay, I think I addressed all of the items that you mentioned. The help text in
|
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.
This is awesome. I think it's very close to ready.
src/python/pants/option/subsystem.py
Outdated
help: ClassVar[str | Callable[[], str]] | ||
|
||
@classproperty | ||
def help_extended(cls) -> str: | ||
""" | ||
Help text to be used in `./pants help`. | ||
Subclasses may override this to add more information, | ||
but by default, the text generated by `help` is returned unchanged. | ||
""" | ||
if isinstance(cls.help, str): | ||
return cls.help | ||
|
||
return cls.help() |
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.
Fair enough!
5938ff1
to
0a818c1
Compare
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.
Thanks for all the iteration!
src/python/pants/option/subsystem.py
Outdated
help: ClassVar[str | Callable[[], str]] | ||
|
||
@classproperty | ||
def help_extended(cls) -> str: | ||
""" | ||
Help text to be used in `./pants help`. | ||
Subclasses may override this to add more information, | ||
but by default, the text generated by `help` is returned unchanged. | ||
""" | ||
if isinstance(cls.help, str): | ||
return cls.help | ||
|
||
return cls.help() |
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.
Hm, sorry to revisit this, but I'm a bit nervous about this approach, as it seems like we're pushing something that's somewhat of an implementation detail of PythonToolRequirementBase
/ the Python subsystems up to the top-level subsystem concept, side stepping the normal tools for this in Python (i.e. subclassing & overrides). All of these becomes available to third-party plugins, so exposing it has future-design/backwards-compatibility concerns (i.e. if we land this and then reconsider, we might have to go through deprecation cycles etc.).
I can think of a few options:
- keep this approach, with a new method on the
Subsystem
class which lets "leaf" subclasses just sethelp
while still giving superclasses flexibility for manipulating it - a new field manipulated by the Python tool helpers, that Python tool subclasses need to set
- a class method that Python tool subclasses can call when formatting their own help text
- omit this information about the default version from the subsystem help string and have it just in places that don't cause the subclassing fiddle, i.e. option help text like
install_from_resolve
.- Variant: omit it for now so we can land this PR with just the parsing & display in option text and no change to the top-level help text, and then consider how to display it elsewhere as follow-up
For 2, If we were to add a new field, I think that'd mean:
- adding an field
help_short
(or some other name) toPythonToolRequirementBase
- updating the ~40 subclasses to swap
help
-> , which would be annoying but not horrible - finessing how
PythonToolRequirementBase
sets itshelp
property to the extra-formatting version, to work better with mypy + existing classes (I think it'd have to behelp: ClassVar[str | Callable[[], str] = _real_help_classmethod
with the type annotation) - communicating the change for plugins in release notes, something like "subclasses of
PythonToolRequirementBase
andPythonToolBase
can replacehelp
with to use the default help behaviour which inserts the default tool version".
For 3, that might be something like a class method def default_version_help_text(cls) -> str
and downstream classes like Black
& ClangFormat
etc. have to call it in their help constructors f"... {cls.default_version_help_text()}"`.
I'm somewhat inclined to 4i (i.e. split this PR up so that there's a separate PR with the change to the top-level help text), so that this PR isn't blocked in this discussion and we get to see some of the benefits of your work sooner. But, I'm unsure.
What do you think @krishnan-chandra?
493d495
to
9437d14
Compare
install_from_resolve
arg documentation
Co-authored-by: Huon Wilson <[email protected]>
Co-authored-by: Huon Wilson <[email protected]>
Co-authored-by: Huon Wilson <[email protected]>
297236e
to
562d940
Compare
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.
Awesome. Thank you again for the iteration
Closes #20722. Here's what the new output looks like:
I couldn't work out how to test this except by running the CLI to generate the description (see above). And that...seems to work?