2323
2424_system = platform .uname ().system
2525
26+ if _system == 'Windows' :
27+ def platform_exe (name ):
28+ if name .endswith ('.exe' ):
29+ return name
30+ return name + '.exe'
31+ else :
32+ def platform_exe (name ):
33+ return name
34+
35+
2636if _system == 'Linux' :
2737 def ensure_dead_with_parent ():
2838 import ctypes
@@ -165,13 +175,29 @@ def start(self, wait=60, *, server_settings={}, **opts):
165175 for k , v in server_settings .items ():
166176 extra_args .extend (['-c' , '{}={}' .format (k , v )])
167177
168- self ._daemon_process = \
169- subprocess .Popen (
170- [self ._postgres , '-D' , self ._data_dir , * extra_args ],
171- stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL ,
172- preexec_fn = ensure_dead_with_parent )
178+ if _system == 'Windows' :
179+ # On Windows we have to use pg_ctl as direct execution
180+ # of postgres daemon under an Administrative account
181+ # is not permitted and there is no easy way to drop
182+ # privileges.
183+ process = subprocess .run (
184+ [self ._pg_ctl , 'start' , '-D' , self ._data_dir ,
185+ '-o' , ' ' .join (extra_args )],
186+ stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL )
187+ stderr = process .stderr
188+
189+ if process .returncode != 0 :
190+ raise ClusterError (
191+ 'pg_ctl start exited with status {:d}: {}' .format (
192+ process .returncode , stderr .decode ()))
193+ else :
194+ self ._daemon_process = \
195+ subprocess .Popen (
196+ [self ._postgres , '-D' , self ._data_dir , * extra_args ],
197+ stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL ,
198+ preexec_fn = ensure_dead_with_parent )
173199
174- self ._daemon_pid = self ._daemon_process .pid
200+ self ._daemon_pid = self ._daemon_process .pid
175201
176202 self ._test_connection (timeout = wait )
177203
@@ -291,11 +317,16 @@ def add_hba_entry(self, *, type='host', database, user, address=None,
291317
292318 def trust_local_connections (self ):
293319 self .reset_hba ()
294- self .add_hba_entry (type = 'local' , database = 'all' ,
295- user = 'all' , auth_method = 'trust' )
320+
321+ if _system != 'Windows' :
322+ self .add_hba_entry (type = 'local' , database = 'all' ,
323+ user = 'all' , auth_method = 'trust' )
296324 self .add_hba_entry (type = 'host' , address = '127.0.0.1/32' ,
297325 database = 'all' , user = 'all' ,
298326 auth_method = 'trust' )
327+ self .add_hba_entry (type = 'host' , address = '::1/128' ,
328+ database = 'all' , user = 'all' ,
329+ auth_method = 'trust' )
299330 status = self .get_status ()
300331 if status == 'running' :
301332 self .reload ()
@@ -367,8 +398,9 @@ def _test_connection(self, timeout=60):
367398
368399 try :
369400 con = loop .run_until_complete (
370- asyncpg .connect (database = 'postgres' , timeout = 5 ,
371- loop = loop , ** self ._connection_addr ))
401+ asyncpg .connect (database = 'postgres' ,
402+ timeout = 5 , loop = loop ,
403+ ** self ._connection_addr ))
372404 except (OSError , asyncio .TimeoutError ,
373405 asyncpg .CannotConnectNowError ,
374406 asyncpg .PostgresConnectionError ):
@@ -409,11 +441,13 @@ def _find_pg_config(self, pg_config_path):
409441 if pg_config_path is None :
410442 pg_install = os .environ .get ('PGINSTALLATION' )
411443 if pg_install :
412- pg_config_path = os .path .join (pg_install , 'pg_config' )
444+ pg_config_path = platform_exe (
445+ os .path .join (pg_install , 'pg_config' ))
413446 else :
414447 pathenv = os .environ .get ('PATH' ).split (os .pathsep )
415448 for path in pathenv :
416- pg_config_path = os .path .join (path , 'pg_config' )
449+ pg_config_path = platform_exe (
450+ os .path .join (path , 'pg_config' ))
417451 if os .path .exists (pg_config_path ):
418452 break
419453 else :
@@ -434,7 +468,7 @@ def _find_pg_binary(self, binary):
434468 'could not find {} executable: ' .format (binary ) +
435469 'pg_config output did not provide the BINDIR value' )
436470
437- bpath = os .path .join (bindir , binary )
471+ bpath = platform_exe ( os .path .join (bindir , binary ) )
438472
439473 if not os .path .isfile (bpath ):
440474 raise ClusterError (
0 commit comments