@@ -79,6 +79,24 @@ def get_localhost() -> Literal["::1", "127.0.0.1"]:
79
79
raise
80
80
81
81
82
+ @public
83
+ def is_unspecified_address (address : str ) -> bool :
84
+ unspecified_address_list = ["" , "0.0.0.0" , "::" ]
85
+ return address in unspecified_address_list
86
+
87
+
88
+ @public
89
+ def convert_unspecified_address_to_localhost (
90
+ address : str
91
+ ) -> Literal ["::1" , "127.0.0.1" ]:
92
+ address_dict = {
93
+ "" : get_localhost (),
94
+ "0.0.0.0" : "127.0.0.1" ,
95
+ "::" : "::1" ,
96
+ }
97
+ return address_dict .get (address , get_localhost ())
98
+
99
+
82
100
class _FakeServer (asyncio .StreamReaderProtocol ):
83
101
"""
84
102
Returned by _factory_invoker() in lieu of an SMTP instance in case
@@ -396,8 +414,15 @@ def __init__(
396
414
loop ,
397
415
** kwargs ,
398
416
)
399
- self ._localhost = get_localhost ()
400
- self .hostname = self ._localhost if hostname is None else hostname
417
+ if is_unspecified_address (hostname ) is True :
418
+ self ._localhost = convert_unspecified_address_to_localhost (hostname )
419
+ self .hostname = hostname
420
+ elif hostname is None :
421
+ self ._localhost = get_localhost ()
422
+ self .hostname = self ._localhost
423
+ else :
424
+ self ._localhost = get_localhost ()
425
+ self .hostname = hostname
401
426
self .port = port
402
427
403
428
def _create_server (self ) -> Coroutine :
@@ -421,7 +446,7 @@ def _trigger_server(self):
421
446
"""
422
447
# At this point, if self.hostname is Falsy, it most likely is "" (bind to all
423
448
# addresses). In such case, it should be safe to connect to localhost)
424
- hostname = self .hostname or self ._localhost
449
+ hostname = self ._localhost if is_unspecified_address ( self . hostname ) is True else self .hostname
425
450
with ExitStack () as stk :
426
451
s = stk .enter_context (create_connection ((hostname , self .port ), 1.0 ))
427
452
if self .ssl_context :
0 commit comments