micropython/python3 compatible modules

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
User avatar
curt
Posts: 25
Joined: Thu Jul 29, 2021 3:52 am
Location: Big Lake, Alaska

micropython/python3 compatible modules

Post by curt » Sat Jun 18, 2022 6:11 pm

I am working on a module that will normally run under micopython but can be used with python3

After finding many ways to include the time.ticks_* upython functions in python3, this is the only coding that worked. Is this acceptable or is there a better approach?

Code: Select all

try :
    import utime as time
except :
    from types import MethodType
    import time as time
    def ticks_ms(self):
        return int (round (time.time () * 1000))
    def ticks_add(self, ms_1, ms_2):
        return ms_1 + ms_2
    def ticks_diff(self, ms_1, ms_2):
        return ms_1 - ms_2
    def sleep_ms (self, ms_1) :
        return time.sleep (ms_1 / 1000)
    time.ticks_ms = MethodType (ticks_ms, time)
    time.ticks_add = MethodType (ticks_add, time)
    time.ticks_diff = MethodType (ticks_diff, time)
    time.sleep_ms = MethodType (sleep_ms, time)
In my module's example applications there is code I want to leave out code (machine.WDT for example) if not running with upython. Is there a way to determine it the application is running with upython?

Thanks,
Curt

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: micropython/python3 compatible modules

Post by jimmo » Mon Jun 20, 2022 4:09 am

curt wrote:
Sat Jun 18, 2022 6:11 pm
Is there a way to determine it the application is running with upython?
There are a few ways, but probably the simplest is that `sys.implementation.name` will always be "micropython".

The other common approach is the try/except module import.

One thing you can do is monkeypatch CPython's time module at startup. So maybe write a cpython_patch.py that you only import when running on CPython that does

Code: Select all

import time
def ticks_ms(self):
        return int (round (time.time () * 1000))
time.ticks_ms = ticks_ms
...
(I realise this situation isn't ideal... I think we should probably eventually move all MicroPython-specific functionality into different modules, so that a common "micropython-on-cpython" library can be maintained)

User avatar
curt
Posts: 25
Joined: Thu Jul 29, 2021 3:52 am
Location: Big Lake, Alaska

Re: micropython/python3 compatible modules

Post by curt » Mon Jun 20, 2022 6:26 pm

Thanks @jimmo for your suggestions and explanations they were very helpful.

I decided to go with "sys.implementation.name" as the most direct way to determine which python is running the application. Testing modules works but module implementation can change over time.

Adding methods to modules appears to be more complicated in python3 (see code in my original post).

My final (well work in progress) code below does what I wanted

Code: Select all

import sys
MICRO_PYTHON = sys.implementation.name == "micropython"

#---- Example module:
from poll_looper import PollLooper

#---- Example plugins:
from pi_shutdown_timer import ShutdownTimer
from pi_template import PlugInTemplate
if MICRO_PYTHON :               # micropython only
    from pi_watchdog import Watchdog

POLL_INTERVAL = 250             # milliseconds

#-------------------------------------------------------------------------------
# main
#-------------------------------------------------------------------------------

poller = PollLooper (POLL_INTERVAL)

poller.poll_add (ShutdownTimer (poller ,
                                minutes = 0 ,
                                seconds = 30))
poller.poll_add (PlugInTemplate (poller ,
                                poll_seconds = 5))

if MICRO_PYTHON :               # micropython only
    poller.poll_add (Watchdog (poller))

poller.poll_start ()
Curt

Post Reply