Page 1 of 1

Best way to "detect" MicroPython

Posted: Sun Jul 22, 2018 5:11 pm
by MrPaul
I'm writing a library which is targeted to be able to run under MicroPython, but also "regular" python and development/unit testing is largely happening under regular python.

There are a few things which need to have differences between them. Typical, of course, is the import; "ucollections" vs. "collections", etc. Since I'll likely be using CircuitPython these are slightly less bothersome, but I'd like to work with all of them. The obvious way is to try importing ucollections (for example) and on import error import collections, but that seems a bit clunky. Is there a better way?

const() is another thing to look out for; I'll need to define it for regular python. What is the most efficient way to detecting if it exists?

A few other places can get icky; for example, pySerial read() is readchar() in UART, but I guess isinstance or the like is a way to tackle those. Or could wrap UART to be minimally pySerial like (or vice versa of course), but would still need someway of telling which python.

I guess I can see solutions for most of these, but was looking for something like a "best practices" to write cross-platform apps.

Re: Best way to "detect" MicroPython

Posted: Mon Jul 23, 2018 3:37 pm
by dhylands
I normally use os.uname().sysname. As far as I know all of the ports also have a builtin micropython module. so you could test if that succeeds or not.

I also typically create wrappers for things like serial ports, which allows me to emulate serial ports on various platforms and even use sockets instead of the serial port.

For example, see: https://github.com/dhylands/json-ipc The serial_port.py, socket_port.py, and stm_usb_port.py are all wrapper which provide the same (or similar) API.

Re: Best way to "detect" MicroPython

Posted: Sun Sep 16, 2018 12:14 am
by HermannSW
dhylands wrote:
Mon Jul 23, 2018 3:37 pm
I normally use os.uname().sysname.
That does return "esp8266" for my ESP-01s MicroPython.
Even uos.uname() does not show the string "MicroPython".
The version could be an indicator, though.
"MicroPython" gets shown when pressing CTRL-B.
Is there a programmatic way to query "MicroPython" string?

Code: Select all

$ ./webrepl_client.py -s
Password: 12345678

WebREPL connected
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> uos.uname().sysname
'esp8266'
>>> uos.uname()
(sysname='esp8266', nodename='esp8266', release='2.0.0(5a875ba)', version='v1.9.4-481-g3cd2c281d on 2018-09-04', machine='ESP module with ESP8266')
>>> \x02

MicroPython v1.9.4-481-g3cd2c281d on 2018-09-04; ESP module with ESP8266
Type "help()" for more information.
>>> 
>>> 

Re: Best way to "detect" MicroPython

Posted: Sun Sep 16, 2018 5:51 am
by pythoncoder
I do it the obvious way:

Code: Select all

try:
    from micropython import const
    upython = True
except ImportError:
    const = lambda x : x
    upython = False

Re: Best way to "detect" MicroPython

Posted: Sun Sep 16, 2018 7:07 am
by Roberthh
Many ways to rome. I use:

Code: Select all

import sys
if sys.implementation.name == "micropython":
	# whatever flag is set then

Re: Best way to "detect" MicroPython

Posted: Sun Sep 16, 2018 10:15 am
by HermannSW
Thanks, that is the easy solution I searched for:

Code: Select all

$ ./webrepl_client.py -s
Password: 12345678

WebREPL connected
>>> import sys
>>> sys.implementation
(name='micropython', version=(1, 9, 4))
>>> 

Re: Best way to "detect" MicroPython

Posted: Sun Sep 16, 2018 1:11 pm
by HermannSW
Works for python3 (on Raspbian) as well (I know that MicroPython is derived from python3):

Code: Select all

$ echo -e "import sys\nprint(sys.implementation)" | python3 -
namespace(_multiarch='arm-linux-gnueabihf', cache_tag='cpython-35', hexversion=50660336, name='cpython', version=sys.version_info(major=3, minor=5, micro=3, releaselevel='final', serial=0))
$ 
Does not work for python2 though:

Code: Select all

$ echo -e "import sys\nprint(sys.implementation)" | python -
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: 'module' object has no attribute 'implementation'
$