Skip to content
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

feat: Make register_plugin a standalone function and include shared lib discovery #14804

Merged
merged 35 commits into from
Mar 15, 2024

Conversation

MarcoGorelli
Copy link
Collaborator

@MarcoGorelli MarcoGorelli commented Mar 1, 2024

Starting by giving plugin authors a public version of _get_shared_lib_location

I'd also really like to have a public version of parse_as_expression + wrap_expr, but will leave that for a separate discussion a public parse_as_expression would no longer be needed with these changes

@github-actions github-actions bot added enhancement New feature or an improvement of an existing feature python Related to Python Polars rust Related to Rust Polars labels Mar 1, 2024
@MarcoGorelli MarcoGorelli marked this pull request as ready for review March 1, 2024 09:32
Copy link
Member

@stinodego stinodego left a comment

Choose a reason for hiding this comment

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

If we're going to make this part of the public API, we have to make sure the typing is done correctly and it has a proper docstring (e.g. document the parameters / point to the user guide with extensive plugin docs). Probably should also properly use pathlib.

We can also take this opportunity to reconsider the function/parameter names.

We should also document it as unstable.

@MarcoGorelli MarcoGorelli marked this pull request as draft March 1, 2024 11:56
Copy link

codecov bot commented Mar 1, 2024

Codecov Report

Attention: Patch coverage is 93.24324% with 5 lines in your changes are missing coverage. Please review.

Project coverage is 81.06%. Comparing base (fd9eba2) to head (263225c).
Report is 15 commits behind head on main.

❗ Current head 263225c differs from pull request most recent head 0f5183e. Consider uploading reports for the commit 0f5183e to get more accurate results

Files Patch % Lines
py-polars/polars/expr/expr.py 0.00% 4 Missing ⚠️
py-polars/src/functions/misc.rs 97.14% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #14804      +/-   ##
==========================================
+ Coverage   81.02%   81.06%   +0.04%     
==========================================
  Files        1338     1342       +4     
  Lines      173706   173865     +159     
  Branches     2461     2459       -2     
==========================================
+ Hits       140742   140945     +203     
+ Misses      32494    32454      -40     
+ Partials      470      466       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@MarcoGorelli MarcoGorelli marked this pull request as ready for review March 1, 2024 13:27
Copy link
Member

@stinodego stinodego left a comment

Choose a reason for hiding this comment

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

Could you add a simple test for this function? Should be easy enough to set up a sensible test by using tmp_path fixture.

@MarcoGorelli MarcoGorelli marked this pull request as draft March 4, 2024 14:49
@MarcoGorelli MarcoGorelli marked this pull request as ready for review March 6, 2024 21:40
@stinodego
Copy link
Member

stinodego commented Mar 14, 2024

(I) have added a step in the Python3.11 Ubuntu job to test a little sample plugin in CI. It adds ~1m 6s to that job's CI time but I think it's well worth it, especially if clients are using plugins in production

This is probably a good idea, but I don't really want a sample_plugin folder in the repo root. Could you split the testing/CI change off to a separate PR? Then we can merge this API improvement now, and think a bit about the best way to test plugins separately.

@stinodego stinodego changed the title feat: make public plugins.py module feat: Make register_plugin a standalone function and include shared lib discovery Mar 14, 2024
@MarcoGorelli
Copy link
Collaborator Author

Sounds good, thanks!

Copy link
Member

@stinodego stinodego left a comment

Choose a reason for hiding this comment

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

I did some cleanup and made some minor changes.

The function is now called register_plugin_function, as it registers a single function (not all functions in the plugin).

We have to decide whether we want to throw a deprecation warning for the previous Expr.register_plugin (and ultimately remove it?), due to backward compatibility. It was marked unstable and thanks to Marco's experience we have found that the existing API is lacking.

@ritchie46 what do you think?

@ritchie46
Copy link
Member

Yeap, sounds good to me. 👍

@stinodego
Copy link
Member

stinodego commented Mar 15, 2024

Okay, I have done a few more things:

  • The old plugin functions are marked as deprecated through a warning in the docstring, but do not throw a deprecation warning, since this warning is intended for plugin creators but would be shown to plugin users too.
  • Un-mark the new function as unstable. Again, an unstable warning would end up with end users, which we do not want. We also do not plan to mess around with this API, so it doesn't need to be unstable.
  • Redirect the deprecated functionality to the new functionality, to avoid code duplication.
  • Some small updates to the API names.
  • Include another test.

@MarcoGorelli could you give this another look and let me know if you're on board with everything as it currently stands? Then we can work out any last potential issues and get it merged.

I'd say this is a really nice ergonomics improvement for plugin authors!

collect_groups,
input_wildcard_expansion,
returns_scalar,
cast_to_supertypes: cast_to_supertype,
Copy link
Member

Choose a reason for hiding this comment

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

I will rename cast_to_supertypes internally to cast_to_supertype. The inputs all get cast to their (singular) supertype, so the previous name didn't make sense. I already corrected it in the new plugin function public API, so we don't have to change that again later.

@MarcoGorelli
Copy link
Collaborator Author

MarcoGorelli commented Mar 15, 2024

Thanks!

do not throw a deprecation warning, since this warning is intended for plugin creators but would be shown to plugin users too

Are you sure about this?:

  • Polars _get_shared_lib_location emits DeprecationWarning
  • plugin uses _get_shared_lib_location
  • user users plugin

So the user wouldn't see the DeprecationWarning https://docs.python.org/3/library/exceptions.html#DeprecationWarning "Ignored by the default warning filters, except in the __main__ module". There's a nice example of this here: #15081

@stinodego
Copy link
Member

Aha, in that case I'm adding back the warning 👍

@MarcoGorelli
Copy link
Collaborator Author

MarcoGorelli commented Mar 15, 2024

Looks good to me, thanks

I just checked this out with polars-xdt, and:

  • current tests pass, but with deprecation warning
  • running polars_xdt directly as a user doesn't show any deprecation warning
  • updating to use the new public function results and tests all pass

@stinodego
Copy link
Member

Thanks for checking! All right, let's press the green button then 👍

@stinodego stinodego merged commit 71a6563 into pola-rs:main Mar 15, 2024
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or an improvement of an existing feature python Related to Python Polars rust Related to Rust Polars
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants