@@ -710,25 +710,22 @@ def _get_asyncio_task(self):
710710 return task
711711
712712 def _get_pid_from_process (self , process ):
713- """process could be a subprocess.Popen, multiprocessing.Process or a pid
713+ """process could evaluate to any object with a `process` attribute or an integer
714714 """
715- # They are not used elsewhere so do a lazy import
716- from multiprocessing import Process
717- from subprocess import Popen
718715
719716 try :
720717 process = self ._getval (process )
721718 except :
722719 # Error message is already displayed
723720 return None
724721
725- if isinstance (process , (Process , Popen )):
726- return process .pid
727- elif isinstance (process , int ):
728- return process
722+ pid = getattr (process , "pid" , process )
729723
730- self .error (f"Invalid process { process } " )
731- return None
724+ if not isinstance (pid , int ):
725+ self .error (f"Invalid process { process !r} " )
726+ return None
727+
728+ return pid
732729
733730 def interaction (self , frame , tb_or_exc ):
734731 # Restore the previous signal handler at the Pdb prompt.
@@ -1982,13 +1979,13 @@ def do_debug(self, arg):
19821979
19831980 complete_debug = _complete_expression
19841981
1985- def do_attach (self , process ):
1982+ def do_attach (self , arg ):
19861983 """attach process
19871984
1988- Attach to process, which can be a subprocess.Popen,
1989- multiprocessing.Process or a pid .
1985+ Attach to process, which can be any object that has a pid
1986+ attribute or a process ID .
19901987 """
1991- pid = self ._get_pid_from_process (process )
1988+ pid = self ._get_pid_from_process (arg )
19921989
19931990 if pid is not None :
19941991 self .message (f"Attaching to process { pid } " )
@@ -2780,6 +2777,7 @@ def _ensure_valid_message(self, msg):
27802777 # needs to know it for multi-line editing.
27812778 pass
27822779 case {"attach" : int ()}:
2780+ # Ask the client to attach to the given process ID.
27832781 pass
27842782 case _:
27852783 raise AssertionError (
@@ -3441,6 +3439,12 @@ def _connect(
34413439
34423440def attach (pid , commands = ()):
34433441 """Attach to a running process with the given PID."""
3442+
3443+ if threading .current_thread () is not threading .main_thread ():
3444+ raise RuntimeError (
3445+ "pdb.attach() must be called from the main thread"
3446+ )
3447+
34443448 with ExitStack () as stack :
34453449 server = stack .enter_context (
34463450 closing (socket .create_server (("localhost" , 0 )))
0 commit comments