A dirty hack for uasyncio webserver bugs on micropython:
TypeError: function takes 2 positional arguments but 3 were given
Introduction:
I just used the uasyncio library on microPython (upy) playform for my ESP32 project. As I was implementing a simple web service using the server provided by this library, the example code below didn’t work on my code sketch:
Error appearance:
1 | import uasyncio as asyncio |
It said:
File “/lib/uasyncio/__init__.py”, line 60, in remove_writer
TypeError: function takes 2 positional arguments but 3 were given
every time I call yield from writer.aclose()
in my code.
#(uasyncio, writer.aclose(), remove_writer)
In order to fix the bug, I dug into the source code to find its defect.
Install uasyncio
——How I installed the uasyncio library on micropython ESP32 build?
1 | import upip |
With an internet connection, the board will search the web with its builtin (but not loaded by default) package manager upip
. It will download the library to /lib/uasyncio/
directory on your ESP32’s file system.
Finding the bug
For a long-time struggle, I finally located where the error occurs. This is the function in __init__.py
of uasyncio library:
1 | import uselect as select |
As I looked up the documentation, the self.poller.unregister()
only receives 2 arguments: (self, fd)
.
So, as the code tries to pass 3 arguments (self.poller, sock, FALSE)
to the poller, the program crashes.
Fix:
My solution, may be a dirty hack:
1 | def remove_writer(self, sock): |
- By just removing the
False
flag argument, the code worked like a charm (at least for my small piece of example code).
Another solution from Github:
1 | def remove_writer(self, sock): |
- Perhaps this one is better a solution.