Re: How to get a raised exception from other thread

2005-10-22 Thread dcrespo
 One suggestion about the above: description is actually the exception
 instance (the object), not just the description.

Yes. In fact, it's a tuple. Maybe, I'll change it for just printing the
second item of it.

Thanks a lot.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-21 Thread Peter Hansen
dcrespo wrote:
 Ok, sorry about the above question. I solved it adding this to the main
 thread:
 
 try:
 SrvrTCP = module.ThreadedTCPServer(ip,port)
 SrvrTCP.start()
 except Exception, description:
 MsgBox(self,TCPServer
 Error:\n\n+str(description),title=TCPServer,style=wx.OK |
 wx.ICON_ERROR)
 return
 
 Peter, thank you very much.

You're quite welcome.  It's nice to be able to provide a perfect 
answer, for a change. :-)

One suggestion about the above: description is actually the exception 
instance (the object), not just the description.  The except statement 
can take two items after: the exception type(s) to catch and, 
optionally, a name to bind to the exception instance.  But since 
exception objects know how to represent themselves as strings, calling 
str() on it gives you the description you wanted.  Therefore it would be 
more readable/correct to say this:

except Exception, ex:
 MsgBox(. str(ex) ... )

But I'm happy it works either way!

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-21 Thread WalterHoward

Peter Hansen wrote:
 [EMAIL PROTECTED] wrote:
  Nevermind.  I found a better solution.  I used shared memory to create
  a keep-alive flag.  I then use the select function with a specified
  timeout, and recheck the keep-alive flag after each timeout.

 As Dennis points out, your original attempt was destined to fail because
 you were calling the method from the main thread, not the one you wanted
 to kill.  Threads don't magically execute any methods that are attached
 to the Thread instance just because they're attached.  You have to
 actually call those methods *from* the thread, which means from the
 run() method or from any of the routines it calls (whether they are
 methods on that Thread or not), but it must be done in the context of
 the thread you want to raise exceptions in or it won't work.

 More importantly, you've now described your use case (and I hope that of
 the OP as well, since he hasn't replied yet): killing threads.

 This is an oft-discussed topic here, and searching the archives will
 probably give you lots more answers, but the short answer is you cannot
 kill a thread in Python (except by exiting the entire process). Instead,
 as you've discovered, you must ask it nicely to exit.  The nearly
 canonical approach to doing that is as follows:

 class MyThread(threading.Thread):
  def __init__(self, *args, **kwargs):
  threading.Thread.__init__(self, *args, **kwargs)
  self._keepRunning = True

  def stop(self, timeout=None):
  self._keepRunning = False
  # optional: wait for thread to exit
  self.join(timeout=timeout)

  def run(self):
  while self._keepRunning:
  # do stuff here

 Now you can do things like this:

 thread = MyThread()
 thread.start()
 # other stuff...
 thread.stop()# block here until the thread exits
 
 I hope that clarifies things a little more...
 
 -Peter

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-19 Thread Antoon Pardon
Op 2005-10-18, dcrespo schreef [EMAIL PROTECTED]:
 Before, after, or during the .start() call, or somewhere else?

 I'd like to catch *just after* the .start() call.

 I'm quite sure the problem you are trying to solve can be solved, but
 you are still describing part of the solution you believe you need,
 rather than explaining why you want to do this (which may let us show
 you other, simpler or cleaner ways to accomplish your goals).

 The thing is that I have in ProgramB a class derived from
 threading.Thread, that runs a TCPServer, listening to a port on local
 ip address.

 As you surely know, you have to specify certain parameters when
 instantiating the tcpserver:

 SocketServer.TCPServer(server_address, RequestHandlerClass)
 where server_address is a tuple (ip,port)
 ip has to be one of three modes of values (If I remember well):

 1. A null string ''
Listens on all IP local address

 2. A string containing the local IP address where you want it to listen
Listens only in the specified local IP address

 3. A string containing localhost.
Listens only for connections from localhost.

 Here comes the problem:
 When you specify the case number 2, the IP must be valid for the
 computer where the program runs, otherwise, it raises an exception
 saying that Can't assign requested address.
 The TCPServer class, defined in a module, is ran (instantiatedly) from
 the main program through a started thread. The thread also is in the
 same module as TCPServer class.
 It looks like (it's much more code than this. If you want the whole
 code, tell me):

 MainProgram.py
 ...
 SrvrTCP = module.ThreadedTCPServer(ip,port)
 SrvrTCP.start()
 #Here, I want to know if the TCPServer started well.
 ...


 module.py
 ...
 class ThreadedTCPServer(threading.Thread):

 def __init__(self, ip,port):
 threading.Thread.__init__(self)
 self.ip= ip
 self.port= port

 def run(self):
 TCPServer((self.ip,self.port)) #Here, if the self.ip is
 invalid, it raises an exception.

Just a suggestion, but since it is the main thread you want notified,
you could use signals here. Something like the following:

MainProgram.py

class TCPProblem(Exception):
  pass

def signalcallback(signum, frame):
  raise TCPProblem

signal.signal(signal.SIGHUP, signalcallback)

SrvrTCP = module.ThreadedTCPServer(ip,port)
SrvrTCP.start()
...


module.py

mainpid = os.getpid()

class ThreadedTCPServer(threading.Thread):

def __init__(self, ip,port):
threading.Thread.__init__(self)
self.ip= ip
self.port= port

def run(self):
try:
  TCPServer((self.ip,self.port)) #Here, if the self.ip is invalid, it 
raises an exception.
except ...:
  os.kill(mainpid, signal.SIGHUP)
  
-- 
Antoon Pardon

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-19 Thread dcrespo
 Now that may not be perfect, since I'm not familiar with the TCPServer()
 call.  I've sort of assumed it does something quickly and returns, or
 raises an exception if the input is bad.  If it doesn't actually return
 if it starts successfully, you would need a little different approach.
 Probably adding a simple timeout to the self.startEvent.wait() call
 would work.

It's perfect! Thank you very much.

After the .start() call in the main thread, it just waits until was a
succesfull thread start. It's just perfect.

One more thing, I would like to catch the description string of the
error, so I can show it to the user in a Message Box. How can I do that
in the main threa, once that I allready catched the exception?

Thank you so much

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-19 Thread dcrespo
Ok, sorry about the above question. I solved it adding this to the main
thread:

try:
SrvrTCP = module.ThreadedTCPServer(ip,port)
SrvrTCP.start()
except Exception, description:
MsgBox(self,TCPServer
Error:\n\n+str(description),title=TCPServer,style=wx.OK |
wx.ICON_ERROR)
return

Peter, thank you very much.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-18 Thread dcrespo
 Before, after, or during the .start() call, or somewhere else?

I'd like to catch *just after* the .start() call.

 I'm quite sure the problem you are trying to solve can be solved, but
 you are still describing part of the solution you believe you need,
 rather than explaining why you want to do this (which may let us show
 you other, simpler or cleaner ways to accomplish your goals).

The thing is that I have in ProgramB a class derived from
threading.Thread, that runs a TCPServer, listening to a port on local
ip address.

As you surely know, you have to specify certain parameters when
instantiating the tcpserver:

SocketServer.TCPServer(server_address, RequestHandlerClass)
where server_address is a tuple (ip,port)
ip has to be one of three modes of values (If I remember well):

1. A null string ''
   Listens on all IP local address

2. A string containing the local IP address where you want it to listen
   Listens only in the specified local IP address

3. A string containing localhost.
   Listens only for connections from localhost.

Here comes the problem:
When you specify the case number 2, the IP must be valid for the
computer where the program runs, otherwise, it raises an exception
saying that Can't assign requested address.
The TCPServer class, defined in a module, is ran (instantiatedly) from
the main program through a started thread. The thread also is in the
same module as TCPServer class.
It looks like (it's much more code than this. If you want the whole
code, tell me):

MainProgram.py
...
SrvrTCP = module.ThreadedTCPServer(ip,port)
SrvrTCP.start()
#Here, I want to know if the TCPServer started well.
...


module.py
...
class ThreadedTCPServer(threading.Thread):

def __init__(self, ip,port):
threading.Thread.__init__(self)
self.ip= ip
self.port= port

def run(self):
TCPServer((self.ip,self.port)) #Here, if the self.ip is
invalid, it raises an exception.
...

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-18 Thread Peter Hansen
dcrespo wrote:
Before, after, or during the .start() call, or somewhere else?
 I'd like to catch *just after* the .start() call.

Excellent.  That makes it pretty easy then, since even though you are 
spawning a thread to do the work, your main thread isn't expected to 
continue processing in parallel.  See my draft solution below.  If it 
doesn't seem to suit, explain where it fails you and we can try to 
evolve it (assuming we're on the same page at all here).

 When you specify the case number 2, the IP must be valid for the
 computer where the program runs, otherwise, it raises an exception
 saying that Can't assign requested address.
 
 MainProgram.py
 ...
 SrvrTCP = module.ThreadedTCPServer(ip,port)
 SrvrTCP.start()
  #Here, I want to know if the TCPServer started well.

Leave that part as it is.  We'll override the start() method in your 
subclass to solve your problem.

 module.py
 ...
 class ThreadedTCPServer(threading.Thread):
 
 def __init__(self, ip,port):
 threading.Thread.__init__(self)
 self.ip= ip
 self.port= port
   self.startError = None
   self.startedEvent = threading.Event()


   def start(self):
   '''start thread and wait for successful start'''
   threading.Thread.start(self)
   self.startedEvent.wait()
   if self.startError:
   raise self.startError


 def run(self):
 TCPServer((self.ip,self.port)) #Here, if the self.ip is
 invalid, it raises an exception.
 ...

We have to change the run() method slightly now:

   def run(self):
   try:
   try:
   TCPServer((self.ip, self.port))
   except Exception, ex:
   self.startError = ex
   return
   finally:
   self.startedEvent.set()

   # do the rest of the existing run() code here


Now that may not be perfect, since I'm not familiar with the TCPServer() 
call.  I've sort of assumed it does something quickly and returns, or 
raises an exception if the input is bad.  If it doesn't actually return 
if it starts successfully, you would need a little different approach. 
Probably adding a simple timeout to the self.startEvent.wait() call 
would work.

Note also that you don't get the full original traceback with this 
technique.  I'm not sure you can, actually (though I can imagine that 
with Python one could stitch together a traceback from a previous 
exception as one raises a new exception).  From what you describe, 
however, it sounds like you just need to know that the exception 
occurred, not the precise line of code down in TCPServer() where it was 
originally raised.

I hope that helps and/or gives you some leads on a better solution.

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Alex Martelli
[EMAIL PROTECTED] wrote:

 Nevermind.  I found a better solution.  I used shared memory to create
 a keep-alive flag.  I then use the select function with a specified
 timeout, and recheck the keep-alive flag after each timeout.

Definitely a better architecture.  Anyway, one supported way for a
thread to raise an exception in a different thread is function
thread.interrupt_main(), which raises a KeyboardInterrupt in the *main*
thread (the one thread that's running at the beginning of your program).

There's also a supported, documented function to raise any given
exception in any existing thread, but it's deliberately NOT directly
exposed to Python code -- you need a few lines of  C-coded extension (or
pyrex, ctypes, etc, etc) to get at the functionality.  This small but
non-null amount of attrition was deliberately put there to avoid
casual overuse of a facility intended only to help in very peculiar
cases (essentially in debuggers c, where the thread's code may be buggy
and fail to check a keep-alive flag correctly...!-).


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Antoon Pardon
Op 2005-10-14, dcrespo schreef [EMAIL PROTECTED]:
 Hi all,

 How can I get a raised exception from other thread that is in an
 imported module?

 For example:

You could try the following class, it needs ctypes and if the exception
is raised while in a C-extention, the exception will be delayed until
the extention is left. Some delay is unavoidable. You may also need
to fiddle with the length of the sleep at the end of this script 
or the values in the xrange calls in the Continue threads

 except.py 

import os
import ctypes
from time import sleep
from random import randint


class TimeOut(Exception):
  pass


class Alarm(Exception):
  pass

import threading

class Xthread(threading.Thread):


  def start(self):
self.__original_run = self.run
self.run = self.__run 
threading.Thread.start(self)


  def __run(self):
self.__thrd_id = threading._get_ident()
try:
  self.__original_run()
finally:
  self.run = self.__original_run


  def raize(self, excpt):

Nr = ctypes.pythonapi.PyThreadState_SetAsyncExc(self.__thrd_id, 
ctypes.py_object(excpt))
while Nr  1:
  ctypes.pythonapi.PyThreadState_SetAsyncExc(self.__thrd_id, None)
  sleep(0.1)
  Nr = ctypes.pythonapi.PyThreadState_SetAsyncExc(self.__thrd_id, 
ctypes.py_object(excpt))

  def alarm(self, tm):

alrm = threading.Timer(tm, self.raize, (TimeOut,))
alrm.start()
return alrm

class Continue(Xthread):

  def run(self):

self.id = os.getpid()
print self.id, Begin
i = 0
try:
  for _ in xrange(randint(0,20)):
for e in xrange(4 * 10):
i = i + e
  print self.id, Finished
except Alarm:
  print self.id, Interupted


lst = [Continue() for _ in xrange(10)]

for T in lst:
  T.start()

try:
  sleep(15)
finally:
  for T in lst:
T.raize(Alarm)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Antoon Pardon
Op 2005-10-17, Alex Martelli schreef [EMAIL PROTECTED]:
[EMAIL PROTECTED] wrote:

 Nevermind.  I found a better solution.  I used shared memory to create
 a keep-alive flag.  I then use the select function with a specified
 timeout, and recheck the keep-alive flag after each timeout.

 Definitely a better architecture.  Anyway, one supported way for a
 thread to raise an exception in a different thread is function
 thread.interrupt_main(), which raises a KeyboardInterrupt in the *main*
 thread (the one thread that's running at the beginning of your program).

 There's also a supported, documented function to raise any given
 exception in any existing thread, but it's deliberately NOT directly
 exposed to Python code -- you need a few lines of  C-coded extension (or
 pyrex, ctypes, etc, etc) to get at the functionality.  This small but
 non-null amount of attrition was deliberately put there to avoid
 casual overuse of a facility intended only to help in very peculiar
 cases (essentially in debuggers c, where the thread's code may be buggy
 and fail to check a keep-alive flag correctly...!-).

I find this rather arrogant. It is not up to the developers of python
to decide how the users of python will use the language. If someone
has use of specific functionality he shouldn't be stopped because his
use is outside the intentions of the developers.

Just suppose you are writing a chess program. You let the program
think while it is the users move, but this thinking has to be
interrupted and some cleanup has to be made after the users move
has made a lot of this thinking obsolete by his move. Such code
could be mixture of loops and recursion that makes use of a simple
flag to end it all, unpractical. Use of an exception raised from
somewhere else would IMO in this case be an acceptable choice.

Why should the coder of this software have to go through this
deliberate set up attrition, to get at this functionality, just
because it wasn't intented to be used in such a way by the
developers?

As far as I know, pyrex and ctypes weren't intended to get
at the Python/C api. But they didn't create extra hurdles
for those who could use it that way.

-- 
Antoon Pardon
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Steve Holden
Antoon Pardon wrote:
 Op 2005-10-17, Alex Martelli schreef [EMAIL PROTECTED]:
 
[EMAIL PROTECTED] wrote:


Nevermind.  I found a better solution.  I used shared memory to create
a keep-alive flag.  I then use the select function with a specified
timeout, and recheck the keep-alive flag after each timeout.

Definitely a better architecture.  Anyway, one supported way for a
thread to raise an exception in a different thread is function
thread.interrupt_main(), which raises a KeyboardInterrupt in the *main*
thread (the one thread that's running at the beginning of your program).

There's also a supported, documented function to raise any given
exception in any existing thread, but it's deliberately NOT directly
exposed to Python code -- you need a few lines of  C-coded extension (or
pyrex, ctypes, etc, etc) to get at the functionality.  This small but
non-null amount of attrition was deliberately put there to avoid
casual overuse of a facility intended only to help in very peculiar
cases (essentially in debuggers c, where the thread's code may be buggy
and fail to check a keep-alive flag correctly...!-).
 
 
 I find this rather arrogant. It is not up to the developers of python
 to decide how the users of python will use the language. If someone
 has use of specific functionality he shouldn't be stopped because his
 use is outside the intentions of the developers.
 
The developers have to support (at no cost) what the users do, so if 
they want to make use of certain features inaccessible to users who are 
likely to go wrong then that's up to them.

 Just suppose you are writing a chess program. You let the program
 think while it is the users move, but this thinking has to be
 interrupted and some cleanup has to be made after the users move
 has made a lot of this thinking obsolete by his move. Such code
 could be mixture of loops and recursion that makes use of a simple
 flag to end it all, unpractical. Use of an exception raised from
 somewhere else would IMO in this case be an acceptable choice.
 
In *your* opinion, possibly. In my opinion it would seem to make more 
sense to have the worker thread code examine a shared flag and raise an 
exception at some convenient point in its calculation cycle. Otherwise 
you have to write the worker thread to be capable of handling 
asynchronous signals, which is a notoriously difficult task. I presume 
this is why Alex commented that he thought the OP's better solution 
was definitely a better architecture.

 Why should the coder of this software have to go through this
 deliberate set up attrition, to get at this functionality, just
 because it wasn't intented to be used in such a way by the
 developers?
 
Because otherwise people who know no better will use the feature for 
purposes where it's not the best way to achieve the required 
functionality, leading to yet more endless discussions about why it 
doesn't work. Asynchronous signalling between threads is an accident 
waiting to happen in the hands of an inexperienced programmer.

 As far as I know, pyrex and ctypes weren't intended to get
 at the Python/C api. But they didn't create extra hurdles
 for those who could use it that way.
 
This seems like a complete non sequitur to me. Let's stick to the point.

regards
  Steve
-- 
Steve Holden   +44 150 684 7255  +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006  www.python.org/pycon/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Paul Rubin
Steve Holden [EMAIL PROTECTED] writes:
 Otherwise you have to write the worker thread to be capable of
 handling asynchronous signals, which is a notoriously difficult task.

Doing it properly needs a language extension.

http://www.cs.williams.edu/~freund/papers/02-lwl2.ps
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Antoon Pardon
Op 2005-10-17, Steve Holden schreef [EMAIL PROTECTED]:
 Antoon Pardon wrote:
 Op 2005-10-17, Alex Martelli schreef [EMAIL PROTECTED]:
 
[EMAIL PROTECTED] wrote:


Nevermind.  I found a better solution.  I used shared memory to create
a keep-alive flag.  I then use the select function with a specified
timeout, and recheck the keep-alive flag after each timeout.

Definitely a better architecture.  Anyway, one supported way for a
thread to raise an exception in a different thread is function
thread.interrupt_main(), which raises a KeyboardInterrupt in the *main*
thread (the one thread that's running at the beginning of your program).

There's also a supported, documented function to raise any given
exception in any existing thread, but it's deliberately NOT directly
exposed to Python code -- you need a few lines of  C-coded extension (or
pyrex, ctypes, etc, etc) to get at the functionality.  This small but
non-null amount of attrition was deliberately put there to avoid
casual overuse of a facility intended only to help in very peculiar
cases (essentially in debuggers c, where the thread's code may be buggy
and fail to check a keep-alive flag correctly...!-).
 
 
 I find this rather arrogant. It is not up to the developers of python
 to decide how the users of python will use the language. If someone
 has use of specific functionality he shouldn't be stopped because his
 use is outside the intentions of the developers.
 
 The developers have to support (at no cost) what the users do,

Only in so far that correct programs behave correctly. The developers
are not obligated to correct buggy programs. They have every right to
say that if a programmor can handle certain concepts he should seek
help with that concept elsewhere.

 so if 
 they want to make use of certain features inaccessible to users who are 
 likely to go wrong then that's up to them.

But the way it is made inaccessible has nothing to do with knowing
how to use the feature. That you can dable with C-extententions, pyrex
or ctypes says nothing about your ability to handle threads that
raise exceptions in each other.

 Just suppose you are writing a chess program. You let the program
 think while it is the users move, but this thinking has to be
 interrupted and some cleanup has to be made after the users move
 has made a lot of this thinking obsolete by his move. Such code
 could be mixture of loops and recursion that makes use of a simple
 flag to end it all, unpractical. Use of an exception raised from
 somewhere else would IMO in this case be an acceptable choice.
 
 In *your* opinion, possibly. In my opinion it would seem to make more 
 sense to have the worker thread code examine a shared flag and raise an 
 exception at some convenient point in its calculation cycle.

What it there is no such convenient point? What if you have a number
of differnt routines that recursively call each other each with its
own number of nested loops. If you want something that is a bit
responsive you will have to put a check for this flag in any loop.

 Otherwise 
 you have to write the worker thread to be capable of handling 
 asynchronous signals, which is a notoriously difficult task. I presume 
 this is why Alex commented that he thought the OP's better solution 
 was definitely a better architecture.

IMO the flag is the better architecture in this case because python
can't interrupt a tread with an exception while that thread is in
C-code.

 Why should the coder of this software have to go through this
 deliberate set up attrition, to get at this functionality, just
 because it wasn't intented to be used in such a way by the
 developers?
 
 Because otherwise people who know no better will use the feature for 
 purposes where it's not the best way to achieve the required 
 functionality, leading to yet more endless discussions about why it 
 doesn't work.

Then don't react to those questions. A lot of questions about threads
are already answered as follows: Don't use threads, use twised or
If you have to use threads, use Queues. IMO there is nothing wrong
with telling people that if they want to use certain features it is
expected they know what thet are doing.

 Asynchronous signalling between threads is an accident 
 waiting to happen in the hands of an inexperienced programmer.

So? Do we want python to be limited to features that can't
cause problems in the hands of an inexperienced programmer?

-- 
Antoon Pardon
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Lasse Vågsæther Karlsen
Steve Holden wrote:
snip
 Why should the coder of this software have to go through this
 deliberate set up attrition, to get at this functionality, just
 because it wasn't intented to be used in such a way by the
 developers?

 Because otherwise people who know no better will use the feature for 
 purposes where it's not the best way to achieve the required 
 functionality, leading to yet more endless discussions about why it 
 doesn't work. Asynchronous signalling between threads is an accident 
 waiting to happen in the hands of an inexperienced programmer.

I can't agree with that opinion. There's tons of features of existing 
programming languages and systems, Python included, that is pretty much 
guaranteed to be misused, and badly at that. We can't remove those just 
on the off chance someone might start a thread on a newsgroup about why 
this is or isn't the best way to do things. If we do that then I guess 
list comprehension is out the window because there's tons of posts (from 
me included) that get this wrong.

The point of a programming language is not to dumb down the environment 
to a point where it is impossible to write bad code. Instead it's about 
empowering the programmers to be able to accomplish their tasks.

In any case, this exception-in-another-thread problem has inherent 
issues which must be solved, among others:

- C extension code can't be interrupted
- an exception thrown at the wrong time in a finally/except block might 
cause more problems than it intends to solve

So until a good implementation exists, there shouldn't be any point in 
actually discussing the motives of the programmers who wishes to use the 
feature.

snip

-- 
Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:[EMAIL PROTECTED]
PGP KeyID: 0x2A42A1C2
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread dcrespo
Hi Peter. Sorry for my delay. I wasn't in home the weekend.

 Define what get means for your purposes.  It appears that you mean you
 want to catch the exception, but in the thread which launched the other
 thread in the first place.  If that's true, please show where you would
 expect to catch this exception, given that when you start the thread,
 the main thread continues running and might even finish before the other
 thread finishes.

In my above example, I want to catch in ProgramA the raised exception
in ProgramB. Please, look at my example one more time.

Thanks.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-17 Thread Peter Hansen
dcrespo wrote:
Define what get means for your purposes.  It appears that you mean you
want to catch the exception, but in the thread which launched the other
thread in the first place.  If that's true, please show where you would
expect to catch this exception, given that when you start the thread,
the main thread continues running and might even finish before the other
thread finishes.
 
 In my above example, I want to catch in ProgramA the raised exception
 in ProgramB. 

Better not to call them programs since they're not separate programs, 
just separate modules, one of which starts a thread using methods in the 
other module.

And you haven't really answered the questions I asked.  Please show 
exactly where you expect to catch the exception, given the points I note 
above.  Before, after, or during the .start() call, or somewhere else?

 Please, look at my example one more time.

Done.  It didn't really help looking at it a third time.  It's still 
unclear what you want.

Maybe explaining the use case would help you help us help you. :-)

Your example seems contrived.  In the real code you want to write, why 
do you expect an exception to occur?  Will it be raised deliberately, as 
you show in the example, or is it unexpected (and unhandled by any 
try/except at the top level of the thread's run() method)?  Or do you 
really need to use an exception here?

I'm quite sure the problem you are trying to solve can be solved, but 
you are still describing part of the solution you believe you need, 
rather than explaining why you want to do this (which may let us show 
you other, simpler or cleaner ways to accomplish your goals).

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-16 Thread Klaas
In article [EMAIL PROTECTED],
 [EMAIL PROTECTED] wrote:

 Nevermind.  I found a better solution.  I used shared memory to create
 a keep-alive flag.  I then use the select function with a specified
 timeout, and recheck the keep-alive flag after each timeout.
 
 Thanx for all the input.

How about a threading.Event?

-Mike
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-16 Thread Peter Hansen
[EMAIL PROTECTED] wrote:
 Nevermind.  I found a better solution.  I used shared memory to create
 a keep-alive flag.  I then use the select function with a specified
 timeout, and recheck the keep-alive flag after each timeout.

As Dennis points out, your original attempt was destined to fail because 
you were calling the method from the main thread, not the one you wanted 
to kill.  Threads don't magically execute any methods that are attached 
to the Thread instance just because they're attached.  You have to 
actually call those methods *from* the thread, which means from the 
run() method or from any of the routines it calls (whether they are 
methods on that Thread or not), but it must be done in the context of 
the thread you want to raise exceptions in or it won't work.

More importantly, you've now described your use case (and I hope that of 
the OP as well, since he hasn't replied yet): killing threads.

This is an oft-discussed topic here, and searching the archives will 
probably give you lots more answers, but the short answer is you cannot 
kill a thread in Python (except by exiting the entire process). Instead, 
as you've discovered, you must ask it nicely to exit.  The nearly 
canonical approach to doing that is as follows:

class MyThread(threading.Thread):
 def __init__(self, *args, **kwargs):
 threading.Thread.__init__(self, *args, **kwargs)
 self._keepRunning = True

 def stop(self, timeout=None):
 self._keepRunning = False
 # optional: wait for thread to exit
 self.join(timeout=timeout)

 def run(self):
 while self._keepRunning:
 # do stuff here

Now you can do things like this:

thread = MyThread()
thread.start()
# other stuff...
thread.stop()# block here until the thread exits

I hope that clarifies things a little more...

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-16 Thread Lasse Vågsæther Karlsen
Peter Hansen wrote:
 [EMAIL PROTECTED] wrote:
 
 Nevermind.  I found a better solution.  I used shared memory to create
 a keep-alive flag.  I then use the select function with a specified
 timeout, and recheck the keep-alive flag after each timeout.
 
 
 As Dennis points out, your original attempt was destined to fail because 
 you were calling the method from the main thread, not the one you wanted 
snip

A similar problem exists in .NET but they solved it by creating an 
Abort method that raises an exception in the thread itself, basically 
doing what you wanted to do.

However, this leads to all sorts of problem, particular when that 
exception is raised in a finally block in that thread, which could mean 
that the finally block did not fully execute, leading to resource leaks 
or similar problems.

They pondered a while about constructing non-interruptible blocks of 
code for .NET 2.0 but I'm not entirely sure how that worked out.

In any case, the best way is to use some kind of signal that the thread 
reacts to, either by having it specifically wait for a signallable 
object (like an event) or just by checking a boolean variable or similar 
for a magic value that means now is a good time for you to terminate.

-- 
Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:[EMAIL PROTECTED]
PGP KeyID: 0x2A42A1C2
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-15 Thread dcrespo
Thanks for your answer, but I think that created thread in python
should create a thread either on windows and linux.

Can you give me Python example of how to do what I want to do? Thanks

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-15 Thread Peter Hansen
dcrespo wrote:
 How can I get a raised exception from other thread that is in an
 imported module?

Define what get means for your purposes.  It appears that you mean you 
want to catch the exception, but in the thread which launched the other 
thread in the first place.  If that's true, please show where you would 
expect to catch this exception, given that when you start the thread, 
the main thread continues running and might even finish before the other 
thread finishes.

 thread = programB.MakeThread()
 thread.start()
...
# later code which might have completed by the time the thread finishes
...

Are you looking, for example, for some kind of
thread.waitUntilCompletionAndReRaiseExceptions() method?

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-15 Thread themightydoyle
I also need an answer to this problem.  I'm using windows.  Throwing an
exception in thread B from thread A using a callback function.

The function runs, but the thread never actually catches the exception.
 The try/except block is in the run() method (over-riden from the
Thread class)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-15 Thread Peter Hansen
[EMAIL PROTECTED] wrote:
 I also need an answer to this problem.  

What _is_ the problem?  We're still waiting for a clear description from 
the OP as to what the problem really is.  How would you describe what 
_your_ problem is?

  I'm using windows.  Throwing an
 exception in thread B from thread A using a callback function.
 
 The function runs, but the thread never actually catches the exception.
  The try/except block is in the run() method (over-riden from the
 Thread class)

Rather than force us all to guess what you are doing wrong, maybe it 
would be better if you posted a small amount of code that shows the problem.

Exceptions raised in threads can definitely be caught in the run() 
method if the code is written correctly, so that is not in itself an issue.

-Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-15 Thread themightydoyle
Here's a dumbed down version of what i'm doing:

import time
import threading

class threader(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
pass

def run(self):
try:
while 1:
time.sleep(5)
except SystemExit:
print Got Exit Message in thread

def killMe(self):
raise SystemExit



thread1 = threader()
thread2 = threader()

thread1.start()
thread2.start()

time.sleep(5)

try:
print Killing thread 1
thread1.killMe()
print killing thread 2
thread2.killMe()
except SystemExit:
print Got exceptin in main thread



The exception is not propogated to the threads I spawned, but instead
comes back in the main thread.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-15 Thread themightydoyle
Nevermind.  I found a better solution.  I used shared memory to create
a keep-alive flag.  I then use the select function with a specified
timeout, and recheck the keep-alive flag after each timeout.

Thanx for all the input.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-14 Thread Jeremy Moles
On non-Windows system there are a ton of ways to do it--this is almost a
whole field unto itself. :) (D-BUS, fifos, sockets, shmfs, etc.) In
Windows, I wouldn't have a clue. 

I guess this is a hard question to answer without a bit more
information. :)

On Fri, 2005-10-14 at 14:45 -0700, dcrespo wrote:
 Hi all,
 
 How can I get a raised exception from other thread that is in an
 imported module?
 
 For example:
 
 ---
 programA.py
 ---
 
 import programB
 
 thread = programB.MakeThread()
 thread.start()
 
 ---
 programB.py
 ---
 import threading, time
 
 class SomeException(Exception):
 pass
 
 class MakeThread(threading.Thread):
 def __init__(self):
 threading.Thread.__init__(self)
 
 def run(self):
 i = 0
 while 1:
 print i
 i += 1
 time.sleep(1) #wait a second to continue
 if i10:
 raise SomeException()
 
 
 Thanks
 
 Daniel
 

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get a raised exception from other thread

2005-10-14 Thread Shitiz Bansal


Threads can share the same memory space.
Hence a very neat way to achieve the objective.

 For example:  --- programA.py ---  import programB
Exception=0;initialising a variable
 thread = programB.MakeThread() thread.start()
if (Exception):
 raise SomeException()
 --- programB.py --- import threading, time  class SomeException(Exception): pass  class MakeThread(threading.Thread): def __init__(self): threading.Thread.__init__(self)  def run(self): i = 0 while 1: print i i += 1 time.sleep(1) #wait a second to continue if i10:omit this -raise SomeException()
instead:

if i10:
Exception=1 or whatever 
Sounds cool?

shitizJeremy Moles [EMAIL PROTECTED] wrote:
On non-Windows system there are a ton of ways to do it--this is almost awhole field unto itself. :) (D-BUS, fifos, sockets, shmfs, etc.) InWindows, I wouldn't have a clue. I guess this is a hard question to answer without a bit moreinformation. :)On Fri, 2005-10-14 at 14:45 -0700, dcrespo wrote: Hi all,  How can I get a raised exception from other thread that is in an imported module?  For example:  --- programA.py ---  import programB  thread = programB.MakeThread() thread.start()  --- programB.py --- import threading, time  class SomeException(Exception): pass  class MakeThread(threading.Thread):!
 ; def
 __init__(self): threading.Thread.__init__(self)  def run(self): i = 0 while 1: print i i += 1 time.sleep(1) #wait a second to continue if i10: raise SomeException()   Thanks  Daniel -- http://mail.python.org/mailman/listinfo/python-list
		 Yahoo! Music Unlimited - Access over 1 million songs. Try it free.-- 
http://mail.python.org/mailman/listinfo/python-list