Async Constructor (__ainit__)

1,611 views
Skip to first unread message

Imran Geriskovan

unread,
Jan 31, 2016, 6:51:16 AM1/31/16
to python...@googlegroups.com
Currently class instances can not
directly be created asyncronously.

Yes, there are other means for async
creation. (As we have discussed before,
factories, __new__ is a coroutine, etc)

However, having all creation logic, under
the class definition and similar to
__init__ is more elegant.

Regards,
Imran

Hynek Schlawack

unread,
Jan 31, 2016, 8:31:11 AM1/31/16
to python...@googlegroups.com
Generally speaking having side-effects in __init__ is a bad idea since it among others inhibits testability.

There has been a great blog post on that topic that goes great lengths to plot out all the downsides: http://as.ynchrono.us/2014/12/asynchronous-object-initialization.html

Adding async initializers would hence only foster the adoption of anti-patterns.

—h

Imran Geriskovan

unread,
Jan 31, 2016, 10:19:40 AM1/31/16
to Hynek Schlawack, python...@googlegroups.com
Did you mean this? :

aresult = await someafunc() # Good
aobject = await AClass() # Bad!!
bobject = await somefuncreturningBOjbect() # Good???

Interesting. What is the difference?
Is it python's duty to make Bad! style,
anti-patterns impossible?

I think there is no relation between microblog,
sqlite, etc with the subject.

Yann Kaiser

unread,
Jan 31, 2016, 1:48:56 PM1/31/16
to Imran Geriskovan, Hynek Schlawack, python...@googlegroups.com
I'd say using a classmethod is rather elegant as it lets you factor out the requests for awaitables which you'd most likely want to replace in testing.

Hynek Schlawack

unread,
Feb 1, 2016, 3:16:55 AM2/1/16
to Yann Kaiser, Imran Geriskovan, python...@googlegroups.com
I was about to write a longer response but this the nail on the head.

If you can’t construct an object without side-effects, it’s a pain to test.  I have class methods like Service.start() that will do all the side-effect-y stuff and initialize the Service class with the results.

Now if I want to test that class, I can inject anything I want.

Yury Selivanov

unread,
Feb 1, 2016, 12:03:05 PM2/1/16
to python...@googlegroups.com
Hi Imran,
I don't think it's possible to implement this (even if
we would like to).

See, in "await something()", "await" receives the result
of "something()". So even if "something" is a class with
an "__ainit__", it will be already instantiated (with
__init__ and __new__).

Right now, "await obj" checks for an __await__ method.
Adding __ainit__ in the mix, with unclear semantics,
would only complicate things and make a negative
performance impact.

Yury

Imran Geriskovan

unread,
Feb 2, 2016, 4:10:11 AM2/2/16
to Yury Selivanov, python...@googlegroups.com
>> Currently class instances can not
>> directly be created asyncronously.

> Right now, "await obj" checks for an __await__ method.
> Adding __ainit__ in the mix, with unclear semantics,
> would only complicate things and make a negative
> performance impact.
> Yury

Thanks Yury for the explanation.
Then, instead of "await" we need something like

aobj = ainit AClass()

However, I'm not sure if its proper.

Anyway, there is also an unsettled discussion
for async C++ styles. Once you go ahead
with "await" prefixes, this results in
"two replicated code islands" with approximately
same content but one with "await" s and the other
with plain old style. So there is also a search
for async approach without specific keywords.
So, the moral of the story is additional
keywords are bad.

While this is not directly related to my
request for __ainit__, it is an other view
about the unsettled state of the async
programming in general. And it is not specific
to python.

Regards,
Imran
Reply all
Reply to author
Forward
0 new messages