Re: MacOS 10.9.2: threading error using python.org 2.7.6 distribution

2014-04-28 Thread Matthew Pounsett
On Sunday, 27 April 2014 10:33:38 UTC-4, Chris Angelico  wrote:
> In most contexts, "thread unsafe" simply means that you can't use the 
> same facilities simultaneously from two threads (eg a lot of database
> connection libraries are thread unsafe with regard to a single
> connection, as they'll simply write to a pipe or socket and then read
> a response from it). But processes and threads are, on many systems,
> linked. Just the act of spinning off a new thread and then forking can
> potentially cause problems. Those are the exact sorts of issues that
> you'll see when you switch OSes, as it's the underlying thread/process
> model that's significant. (Particularly of note is that Windows is
> *very* different from Unix-based systems, in that subprocess
> management is not done by forking. But not applicable here.)
> 

Thanks, I'll keep all that in mind.  I have to wonder how much of a problem it 
is here though, since I was able to demonstrate a functioning fork inside a new 
thread further up in the discussion.

I have a new development that I find interesting, and I'm wondering if you 
still think it's the same problem.

I have taken that threading object and turned it into a normal function 
definition.  It's still forking the external tool, but it's doing so in the 
main thread, and it is finished execution before any other threads are created. 
  And I'm still getting the same error.

Turns out it's not coming from the threading module, but from the subprocess 
module instead.  Specifically, like 709 of 
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py
which is this:

try:
self._execute_child(args, executable, preexec_fn, close_fds,
cwd, env, universal_newlines,
startupinfo, creationflags, shell, to_close,
p2cread, p2cwrite,
c2pread, c2pwrite,
errread, errwrite)
except Exception:

I get the "Warning: No stack to get attribute from" twice when that 
self._execute_child() call is made.  I've tried stepping into it to narrow it 
down further, but I'm getting weird behaviour from the debugger that I've never 
seen before once I do that.  It's making it hard to track down exactly where 
the error is occurring.

Interestingly, it's not actually raising an exception there.  The except block 
is not being run.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: MacOS 10.9.2: threading error using python.org 2.7.6 distribution

2014-04-27 Thread Matthew Pounsett
On Friday, 25 April 2014 14:58:56 UTC-4, Ned Deily  wrote:
> FWIW, the Python 2 version of subprocess is known to be thread-unsafe.  
> There is a Py2 backport available on PyPI of the improved Python 3 
> subprocess module:

Since that't the only thread that calls anything in subprocess, and I'm only 
running one instance of the thread, I'm not too concerned about how threadsafe 
subprocess is.  In this case it shouldn't matter.  Thanks for the info though.. 
that might be handy at some future point.

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


Re: MacOS 10.9.2: threading error using python.org 2.7.6 distribution

2014-04-27 Thread Matthew Pounsett
On Friday, 25 April 2014 10:05:03 UTC-4, Chris Angelico  wrote:
> First culprit I'd look at is the mixing of subprocess and threading.
> It's entirely possible that something goes messy when you fork from a
> thread.

I liked the theory, but I've run some tests and can't reproduce the error that 
way.  I'm using all the elements in my test code that the real code runs, and I 
can't get the same error.  Even when I deliberately break things I'm getting a 
proper exception with stack trace.

class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)

def run(self):
logger = logging.getLogger("thread")
p1 = subprocess.Popen( shlex.split( 'echo "MyThread calls echo."'),
stdout=subprocess.PIPE, universal_newlines=True)
logger.debug( p1.communicate()[0].decode('utf-8', 'ignore' ))
logger.debug( "MyThread runs and exits." )

def main():
console = logging.StreamHandler()
console.setFormatter(
logging.Formatter('%(asctime)s [%(name)-12s] %(message)s', '%T'))
logger = logging.getLogger()
logger.addHandler(console)
logger.setLevel(logging.NOTSET)

try:
t = MyThread()
#t = RTF2TXT("../data/SRD/rtf/", Queue.Queue())
t.start()
except Exception as e:
logger.error( "Failed with {!r}".format(e))

if __name__ == '__main__':
main()


> Separately: You're attempting a very messy charset decode there. You
> attempt to decode as UTF-8, errors ignored, and if that fails, you log
> an error... and continue on with the original bytes. You're risking
> shooting yourself in the foot there; I would recommend you have an
> explicit fall-back (maybe re-decode as Latin-1??), so the next code is
> guaranteed to be working with Unicode. Currently, it might get a
> unicode or a str.

Yeah, that was a logic error on my part that I hadn't got around to noticing, 
since I'd been concentrating on the stuff that was actively breaking.  That 
should have been in an else: block on the end of the try.

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


MacOS 10.9.2: threading error using python.org 2.7.6 distribution

2014-04-25 Thread Matthew Pounsett

I've run into a threading error in some code when I run it on MacOS that works 
flawlessly on a *BSD system running the same version of python.  I'm running 
the python 2.7.6 for MacOS distribution from python.org's downloads page.

I have tried to reproduce the error with a simple example, but so far haven't 
been able to find the element or my code that triggers the error.  I'm hoping 
someone can suggest some things to try and/or look at.  Googling for "pyton" 
and the error returns exactly two pages, neither of which are any help.

When I run it through the debugger, I'm getting the following from inside 
threading.start().  python fails to provide a stack trace when I step into 
_start_new_thread(), which is a pointer to thread.start_new_thread().  It looks 
like threading.__bootstrap_inner() may be throwing an exception which 
thread.start_new_thread() is unable to handle, and for some reason the stack is 
missing so I get no stack trace explaining the error.

It looks like thread.start_new_thread() is in the binary object, so I can't 
actually step into it and find where the error is occurring.

> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py(745)start()
-> _start_new_thread(self.__bootstrap, ())
(Pdb) s
> /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py(750)start()
-> self.__started.wait()
(Pdb) Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from
Warning: No stack to get attribute from

My test code (which works) follows the exact same structure as the failing 
code, making the same calls to the threading module's objects' methods:


import threading

class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)

def run(self):
print "MyThread runs and exits."

def main():
try:
t = MyThread()
t.start()
except Exception as e:
print "Failed with {!r}".format(e)

if __name__ == '__main__':
main()


The actual thread object that's failing looks like this:

class RTF2TXT(threading.Thread):
"""
Takes a directory path and a Queue as arguments.  The directory should be
a collection of RTF files, which will be read one-by-one, converted to
text, and each output line will be appended in order to the Queue.
"""
def __init__(self, path, queue):
threading.Thread.__init__(self)
self.path = path
self.queue = queue

def run(self):
logger = logging.getLogger('RTF2TXT')
if not os.path.isdir(self.path):
raise TypeError, "supplied path must be a directory"
for f in sorted(os.listdir(self.path)):
ff = os.path.join(self.path, f)
args = [ UNRTF_BIN, '-P', '.', '-t', 'unrtf.text',  ff ]
logger.debug("Processing file {} with args {!r}".format(f, args))
p1 = subprocess.Popen( args, stdout=subprocess.PIPE,
universal_newlines=True)
output = p1.communicate()[0]
try:
output = output.decode('utf-8', 'ignore')
except Exception as err:
logger.error("Failed to decode output: {}".format(err))
logger.error("Output was: {!r}".format(output))

for line in output.split("\n"):
line = line.strip()
self.queue.put(line)
self.queue.put("")

Note: I only run one instance of this thread.  The Queue object is used to pass 
work off to another thread for later processing.

If I insert that object into the test code and run it instead of MyThread(), I 
get the error.  I can't see anything in there that should cause problems for 
the threading module though... especially since this runs fine on another 
system with the same version of python.

Any thoughts on what's going on here?



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


Re: Two questions about logging

2012-01-14 Thread Matthew Pounsett
On Jan 12, 8:03 pm, K Richard Pixley  wrote:
> Here's the confusion.  Each log named __name__ is under the root logger.
>   If you want them all, then catch them all with the root logger.

Thanks!  I knew I was missing something obvious.  Between you and Jean-
Michael Pichavant I've figured out what I need to do here.


On Jan 11, 9:34 pm, Roy Smith  wrote:
> What I would do is log to syslog (logging.handlers.SysLogHandler) and
> let syslog worry about rotating log files.  Why reinvent the wheel?

I've also worked out what I need to reset file handles, although it
took a lot of reading in the various logging.Handler subclasses.  What
I needed isn't explicitly documented anywhere, but it turns out that
calling the close() method on a FileHandler instance does what I
need.  There's no method to re-open the handler, but the next call to
emit() will automatically re-open the file if it isn't already open.

The upshot is that this does the expected thing if you rename its log
file and then send the running script a HUP signal.

#!/usr/bin/env python

import logging
import signal
import time

logger = logging.getLogger()
lh = logging.FileHandler('./foo.log')
lh.setFormatter(logging.Formatter('%(asctime)s %(name)s: %(message)s',
'%T'))
logger.addHandler(lh)

def sighup(signum, frame):
lh.close()
logger.error("handled {0}: {1}".format(signum, frame))

def main():
signal.signal(signal.SIGHUP, sighup)
while 1:
time.sleep(1)
logger.error('a message')

if __name__ == '__main__':
main()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Two questions about logging

2012-01-11 Thread Matthew Pounsett
On Jan 11, 9:34 pm, Roy Smith  wrote:
> What I would do is log to syslog (logging.handlers.SysLogHandler) and
> let syslog worry about rotating log files.  Why reinvent the wheel?

Syslog is fine for an application run by an administrator, but isn't
an option for a user.
-- 
http://mail.python.org/mailman/listinfo/python-list


Two questions about logging

2012-01-11 Thread Matthew Pounsett
I'm trying to figure out a couple of things with the logging module,
and I'm hoping someone can provide some pointers.  I've read through
the module docs on python.org, the basic and advanced tutorials, and
the cookbook post, but a couple of things still elude me.

First, I'd like to be able to permit users to do more typical log
rotation, based on their OS's log rotation handler, rather than
rotating logs from inside an application.  This is usually handled by
signalling an application with a HUP, whereupon it closes and then re-
opens all of its logs, getting new file handles (and new inodes).  I
don't see anything in the Handler methods (or anywhere else) that
would let me tell a logger object to refresh the file handles on a log
file.  Is there some standard way to deal with this?

Second, I'm trying to get a handle on how libraries are meant to
integrate with the applications that use them.  The naming advice in
the advanced tutorial is to use __name__ to name loggers, and to allow
log messages to pass back up to the using application's logger for
processing, but these two pieces of advice seem contradictory.. since
log messages only pass back up to the root if the loggers are named
hierarchically.

> cat foo.py
#!/usr/bin/env python

import logging
import bar

logger = logging.getLogger(__name__)
fh = logging.FileHandler('foo.log')
ch = logging.StreamHandler()
logger.addHandler(fh)
logger.addHandler(ch)
logger.warning('from the first')
bar.funct()

> cat bar.py
#!/usr/bin/env python

import logging

def funct():
logger = logging.getLogger(__name__)
logger.warning('from the second')

> ./foo.py
from the first
No handlers could be found for logger "bar"

So, given this state of affairs, how is a library author to use
loggers, given that he or she can't know how authors who use the
library will name their logger objects?  In the above example, what
would the author of bar.py do to hook up bar's logger with foo's,
without knowing in advance what foo's logger will be named?


Thanks very much for any suggestions, or pointers to documentation
that I've missed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: cause __init__ to return a different class?

2011-09-18 Thread Matthew Pounsett
On Sep 15, 1:54 am, Ryan Kelly  wrote:
> To be friendlier to others reading your code, I would consider using a
> classmethod to create an alternative constructor:

I finally got back to looking at this today.  As it turns out, un-
overriding __new__ in the child class is more complicated than I first
expected, and isn't worth the extra effort.  So, I ended up using a
constructor class method as you suggested.

Thanks again!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: cause __init__ to return a different class?

2011-09-15 Thread Matthew Pounsett
On Sep 15, 1:54 am, Ryan Kelly  wrote:
> The above will do exactly what you want, but it's generally bad style
> unless you have a very specific use-case.  Is there a particular reason
> you need to "magically" return a subclass, rather than making this
> explicit in the code?
>
> To be friendlier to others reading your code, I would consider using a
> classmethod to create an alternative constructor:

Yeah, I was considering doing this as well, particularly if I couldn't
have made the other work.   The reason I'm not too concerned about
anyone misinterpreting what's going on is that in this case the base
class is actually named for being a constructor, and any rare case
where I want a specific subclass the subclass will be created
directly.

Thanks very much for your help!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: cause __init__ to return a different class?

2011-09-15 Thread Matthew Pounsett
On Sep 15, 1:35 am, Chris Rebert  wrote:
> Override __new__() instead:
> http://docs.python.org/reference/datamodel.html#object.__new__

Aha.. thanks!  The reference book I'm working from neglects to mention
__new__, so I'd assumed __init__ was the constructor.  It hadn't
occurred to me that python would separate the functions (I still don't
see exactly why it would be useful to do that, but perhaps insight
will come with time).

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


cause __init__ to return a different class?

2011-09-14 Thread Matthew Pounsett
I'm wondering if there's a way in python to cause __init__ to return a class 
other than the one initially specified.  My use case is that I'd like to have a 
superclass that's capable of generating an instance of a random subclass.  

I've tried both returning the subclass (as I would when overloading an 
operator) but I get the complaint that __init__ wants to return None instead of 
a type.

The other thing I tried was overwriting 'self' while inside __init__ but that 
doesn't seem to work either.

class Parent(object):
def __init__(self, foo):
if foo == True:
self = Child(foo)

class Child(Parent):
def __init__(self, foo):
pass

Is there a way to do this?  
-- 
http://mail.python.org/mailman/listinfo/python-list