@@ -514,13 +514,45 @@ def configure_tornado_logger(self):
514514 handler .setFormatter (formatter )
515515 logger .addHandler (handler )
516516
517+ def _init_asyncio_patch (self ):
518+ """set default asyncio policy to be compatible with tornado
519+
520+ Tornado 6 (at least) is not compatible with the default
521+ asyncio implementation on Windows
522+
523+ Pick the older SelectorEventLoopPolicy on Windows
524+ if the known-incompatible default policy is in use.
525+
526+ do this as early as possible to make it a low priority and overrideable
527+
528+ ref: https://github.com/tornadoweb/tornado/issues/2608
529+
530+ FIXME: if/when tornado supports the defaults in asyncio,
531+ remove and bump tornado requirement for py38
532+ """
533+ if sys .platform .startswith ("win" ) and sys .version_info >= (3 , 8 ):
534+ import asyncio
535+ try :
536+ from asyncio import (
537+ WindowsProactorEventLoopPolicy ,
538+ WindowsSelectorEventLoopPolicy ,
539+ )
540+ except ImportError :
541+ pass
542+ # not affected
543+ else :
544+ if type (asyncio .get_event_loop_policy ()) is WindowsProactorEventLoopPolicy :
545+ # WindowsProactorEventLoopPolicy is not compatible with tornado 6
546+ # fallback to the pre-3.8 default of Selector
547+ asyncio .set_event_loop_policy (WindowsSelectorEventLoopPolicy ())
548+
517549 @catch_config_error
518550 def initialize (self , argv = None ):
551+ self ._init_asyncio_patch ()
519552 super (IPKernelApp , self ).initialize (argv )
520553 if self .subapp is not None :
521554 return
522- # register zmq IOLoop with tornado
523- zmq_ioloop .install ()
555+
524556 self .init_blackhole ()
525557 self .init_connection_file ()
526558 self .init_poller ()
0 commit comments