Josverl / micropython-stubs

Stubs of most MicroPython ports, boards and versions to make writing code that much simpler.
https://micropython-stubs.readthedocs.io
MIT License
133 stars 21 forks source link

Add __call__ for machine Pin and Signal #717

Closed mgsb closed 1 year ago

mgsb commented 1 year ago

Issue #92 comments had the call for Pin, but it is not in the current release. It should be just a copy/rename of the value() method. Adding this for Pin and Signal will allow using pin(1) and signal(0) calls without warnings/errors.

Thanks for this project! I use it frequently with Emacs and the pyvenv and lsp-mode packages for developing my MicroPython projects.

Josverl commented 1 year ago

Can you detail which port and versions of the package you saw this in?

There are quite a few to track through otherwise

Jos

mgsb commented 1 year ago

I am using micropython-esp32 and I believe it is latest (1.19.1). I am willing to work on this if you could provide some guidance. I do not understand how the various "stubs" repos work, and hence, where to make the changes.

Josverl commented 1 year ago

Thanks for the info, with that I can confirm your report:

  1. Micropython documentation lists Pin __call__

  2. The docstubs have the method def __call__(self, x: Optional[Any] = None) -> Any:

  3. The esp32 boardstubs (aka firmware stubs ) do not list the __call__ method

  4. But the resulting esp32 package](https://github.com/Josverl/micropython-stubs/blob/c9faf3ac2c495524fb4d491f6c45326ff565cf2c/publish/micropython-v1_19_1-esp32-stubs/machine.pyi#L750) does not have the __call__ method.

As the process to generate the stubs is mostly automated - a manual change would get overwritten as soon as the next generation cycle runs. ( I just found that I never put the below diagram into the documentation , so thanks for helping me remember that )

I think there are two options to resolve this

  1. Change createstubs.py so that is does include / not skip reporting the __call__ method. Currently it skips/ignores all _underscored methods.
  2. Add an override option in the docstub/boardstub merge process to (forcefully) insert some classes/methods from the documentation that do not exist in the board stubs.

Josverl commented 1 year ago

interestingly at runtime the Pin object does not report that it is callable on esp32 ( but indeed it is) So unfortunately Option 1) will not help solve this (would have been an easy 2-line fix)

('OPEN_DRAIN', '7', "<class 'int'>", 7, 1)
('IRQ_FALLING', '2', "<class 'int'>", 2, 1)
('IRQ_RISING', '1', "<class 'int'>", 1, 1)
('PULL_UP', '2', "<class 'int'>", 2, 1)
('OUT', '3', "<class 'int'>", 3, 1)
('PULL_DOWN', '1', "<class 'int'>", 1, 1)
('WAKE_HIGH', '5', "<class 'int'>", 5, 1)
('DRIVE_0', '0', "<class 'int'>", 0, 1)
('IN', '1', "<class 'int'>", 1, 1)
('WAKE_LOW', '4', "<class 'int'>", 4, 1)
('DRIVE_3', '3', "<class 'int'>", 3, 1)
('DRIVE_1', '1', "<class 'int'>", 1, 1)
('DRIVE_2', '2', "<class 'int'>", 2, 1)
('irq', '<function>', "<class 'function'>", <function>, 2)
('off', '<function>', "<class 'function'>", <function>, 2)
('on', '<function>', "<class 'function'>", <function>, 2)
('init', '<function>', "<class 'function'>", <function>, 2)
('value', '<function>', "<class 'function'>", <function>, 2)
>>> dir(machine.Pin)
['__class__', '__name__', 'value', '__bases__', '__dict__', 'DRIVE_0', 'DRIVE_1', 'DRIVE_2', 'DRIVE_3', 'IN', 'IRQ_FALLING', 'IRQ_RISING', 'OPEN_DRAIN', 'OUT', 'PULL_DOWN', 'PULL_UP', 'WAKE_HIGH', 'WAKE_LOW', 'init', 'irq', 'off', 'on']
>>> p5 = machine.Pin(5, machine.Pin.OUT)
>>> p5.value(1)
>>> p5(0)
Josverl commented 1 year ago

@mgsb

I have automated the addition of the call method and I have added Pin as the baseclass for Signal , so that should inherit that automatically Similar as Switch (although calling Switch makes no sense)

Can you please test to see if this works for you ? you can install the updated stubs from git :

pip install -U "git+https://github.com/Josverl/micropython-stubs/@add_callable#egg=micropython-esp32-stubs&subdirectory=publish/micropython-v1_19_1-esp32-stubs" --no-user --target typings

or

$branch = "add_callable"
$repo = "https://github.com/Josverl/micropython-stubs"
$package = "micropython-esp32-stubs"
$folder = "publish/micropython-v1_19_1-esp32-stubs"
pip install -U "git+$repo/@$branch#egg=$package&subdirectory=$folder" --no-user --target typings
mgsb commented 1 year ago

I installed and see the Pin call now in the .pyi and LSP sessions, but it does not show up for Signal. I do not see Signal as a subclass of Pin the .pyi.

Josverl commented 1 year ago

I found that I/the code did not yet merge the baseclass from the documentation 🤐, I fixed that and added some tests.

there are a few other class/baseclass pairs that need some more work , but for Signal it now should work. image

That should be fixed now, can you give it another try ?

mgsb commented 1 year ago

Thanks - both Pin and Signal __call__ work now in LSP.