-
Notifications
You must be signed in to change notification settings - Fork 27
docs: fix wp_register_ability() args not marked as required. #97
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
base: trunk
Are you sure you want to change the base?
docs: fix wp_register_ability() args not marked as required. #97
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
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.
Pull Request Overview
This PR fixes PHPStan type annotations for the wp_register_ability()
function by marking the label
, description
, execute_callback
, and permission_callback
parameters as required instead of optional in the $args
array.
- Updates PHPStan parameter type annotations to reflect required fields
- Improves static analysis accuracy for developers using PHPStan
- Maintains existing runtime validation while providing better IDE/tooling support
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## trunk WordPress/abilities-api#97 +/- ##
=========================================
Coverage 85.69% 85.69%
Complexity 103 103
=========================================
Files 16 16
Lines 776 776
Branches 86 86
=========================================
Hits 665 665
Misses 111 111
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Overall, I'm in favor of making these args required with a small remark. There are possible paths where the developer might omit these args, for example when using wp_register_ability(
'wp-ai-sdk-chatbot-demo/get-post',
array(
'label' => __( 'Get Post', 'wp-ai-sdk-chatbot-demo' ),
'ability_class' => Get_Post_Ability::class,
)
); An important note, the developer still must provide these properties, which is satisfied with this code: Another, edge case scenario that I can think of would be with the new WP filter Could we use a union like the one below, or would it make it too complicated? /**
* @phpstan-param
* (array{
* label: string,
* description: string,
* execute_callback: callable(mixed $input=): (mixed|\WP_Error),
* permission_callback: callable(mixed $input=): (bool|\WP_Error),
* input_schema?: array<string,mixed>,
* output_schema?: array<string,mixed>,
* meta?: array<string,mixed>,
* ability_class?: class-string<\WP_Ability>,
* ...<string, mixed>
* }
* |
* array{
* ability_class: class-string<\WP_Ability>,
* label?: string,
* description?: string,
* execute_callback?: callable(mixed $input=): (mixed|\WP_Error),
* permission_callback?: callable(mixed $input=): (bool|\WP_Error),
* input_schema?: array<string,mixed>,
* output_schema?: array<string,mixed>,
* meta?: array<string,mixed>,
* ...<string, mixed>
* })
* $args
*/ Perhaps we could also include a unit test that illustrates the usage observed in the WC US demo plugin, providing internal PHPStan verification. |
+1 to what @gziolo suggested above: Neither the current nor the suggested shape in this PR are ideal IMO, because these arguments are only required if Something like this union approach would address the actual requirements properly. |
@felixarntz nit: they are only not required if The fact that IMO as I've said elsewhere, removing the predictability of required args is a huge footgun in general, but way worse to introduce into an initial release in v6.9 where it becomes permanent tech debt In the interim a downstream dev (using PHPStan level 8) really thinks there's a reason for their polymorphism, then I imo a one-line |
Fair point.
Where was that decided? I disagree with that assessment. Extending |
Agreed that extending |
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.
In the interim a downstream dev (using PHPStan level 8) really thinks there's a reason for their polymorphism, then I imo a one-line // @phpstan-ignore argument.type is an encouraging bit of friction to have.
I tend to agree we can optimize for tha majority of devs using the default way to register abilities 👍🏻
@felixarntz @gziolo not the ability to extend the class altogether, the ability to make those required args optional when extending (unlike Woo in that last class which a. respects the shape and b. doesn't need a class even Iirc the discussion started on #21 and moved to #53 + #54. The broader argument against polymorphism also came up in #61 and some other tangental PRs. |
Right, I know we talked about it in several places, but I don't recall any decision that this was discouraged / not recommended or anything along these lines. If you implement your own When no |
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.
Based on the conversation so far, I continue to question this approach: What is the concrete argument against going with @gziolo's suggestion from #97 (comment) instead?
Correct. No "decision" (if I'm now understanding your emphasis) has been made about actively promoting polymorphism in the initial core merge of this API. To make progress without such a decision we've been mostly avoiding polymorphism whenever it would be a breaking change to revert (because going from a single type to a union is a nonbreaking). So when I say that #21 isn't an endorsement on polymorphism, I mean it was explicitly merged without a decision to endorse polymorphism having been made.
WordPress documentation has always been prescriptive, not descriptive. It's why most types in the codebase aren't unioned to
The correlary here is that for <5% usage we're introducing a problematic footgun into an API we're navelgazing into existence isolated from core review, and where forward incompatible changes remain as permanent tech debt. We can always explicitly document the polymorphism in the future if/when we decide that it's something we want holistically and have it be nonbreaking.
If you mean "Overall, I'm in favor of making these args required with a small remark.", then yes that's the approach I think we should take ;) If you mean "Could we use a union like the one below, or would it make it too complicated?" then a quick tl;Dr would be:
@felixarntz what do you believe are the reasons:
|
To be clear, I never suggested to use polymorphism in the first place. The I don't disagree with several of your concerns. But then the proper solution is to not allow polymorphism at all, i.e. get rid of the Having Most other similar shaped WordPress APIs don't allow for such overriding of the class either. These APIs enforce usage of the WordPress object as is, and where they don't, it's likely just as problematic as this. We can deprecate the |
@felixarntz Your point about "half-baked solutions" resonates with me. For the sake of testing,I built a realistic restaurant management plugin to evaluate both approaches. For my use case (5 related abilities with shared rate limiting, logging, and subscription checks), the flexible approach saved 200 lines of duplicate code and reduced maintenance burden by 80%. But if this PR merges, I'll have 5 I agree with your assessment: Either properly support both patterns (union type) or deprecate ability_class entirely. The current PR creates exactly the "half-baked solution" you described. |
@felixarntz I agree with this approach, especially as we wait for WordPress/ai#40 . But if we can't reach a decision here/yet we will have an opportunity during the core merge process to polish off the rest. @Ref34t would you mind sharing? Im afk until tomorrow but the more code examples we have to theorycrafts around the more sound we can be in whatever ends up shipping. |
Nice! It's expected that multiple abilities coming from the same plugin will share logic. For larger teams, it will also help to enforce a certain structure for enforcing best practices like tracking usage, additional permissions, or context checks.
I'm strongly in favor of using an union type and keeping the |
I am in favor of going with either one or the other direction and properly sticking to it. What I'm against is a path where we choose to have I agree there's a higher risk of developers doing it wrong, if we allow I don't lean strongly either way, I only think that we have to make a choice, and when that choice is made, we need to be able to get behind it, and not continue to argue against it randomly in the future - as in "strong opinions, loosely held" :) |
@justlevine I published my 2 examples of the 2 approaches so you can have a better look |
Thanks for sharing @Ref34t 🙇.
Putting aside there's a bunch of "DRY principle" ways you can refactor that code to avoid the PHPStan error entirely (we all agree devs should write code however works best for them), or that you can
We can't call partial-documentation half-baked without acknowledging that the entire abilities API is half-baked, and not even just the
@felixarntz just repeating one nuance again the lack of encouragement is not the same thing as discouraging. I'm just advocating we leave the documentation off to buy us time until [pick: beta1, rc1, wp7.0] to cook. |
Weighing in here, I think we should go with the union type described here: #97 (comment) Here's why: The reality is that this is the most accurate representation of how the system works right now. Since this PR is focused on correcting that type, then that's the type as it stands. Regarding the debate of |
What
This PR fixes the
@phpstan-param
type annotations for the requiredlabel
,description
,execute_callback
, andpermission_callback
$args
onwp_register_ability()
This PR was authored by @johnbillion on justlevine#6, but I didn't see it before the upstream PR got merged. All I did was cherrypick it onto truck.
Why
Per John