"Empty" TypeError

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Ricardo
Posts: 11
Joined: Mon Dec 09, 2019 9:49 pm

"Empty" TypeError

Post by Ricardo » Mon Jun 22, 2020 4:10 pm

Hi there!

The code below runs fine on CPython (versions 2.7.16, 3.4.10, 3.7.0, ...), but produces a "TypeError" on MicroPython (ESP32 firmware esp32-idf3-20200618-unstable-v1.12-554-gce02d5e34):

Code: Select all

class Cfg(dict):
    def __init__(self, default={}):
        self.update(default)

cfg = Cfg(default={"rate": 30})

print(cfg)
Running the code on CPython, the result is:

Code: Select all

{'rate': 30}
Running the same code on Micropython REPL, the result is:

Code: Select all

Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
  File "<stdin>", line 3, in __init__
TypeError:
>>>
Is this a known bug / limitation of MicroPython?

Is there any suggested workaround?

Thanks!

Ricardo
Posts: 11
Joined: Mon Dec 09, 2019 9:49 pm

Re: "Empty" TypeError

Post by Ricardo » Mon Jun 22, 2020 6:46 pm

Oddly enough, this code works on MicroPython:

Code: Select all

class Cfg(dict):
    pass

cfg = Cfg()
cfg.update({"rate": 30})
print(cfg)
The result is, as expected:

Code: Select all

{'rate': 30}
Now I'm using something like this as a workaround, but I wonder if this issue is a bug in MicroPython...

Christian Walther
Posts: 169
Joined: Fri Aug 19, 2016 11:55 am

Re: "Empty" TypeError

Post by Christian Walther » Mon Jun 22, 2020 8:28 pm

It’s probably an instance of the vaguely documented known limitation “subclassing native classes is not fully supported in MicroPython” (http://docs.micropython.org/en/latest/g ... ubclassing).

Ricardo
Posts: 11
Joined: Mon Dec 09, 2019 9:49 pm

Re: "Empty" TypeError

Post by Ricardo » Mon Jun 22, 2020 9:10 pm

Looks like you've hit the target! Thanks, Christian!

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: "Empty" TypeError

Post by SpotlightKid » Mon Jun 22, 2020 9:33 pm

You can always delegate instead of inheriting:

Code: Select all

class Cfg:
    def __init__(self, default={}):
        self._dict = {}
        self._dict.update(default)

    def __getattr__(self, name):
        return getattr(self._dict, name)
    
    def __getitem__(self, name):
        return self._dict[name]
    
    def __repr__(self):
        return repr(self._dict)

    # plus any other special methods you need
    
cfg = Cfg(default={"rate": 30})
print(cfg)

Ricardo
Posts: 11
Joined: Mon Dec 09, 2019 9:49 pm

Re: "Empty" TypeError

Post by Ricardo » Mon Jun 22, 2020 9:46 pm

SpotlightKid wrote:
Mon Jun 22, 2020 9:33 pm
You can always delegate instead of inheriting:
True! It is a bigger workaround, though, but one to keep in mind. Thanks!

Post Reply