Help writing PyCharm plugin for plpython3u

Answered

I've been writing some PostgreSQL functions in Python recently at work through Postgres' excellent plpython3u extension. Unfortunately PyCharm's handling of this is pretty terrible (see https://youtrack.jetbrains.com/issue/PY-42699). I've never written a Jetbrains plugin before (and my Java is pretty rusty) but this sounds like a relatively simple thing to smooth out. I'd love to write a plugin that:

  • Injects some global symbols into the context (e.g. SDGDplpy, etc)

  • Parses the parameters of the outer CREATE FUNCTION ... and injects those into the context

  • Somehow sets the indentation correctly so that PyCharm doesn't keep trying to stupidly indent at the wrong level

I've cloned the JetBrains/intellij-platform-plugin-template plugin and gotten it to build correctly, but now I'm having trouble figuring out where to go next. Can someone help point me in the right direction?

3 comments
Comment actions Permalink

For those of you following along at home, I've made a tiny bit of progress here and I can actually detect the variable names from the outer postgres context: https://github.com/randvoorhies/plpython3u/blob/main/src/main/java/com/github/randvoorhies/plpython3u/DemoInspectionVisitor.java#L31

Now I think I just need to figure out how to add the right PsiElement thing into the element for each detected variable and I should be good to go. Anyone out there have any ideas how to do that?

Also I'm working in the localInspection extension which doesn't really feel like the right idea, but it was one of the few extensions I could actually copy/paste from some example and get to work. Any advice here on a better extension point to use would also be appreciated.

1
Comment actions Permalink

Hi Randolph!

I'm afraid supporting this in a plugin hits a limit of what the API of the Python plugin offers now. A local inspection won't help here. An inspection can add new warnings inside a code fragment but cannot remove existing ones, as all inspections operate independently. There is a way to suppress the warnings about unresolved references, though. Take a look at PyInspectionExtension#ignoreUnresolvedReference. Applying the same logic as you had in your inspection visitor to detect the right context, you can selectively suppress the warnings about unresolved names inside plpython fragments.

Handling the syntactic errors about indentation and return statement outside of a function is much more difficult, though. Honestly, I don't know how to tackle it without writing a custom Python dialect.

On the other hand, these all seem quite straightforward to fix on a database plugin/DataGrip side, because they are in charge now of injecting Python fragments inside SQL. The platform offers a way to add a custom invisible prefix to an injected fragment before it gets highlighted. If there was something like "def f(SD, plpy, a):" automatically inserted as such a prefix for an example in https://youtrack.jetbrains.com/issue/PY-42699, it would resolve all the errors. SQL support is closed source, however. I contacted their team, let's see if they can help.

1
Comment actions Permalink

Thanks Mikhail, keep me posted.

0

Please sign in to leave a comment.