-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(yajl2_c) TypeError when reading from an aiofiles file #32
Comments
@MKuranowski thanks for reporting. I can locally reproduce too, which is good (in a way!), but oddly it didn't happen with the unit tests. I'll have to study a bit closer what's going on. |
Our C code was not ready to deal with suspended executions of utils35._get_read, as the logic assumed that once an awaitable was created to get the read function, it would yield the result (via StopIteration) after the first next() invocation. This broken logic meant that when our asynchronous iterable was called again, it would invoke _get_read() again with no arguments, resulting in an exception being thrown. In our unit tests our dummy async read functions don't suspend their execution, which means that when calling the _get_read(f) function from C we have always gotten away with this bug. This patch fixes this problem, correctly iterating as long as necessary on this first awaitable, rather than only once. This is the original problem reported in #32. Signed-off-by: Rodrigo Tobar <rtobar@icrar.org>
Found the problems (there were two actually), both of course in the
I don't think I'll be able to tackle this second until early next week though. In the meanwhile you can workaround this by defining your own thin wrapper around |
Awaitable objects that don't have an __await__ method are probably generators that have been marked with @types.coroutine, and therefore we should be able to use them directly instead. This check needs only to be done when invoking the read() function, as we know our _get_read function is a native coroutine. What we are *not* yet considering are C-defined python types that have an tp_as_async.am_await field defined. For the time being we are assuming those are rare, but it might bite us in the future. This is the second problem found during the investigation of #32. Signed-off-by: Rodrigo Tobar <rtobar@icrar.org>
I just pushed the last set of changes to the A new release will follow probably tomorrow, time permitting. |
A new 3.1.1 release of ijson including these fixes is now available on PyPI. |
Thank you very much, everything's working as intended :) |
Most of python awaitables are native coroutines (async def functions), but the definition of an awaitable includes also generator functions decorated with the @types.coroutine function, named generated-based coroutines. This small difference has bitten us already in the past (see #32 for example), and while doing other work I realized we hadn't seen the end of it. In particular, the automatic detection of the file object given to the main entry point functions of ijson (basic_parse, parse, kvitems and items) didn't recognize file objects with a generator-based read coroutine as asynchronous file objects, and therefore incorrectly routed them to be parsed using the synchronous family of functions, which of course fails. This commit adds detection of file objects with generator-base read() coroutines on the main entry point functions of all backends, correctly routing them through the corresponding *_async function. Signed-off-by: Rodrigo Tobar <rtobar@icrar.org>
Most of python awaitables are native coroutines (async def functions), but the definition of an awaitable includes also generator functions decorated with the @types.coroutine function, named generated-based coroutines. This small difference has bitten us already in the past (see #32 for example), and while doing other work I realized we hadn't seen the end of it. In particular, the automatic detection of the file object given to the main entry point functions of ijson (basic_parse, parse, kvitems and items) didn't recognize file objects with a generator-based read coroutine as asynchronous file objects, and therefore incorrectly routed them to be parsed using the synchronous family of functions, which of course fails. This commit adds detection of file objects with generator-base read() coroutines on the main entry point functions of all backends, correctly routing them through the corresponding *_async function. Signed-off-by: Rodrigo Tobar <rtobar@icrar.org>
Running Python 3.8.2 (on Linux), ijson 3.1.post0, backend
yajl2_c
, aiofiles 0.5.0.When trying to asynchronously get items from a simple json file, a
TypeError: _get_read() missing 1 required positional argument: 'f'
is raised.Code:
test.json:
Output:
I would expect normal operation that would print all items from the test.json file.
Synchronous code works correctly:
Output:
Update: the
yajl2_cffi
backend works correctly:Code:
Output:
The text was updated successfully, but these errors were encountered: