#PyCharm CircuitPython stubs

1 messages · Page 1 of 1 (latest)

dry robin
#

@haughty solar I have installed PyCharm. Going to use it over VSCode for this. It works now, even with stuff I installed from GitHub and manually mpy compiled. Since the library is at least in the correct search path for PyCharm.

However, what I am trying to figure out is how to get the stubs for the board? The CircuitPython extension for VSCode has some kind of repo of the board stubs, for each board.

haughty solar
#

I don't know about that, I don't know if it's a thing ?

#

I would maybe expect an IDE to have some notion of a "project" to which you add the board drive and its lib directory, giving it knowledge of what is in it, but only py files

dry robin
#

like, he's building some kind of something with this

#

maybe I can simply do a from board import ...?

#

I mean, it looks like they're in there, somehow

#

just wondering how do I target a specific one?

haughty solar
#

oh the board module ?

dry robin
#

yeah

#

in this case an RP2040 feather

#

thank you for your time and help, by the way

#

there's a list of everything supported, but how do I find the stubs?

#

there's that?

#

but it doesn't list the rp2040

haughty solar
#

the built-in modules should be part of circuitpython-stubs, but the board module there contains all pins of all boards, I don't know that there are ways through those stubs to do that

dry robin
#

yeah, I saw it had all of them

haughty solar
#

blinka is the compatiblity layer for Linux boards like the Raspberry pi 4, Beaglebone, and such

dry robin
#

aaah, yeah, true

#

just trying to trace down where it gets those board definitions from in the Python files

#

vendor, product, name, manu, and such

#

from reading some sources some of this is stored in S3, or something?

haughty solar
#

I don't know, I think @autumn citrus might be able to help you
the question is about generating/getting the stubs for a specific board's board module, right ?

autumn citrus
autumn citrus
#

board.c in the core repo for each device is one place to look to find valid pins for any given board, but I'm aware of any way to get that information into pycharm (beyond I guess manually copying the relavent bits into a board.pyi file in the stubs, but that would be impractical at scale for many different device)

dry robin
#

there's that from the vscode extension that does build individual stubs

autumn citrus
#

Interesting. Thanks for the link, that does look promising

dry robin
#

Yeah, I was wondering if there's something we can do for PyCharm that is similar?

#

I've tried the VSCode extension, and while it's pretty decent, it's got a few bugs that are pretty irritating. For instance, if you place a non-bundled .mpy file in your CIRCUITPY dir, it will crash any library operations from that VSCode extension.

autumn citrus
dry robin
#

good catch

autumn citrus
#

Maybe the core stubs could include a little bit of actual python code that allows the user to select a device and builds the pyi for them based on the selected device. Or possibly that could get distributed seperately from the stubs if there is a desire to keep that pypi listing to stubs only and no functional code.

dry robin
#

I would be willing to contribute to this if anybody is game? I'd probably need some help, though.

#

For instance, where would we place it? My guess is that we should probably make this somewhat agnostic and then create a plugin or similar for PyCharm to handle the board selection.

autumn citrus
#

I'd definitely be interested in having this functionality and also willing to help out. I will poke around with this script that you linked later this week and ponder some possible ways we could encorporate that or something similar.

If you're available on Monday's we do a weekly meeting, this might make a good topic for "in the weeds" section to see if other folks have any ideas or input regarding what would be the best way to distribute these individualized board stubs.

dry robin
#

Wonderful. I am available on Mondays. What time?

#

And is this something we do separately from the vscode plugin, or should we plan to contribute back to that project? Maybe make the stubs agnostic for any editor?

autumn citrus
#

I don't have any experience making plugins for PyCharm (or any IDEs) so I've not really looked into that at all yet. Ideally I'd love to come up with a way that it won't require a plugin. I.e. download the core stubs, then run some command passing an argument and something generates and replaces the stock board.pyi file in the stubs.

autumn citrus
dry robin
autumn citrus
# dry robin How do I join the meeting?

Join the #circuitpython-dev channel at the time of the meeting, there is a voice channel here in discord as well and that is where we hold the meeting. You need a specific role in the discord here to be able to speak at the meeting as well. I can give you that role if you'd like, and you'll also get mentioned from it on mondays a bit before the metting.

dry robin
autumn citrus
#

Sure thing. You can always ask any time in #circuitpython-dev to have the circuitpythonista role assigned to you. Me or another mod will take care of it when the time comes.

pure adder
pure adder
#

@autumn citrus @haughty solar to circle back here, I just successfully used a board.pyi from that tar ball in PyCharm and it works

#

the combo of finding the correct one requires parsing the vendor and product ID, and checking the correct folder

#

then including that in the interpreter config's directories

#

I wonder if that [adding path] can be scripted?

autumn citrus
# pure adder Which were a bit difficult to add: https://www.jetbrains.com/help/pycharm/stubs....

this was the process that I used for getting the circuitpython stubs before we figured out how to get the stubs listed on PyPi. Now that they are I can install the stubs with pip and pycharm is able to find and use them for helper hints. I think it may be possible to paste your board.pyi file in the right spot inside of the stubs installed via pip to have it get recognized without needing to do the whole add an interpreter path thing.

pure adder
#

well, maybe

#

you'd have to overwrite a board.pyi file somewhere, no?

#

but from what I can tell, creating local stubs need to completely reproduce the directory structure, basically the same as a mock or whatever

autumn citrus
pure adder
autumn citrus
# pure adder to think this through, then we'd need to back it up, in case the user wants to s...

Need to do a bit of research tbh. I think the board.pyi that is included in the stubs is essentially empty (but I haven't verified this yet). If that is the case then there is really nothing important to switch back to. They could want to switch to another board, in which case I envision running the command again with a different argument for the board that they want to change to.

Maybe it would be good to have a way to do multiple boards, or maybe do away with the idea of it conforming to a specific devices altogether and instead include all possible values in the single board.pyi that gets distributed with the stubs. Then there would be no "second step" of running the command. But as a trade-off the board module would also include things that may not be present / accurate for whatever specific device the user is actually working on. So the IDEs code completion / hints might be a little misleading for any given specific device.

#

The high level choice between those approaches will be good to get input from the group on during the call next week if we can.

#

okay, I have confirmed that the existing board.pyi file that is distributed today does not contain any pin property names:

"""Board specific pin names

Common container for board base pin names. These will vary from board to
board so don't expect portability when using this module.

.. warning:: The board module varies by board. The APIs documented here may or may not be
             available on a specific board."""

from __future__ import annotations

import busio

def I2C() -> busio.I2C:
    """Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton."""
    ...

def SPI() -> busio.SPI:
    """Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a
    singleton."""
    ...

def UART() -> busio.UART:
    """Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton.

    The object created uses the default parameter values for `busio.UART`. If you need to set
    parameters that are not changeable after creation, such as ``receiver_buffer_size``,
    do not use `board.UART()`; instead create a `busio.UART` object explicitly with the
    desired parameters."""
    ...

And does already contain a warning that the values represented in it do not necessarily apply to all devices.

#

Based on that I am inclined to lean toward just including all possible pins in this device. The more I think about the "run a command" approach I think it may not be something that a lot of people actually end up doing. If we include everything at least the file is helpful to everyone and we just have to be clear about it not applying to all devices, which it does mention already.

haughty solar
#

oh I was surprised because in BBEdit board. completes to what looks like all the pin names, but they actually come from Blinka (it uses the jedi language server)

pure adder
autumn citrus
# pure adder is there any meaningful comparison that could happen against, say `board.D10` th...

I think any given pin such as board.D10 would evaluate correctly. The only consequence of containing all possible pins that I can think of is that the IDE would not flag any sort of error if the code in question uses a pin that the users board does not actually have. i.e. it would happily allow you to use board.IO11 without warning since that does exist on some boards, but unless the user is working one of the ones specifically that does have it the code would not actually work as expected on their device.

pure adder
autumn citrus
# pure adder I would want that warning, for sure.

Maybe some kind of hybrid approach could work. By default board.pyi could contain every pin from every device. But we also provide an optional utility with command that can be run to select a specific single device. Running the command overrides the default pyi fill with one generated for the chosen board. The same utility can have a command that reverts back to the default that contains everything.

pure adder
#

That could work. I'm curious to see what people would prefer here. I am more along the lines of I'd rather see a ton of warnings until I have selected a board, than see perfectly happy code that in essence is broken as soon as I upload it to my device.

#

Are there any instances where using the wrong pin could lead to any mechanical or electrical failures? Is that even a concern? Just trying to make sure some kid (probably me) doesn't burn their house down.

autumn citrus
# pure adder Are there any instances where using the wrong pin could lead to any mechanical o...

full disclosure, I come at this from a programming background, not an electrical one. I've learned lots, but my knowledge alone is not up to a point where I would stake safety on it. That being said. It could be possible depending on the circuit and what things are hooked up to the micro-controller. But I think this risk exists regardless of the stubs information. As far as I understand it the stubs for board can only tell you whether a given pin exists. (even in the best case where it's catered to a specific board). It can't tell you much more about the pin i.e. where it's located physically on the hardware, or operating voltages or anything else like that. With that in mind I cannot really think of a scenario where the stubs telling you that a pin does or does not exist (whether or not it's actually correct for the device they are using) could itself increase that risk.

pure adder