Re: If Scheme is so good why MIT drops it?

2009-07-22 Thread Ron Garret
In article urr9m.6558$ze1.5...@news-server.bigpond.net.au,
 Neil Hodgson nyamatongwe+thun...@gmail.com wrote:

 milanj:
 
  and all of them use native threads (python still use green threads ?)
 
Python uses native threads.

But then it adds the global interpreter lock, which completely 
undermines the utility of native threads.  So yes, it uses native 
threads, but it does not actually realize the benefits of that use.

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


Yet another unicode WTF

2009-06-04 Thread Ron Garret
Python 2.6.2 on OS X 10.5.7:

[...@mickey:~]$ echo $LANG
en_US.UTF-8
[...@mickey:~]$ cat frob.py 
#!/usr/bin/env python
print u'\u03BB'

[...@mickey:~]$ ./frob.py 
ª
[...@mickey:~]$ ./frob.py  foo
Traceback (most recent call last):
  File ./frob.py, line 2, in module
print u'\u03BB'
UnicodeEncodeError: 'ascii' codec can't encode character u'\u03bb' in 
position 0: ordinal not in range(128)


(That's supposed to be a small greek lambda, but I'm using a 
brain-damaged news reader that won't let me set the character encoding.  
It shows up correctly in my terminal.)

According to what I thought I knew about unix (and I had fancied myself 
a bit of an expert until just now) this is impossible.  Python is 
obviously picking up a different default encoding when its output is 
being piped to a file, but I always thought one of the fundamental 
invariants of unix processes was that there's no way for a process to 
know what's on the other end of its stdout.

Clues appreciated.  Thanks.

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


Re: Yet another unicode WTF

2009-06-04 Thread Ron Garret
In article h09ten$5q...@lust.ihug.co.nz,
 Lawrence D'Oliveiro l...@geek-central.gen.new_zealand wrote:

 In message rnospamon-e7e08b.18181804062...@news.gha.chartermi.net, Ron 
 Garret wrote:
 
  Python 2.6.2 on OS X 10.5.7:
 
 Same result, Python 2.6.1-3 on Debian Unstable. My $LANG is en_NZ.UTF-8.
 
  ... I always thought one of the fundamental
  invariants of unix processes was that there's no way for a process to
  know what's on the other end of its stdout.
 
 Well, there have long been functions like isatty(3). That's probably what's 
 involved here.

Oh.  Right.  Duh.

I am having an unbelievably bad day involving lawyers.  (And not 
language lawyers, real ones.)

Found the answer here:

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415968

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


distutils extension configuration problem

2009-05-26 Thread Ron Garret
I'm trying to build PyObjC on an Intel Mac running OS X 10.5.7.  The 
build is breaking because distutils seems to want to build extension 
modules as universal binaries, but some of the libraries it depends on 
are built for intel-only, i.e.:

[...@mickey:~/Desktop/pyobjc-framework-ScreenSaver-2.2b2]$ python2.6 
setup.py build
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils
/dist.py:266: UserWarning: Unknown distribution option: 'options'
  warnings.warn(msg)
running build
running build_py
running build_ext
building 'ScreenSaver._inlines' extension
gcc -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -g 
-bundle -undefined dynamic_lookup 
build/temp.macosx-10.3-i386-2.6/Modules/_ScreenSaver_inlines.o -o 
build/lib.macosx-10.3-i386-2.6/ScreenSaver/_inlines.so -framework 
ScreenSaver
ld: in /Developer/SDKs/MacOSX10.4u.sdk/usr/local/lib/libTIFF.dylib, file 
is not of required architecture for architecture ppc
collect2: ld returned 1 exit status
lipo: can't open input file: 
/var/folders/nT/nTiypn-v2RatkU+BYncrKU+++TI/-Tmp-//ccMFYRkt.out (No such 
file or directory)
error: command 'gcc' failed with exit status 1

[...@mickey:~/Desktop/pyobjc-framework-ScreenSaver-2.2b2]$ file 
build/temp.macosx-10.3-i386-2.6/Modules/_ScreenSaver_inlines.o 
build/temp.macosx-10.3-i386-2.6/Modules/_ScreenSaver_inlines.o: Mach-O 
universal binary with 2 architectures
build/temp.macosx-10.3-i386-2.6/Modules/_ScreenSaver_inlines.o (for 
architecture ppc): Mach-O object ppc
build/temp.macosx-10.3-i386-2.6/Modules/_ScreenSaver_inlines.o (for 
architecture i386):   Mach-O object i386

[...@mickey:~/Desktop/pyobjc-framework-ScreenSaver-2.2b2]$ file 
/usr/local/lib/libtiff.dylib 
/usr/local/lib/libtiff.dylib: Mach-O dynamically linked shared library 
i386

How do I get distutils to stop trying to build extensions as universal 
binaries?

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: To unicode or not to unicode

2009-02-20 Thread Ron Garret
In article mailman.373.1235153296.11746.python-l...@python.org,
 MRAB goo...@mrabarnett.plus.com wrote:

 Thorsten Kampe wrote:
  * Ron Garret (Thu, 19 Feb 2009 18:57:13 -0800)
  I'm writing a little wiki that I call µWiki.  That's a lowercase Greek 
  mu at the beginning (it's pronounced micro-wiki). 
  
  No, it's not. I suggest you start your Unicode adventure by configuring 
  your newsreader.
  
 It looked like mu to me, but you're correct: it's MICRO SIGN, not
 GREEK SMALL LETTER MU.

Heh, I didn't know that those two things were distinct.  Learn something 
new every day.

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


What encoding does u'...' syntax use?

2009-02-20 Thread Ron Garret
I would have thought that the answer would be: the default encoding 
(duh!)  But empirically this appears not to be the case:

 unicode('\xb5')
Traceback (most recent call last):
  File stdin, line 1, in module
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb5 in position 0: 
ordinal not in range(128)
 u'\xb5'
u'\xb5'
 print u'\xb5'
µ

(That last character shows up as a micron sign despite the fact that my 
default encoding is ascii, so it seems to me that that unicode string 
must somehow have picked up a latin-1 encoding.)

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


Re: To unicode or not to unicode

2009-02-20 Thread Ron Garret
In article 499f0cf0.8070...@v.loewis.de,
 Martin v. Löwis mar...@v.loewis.de wrote:

 MRAB wrote:
  Thorsten Kampe wrote:
  * Ron Garret (Thu, 19 Feb 2009 18:57:13 -0800)
  I'm writing a little wiki that I call µWiki.  That's a lowercase
  Greek mu at the beginning (it's pronounced micro-wiki). 
 
  No, it's not. I suggest you start your Unicode adventure by
  configuring your newsreader.
 
  It looked like mu to me, but you're correct: it's MICRO SIGN, not
  GREEK SMALL LETTER MU.
 
 I don't think that was the complaint. Instead, the complaint was
 that the OP's original message did not have a Content-type header,

I'm the OP.  I'm using MT-Newswatcher 3.5.1.  I thought I had it 
configured properly, but I guess I didn't.  Under 
Preferences-Languages-Send Messages with Encoding I had selected 
latin-1.  I didn't know I also needed to have MIME turned on for that to 
work.  I've turned it on now.  Is this better?

This should be a micro sign: µ

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


Re: What encoding does u'...' syntax use?

2009-02-20 Thread Ron Garret
In article 499f18bd$0$31879$9b4e6...@newsspool3.arcor-online.net,
 Stefan Behnel stefan...@behnel.de wrote:

 Ron Garret wrote:
  I would have thought that the answer would be: the default encoding 
  (duh!)  But empirically this appears not to be the case:
  
  unicode('\xb5')
  Traceback (most recent call last):
File stdin, line 1, in module
  UnicodeDecodeError: 'ascii' codec can't decode byte 0xb5 in position 0: 
  ordinal not in range(128)
  u'\xb5'
  u'\xb5'
  print u'\xb5'
  µ
  
  (That last character shows up as a micron sign despite the fact that my 
  default encoding is ascii, so it seems to me that that unicode string 
  must somehow have picked up a latin-1 encoding.)
 
 You are mixing up console output and internal data representation. What you
 see in the last line is what the Python interpreter makes of your unicode
 string when passing it into stdout, which in your case seems to use a
 latin-1 encoding (check your environment settings for that).
 
 BTW, Unicode is not an encoding. Wikipedia will tell you more.

Yes, I know that.  But every concrete representation of a unicode string 
has to have an encoding associated with it, including unicode strings 
produced by the Python parser when it parses the ascii string u'\xb5'

My question is: what is that encoding?  It can't be ascii.  So what is 
it?

Put this another way: I would have thought that when the Python parser 
parses u'\xb5' it would produce the same result as calling 
unicode('\xb5'), but it doesn't.  Instead it seems to produce the same 
result as calling unicode('\xb5', 'latin-1').  But my default encoding 
is not latin-1, it's ascii.  So where is the Python parser getting its 
encoding from?  Why does parsing u'\xb5' not produce the same error as 
calling unicode('\xb5')?

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


Re: What encoding does u'...' syntax use?

2009-02-20 Thread Ron Garret
In article 499f3a8f.9010...@v.loewis.de,
 Martin v. Löwis mar...@v.loewis.de wrote:

  u'\xb5'
  u'\xb5'
  print u'\xb5'
  ?
  
  Unicode literals are *in the source file*, which can only have one
  encoding (for a given source file).
  
  (That last character shows up as a micron sign despite the fact that
  my default encoding is ascii, so it seems to me that that unicode
  string must somehow have picked up a latin-1 encoding.)
  
  I think latin-1 was the default without a coding cookie line.  (May be
  uft-8 in 3.0).
 
 It is, but that's irrelevant for the example. In the source
 
   u'\xb5'
 
 all characters are ASCII (i.e. all of letter u, single
 quote, backslash, letter x, letter b, digit 5).
 As a consequence, this source text has the same meaning in all
 supported source encodings (as source encodings must be ASCII
 supersets).
 
 The Unicode literal shown here does not get its interpretation
 from Latin-1. Instead, it directly gets its interpretation from
 the Unicode coded character set. The string is a short-hand
 for
 
  u'\u00b5'
 
 and this denotes character U+00B5 (just as u'\u20ac denotes
 U+20AC; the same holds for any other u'\u').
 
 HTH,
 Martin

Ah, that makes sense.  Thanks!

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


Re: What encoding does u'...' syntax use?

2009-02-20 Thread Ron Garret
In article 499f397c.7030...@v.loewis.de,
 Martin v. Löwis mar...@v.loewis.de wrote:

  Yes, I know that.  But every concrete representation of a unicode string 
  has to have an encoding associated with it, including unicode strings 
  produced by the Python parser when it parses the ascii string u'\xb5'
  
  My question is: what is that encoding?
 
 The internal representation is either UTF-16, or UTF-32; which one is
 a compile-time choice (i.e. when the Python interpreter is built).
 
  Put this another way: I would have thought that when the Python parser 
  parses u'\xb5' it would produce the same result as calling 
  unicode('\xb5'), but it doesn't.
 
 Right. In the former case, \xb5 denotes a Unicode character, namely
 U+00B5, MICRO SIGN. It is the same as u\u00b5, and still the same
 as u\N{MICRO SIGN}. By the same, I mean the very same.
 
 OTOH, unicode('\xb5') is something entirely different. '\xb5' is a
 byte string with length 1, with a single byte with the numeric
 value 0xb5, or 181. It does not, per se, denote any specific character.
 It only gets a character meaning when you try to decode it to unicode,
 which you do with unicode('\xb5'). This is short for
 
   unicode('\xb5', sys.getdefaultencoding())
 
 and sys.getdefaultencoding() is (or should be) ascii. Now, in
 ASCII, byte 0xb5 does not have a meaning (i.e. it does not denote
 a character at all), hence you get a UnicodeError.
 
  Instead it seems to produce the same 
  result as calling unicode('\xb5', 'latin-1').
 
 Sure. However, this is only by coincidence, because latin-1 has the same
 code points as Unicode (for 0..255).
 
  But my default encoding 
  is not latin-1, it's ascii.  So where is the Python parser getting its 
  encoding from?  Why does parsing u'\xb5' not produce the same error as 
  calling unicode('\xb5')?
 
 Because \xb5 *directly* refers to character U+00b5, with no
 byte-oriented encoding in-between.
 
 Regards,
 Martin

OK, I think I get it now.  Thanks!

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


Regular expression bug?

2009-02-19 Thread Ron Garret
I'm trying to split a CamelCase string into its constituent components.  
This kind of works:

 re.split('[a-z][A-Z]', 'fooBarBaz')
['fo', 'a', 'az']

but it consumes the boundary characters.  To fix this I tried using 
lookahead and lookbehind patterns instead, but it doesn't work:

 re.split('((?=[a-z])(?=[A-Z]))', 'fooBarBaz')
['fooBarBaz']

However, it does seem to work with findall:

 re.findall('(?=[a-z])(?=[A-Z])', 'fooBarBaz')
['', '']

So the regular expression seems to be doing the Right Thing.  Is this a 
bug in re.split, or am I missing something?

(BTW, I tried looking at the source code for the re module, but I could 
not find the relevant code.  re.split calls sre_compile.compile().split, 
but the string 'split' does not appear in sre_compile.py.  So where does 
this method come from?)

I'm using Python2.5.

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Regular expression bug?

2009-02-19 Thread Ron Garret
In article mailman.281.1235073821.11746.python-l...@python.org,
 MRAB goo...@mrabarnett.plus.com wrote:

 Ron Garret wrote:
  I'm trying to split a CamelCase string into its constituent components.  
  This kind of works:
  
  re.split('[a-z][A-Z]', 'fooBarBaz')
  ['fo', 'a', 'az']
  
  but it consumes the boundary characters.  To fix this I tried using 
  lookahead and lookbehind patterns instead, but it doesn't work:
  
  re.split('((?=[a-z])(?=[A-Z]))', 'fooBarBaz')
  ['fooBarBaz']
  
  However, it does seem to work with findall:
  
  re.findall('(?=[a-z])(?=[A-Z])', 'fooBarBaz')
  ['', '']
  
  So the regular expression seems to be doing the Right Thing.  Is this a 
  bug in re.split, or am I missing something?
  
  (BTW, I tried looking at the source code for the re module, but I could 
  not find the relevant code.  re.split calls sre_compile.compile().split, 
  but the string 'split' does not appear in sre_compile.py.  So where does 
  this method come from?)
  
  I'm using Python2.5.
  
 I, amongst others, think it's a bug (or 'misfeature'); Guido thinks it
 might be intentional, but changing it could break some existing code.

That seems unlikely.  It would only break where people had code invoking 
re.split on empty matches, which at the moment is essentially a no-op.  
It's hard to imagine there's a lot of code like that around.  What would 
be the point?

 You could do this instead:
 
   re.sub('(?=[a-z])(?=[A-Z])', '@', 'fooBarBaz').split('@')
 ['foo', 'Bar', 'Baz']

Blech!  ;-)  But thanks for the suggestion.

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


Re: Regular expression bug?

2009-02-19 Thread Ron Garret
In article gnkdal$bcq$0...@news.t-online.com,
 Peter Otten __pete...@web.de wrote:

 Ron Garret wrote:
 
  I'm trying to split a CamelCase string into its constituent components.
 
 How about
 
  re.compile([A-Za-z][a-z]*).findall(fooBarBaz)
 ['foo', 'Bar', 'Baz']

That's very clever.  Thanks!

  (BTW, I tried looking at the source code for the re module, but I could
  not find the relevant code.  re.split calls sre_compile.compile().split,
  but the string 'split' does not appear in sre_compile.py.  So where does
  this method come from?)
 
 It's coded in C. The source is Modules/sremodule.c.

Ah.  Thanks!

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


Re: Regular expression bug?

2009-02-19 Thread Ron Garret
In article mailman.277.1235073073.11746.python-l...@python.org,
 andrew cooke and...@acooke.org wrote:

 i wonder what fraction of people posting with bug? in their titles here
 actually find bugs?

IMHO it ought to be an invariant that len(r.split(s)) should always be 
one more than len(r.findall(s)).

 anyway, how about:
 
 re.findall('[A-Z]?[a-z]*', 'fooBarBaz')
 
 or
 
 re.findall('([A-Z][a-z]*|[a-z]+)', 'fooBarBaz')

That will do it.  Thanks!

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


Re: Regular expression bug?

2009-02-19 Thread Ron Garret
In article mailman.273.1235071607.11746.python-l...@python.org,
 Albert Hopkins mar...@letterboxes.org wrote:

 On Thu, 2009-02-19 at 10:55 -0800, Ron Garret wrote:
  I'm trying to split a CamelCase string into its constituent components.  
  This kind of works:
  
   re.split('[a-z][A-Z]', 'fooBarBaz')
  ['fo', 'a', 'az']
  
  but it consumes the boundary characters.  To fix this I tried using 
  lookahead and lookbehind patterns instead, but it doesn't work:
 
 That's how re.split works, same as str.split...

I think one could make the argument that 'foo'.split('') ought to return 
['f','o','o']

 
   re.split('((?=[a-z])(?=[A-Z]))', 'fooBarBaz')
  ['fooBarBaz']
  
  However, it does seem to work with findall:
  
   re.findall('(?=[a-z])(?=[A-Z])', 'fooBarBaz')
  ['', '']
 
 
 Wow!
 
 To tell you the truth, I can't even read that...

It's a regexp.  Of course you can't read it.  ;-)

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


To unicode or not to unicode

2009-02-19 Thread Ron Garret
I'm writing a little wiki that I call µWiki.  That's a lowercase Greek 
mu at the beginning (it's pronounced micro-wiki).  It's working, except 
that I can't actually enter the name of the wiki into the wiki itself 
because the default unicode encoding on my Python installation is 
ascii.  So I'm trying to decide on a course of action.  There seem to 
be three possibilities:

1.  Change the code to properly support unicode.  Preliminary 
investigations indicate that this is going to be a colossal pain in the 
ass.

2.  Change the default encoding on my Python installation to be latin-1 
or UTF8.  The disadvantage to this is that no one else will be able to 
run my code without making the same change to their installation, since 
you can't change default encodings once Python has started.

3.  Punt and spell it 'uwiki' instead.

I'm feeling indecisive so I thought I'd ask other people's opinion.  
What should I do?

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


Re: WebError documentation?

2009-02-07 Thread Ron Garret
In article mailman.9037.1233981452.3487.python-l...@python.org,
 Chris Rebert c...@rebertia.com wrote:

 On Thu, Feb 5, 2009 at 12:52 PM, Ron Garret rnospa...@flownet.com wrote:
  Is there any?  Where is it?  Extensive Googling has proven fruitless.
 
 It's not a standard Python exception. A third-party library you're
 using must be raising it. Check the exception traceback.

I see I did not make myself clear.  I meant the Python software package 
called weberror, not a generic web error.

http://pypi.python.org/pypi/WebError


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


Re: WebError documentation?

2009-02-07 Thread Ron Garret
In article 498de947$0$24412$426a7...@news.free.fr,
 Bruno Desthuilliers bdesth.quelquech...@free.quelquepart.fr wrote:

 Ron Garret a écrit :
  In article mailman.9037.1233981452.3487.python-l...@python.org,
   Chris Rebert c...@rebertia.com wrote:
  
  On Thu, Feb 5, 2009 at 12:52 PM, Ron Garret rnospa...@flownet.com wrote:
  Is there any?  Where is it?  Extensive Googling has proven fruitless.
  It's not a standard Python exception. A third-party library you're
  using must be raising it. Check the exception traceback.
  
  I see I did not make myself clear.
 
 Now *that* is an understatement...
 
I meant the Python software package
  called weberror, not a generic web error.
  
  http://pypi.python.org/pypi/WebError
 
 Google is your friend:
 http://bel-epa.com/docs/thirdparty/weberror/

Thanks!

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


WebError documentation?

2009-02-06 Thread Ron Garret
Is there any?  Where is it?  Extensive Googling has proven fruitless.

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Extreme Yaro weirdness

2009-02-02 Thread Ron Garret
I'm running the following WSGI app under Yaro:

def error(req):
  try:
req.non_existent_key
  except:
try:
  return cgitb.html(sys.exc_info())
except:
  return 'foo'

The result of running this is 'foo'.  In other words, the reference to 
the non-existent key generates an exception as expected, but then the 
generation of the traceback generates ANOTHER exception, which I would 
not have expected.  If I add another TRY/EXCEPT block to capture this 
exception, the result is attached at the bottom of this message.

It gets better.

I get the same result whether I run under Apache/mod_wsgi or standalone 
using wsgi_ref.  But if I add the following code to try to capture a 
Yaro request object so I can noodle around with it:


def error(req):
  global req1
  req1=req
  try: ...


it makes the problem go away!  But it ONLY makes the problem go away 
when running under wsgi_ref, not under Apache!

The problem seems to be specific to Yaro.  If I make an instance of an 
object and try to dereference a non-existent attribute, the initial 
traceback gets generated with no problem.  Also, the Yaro code for 
Request.__getattr__ ultimately calls req.__dict__[attr].  If I make this 
call directly, the problem also goes away.

I am quite baffled by this.  Any suggestions on how to debug this would 
be much appreciated.

Thanks,
rg





type 'exceptions.KeyError'
Python 2.5: /usr/local/bin/python
Mon Feb  2 00:54:33 2009

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 /www/sites/mcia.cc/files/wsgi/test.wsgi in error(req=yaro.Request 
object at 0x2b94a690)
  212   except:
  213 try:
  214   return cgitb.text(sys.exc_info())
  215 except:
  216   try:
global cgitb = module 'cgitb' from '/usr/lib/python2.5/cgitb.pyc'
cgitb.text = function text at 0x2b0adc80
global sys = module 'sys' (built-in)
sys.exc_info = built-in function exc_info

 /www/sites/cgitb.py in text((etype=type 'exceptions.KeyError', 
evalue=KeyError('non_existent_key',), etb=traceback object at 
0x2b960368), context=5)
  215 try: return linecache.getline(file, lnum[0])
  216 finally: lnum[0] += 1
  217 vars = scanvars(reader, frame, locals)
  218 
  219 rows = [' %s %s' % (file, call)]
builtinvars = built-in function vars
global scanvars = function scanvars at 0x2b0adb90
reader = function reader at 0x2bbbea28
frame = frame object at 0xba49e0
locals = {'req': yaro.Request object at 0x2b94a690}

 /www/sites/cgitb.py in scanvars(reader=function reader at 
0x2bbbea28, frame=frame object at 0xba49e0, locals={'req': 
yaro.Request object at 0x2b94a690})
   82 if lasttoken == '.':
   83 if parent is not __UNDEF__:
   84 value = getattr(parent, token, __UNDEF__)
   85 vars.append((prefix + token, prefix, value))
   86 else:
value = yaro.Request object at 0x2b94a690
builtingetattr = built-in function getattr
parent = yaro.Request object at 0x2b94a690
token = 'non_existent_key'
__UNDEF__ undefined

 /www/sites/mcia.cc/files/wsgi/yaro.py in __getattr__(self=yaro.Request 
object at 0x2b94a690, attr='non_existent_key')
  215 elif attr == 'cookie' and not 'cookie' in self.__dict__:
  216 self._load_cookie()
  217 return self.__dict__[attr]
  218 
  219 def _parse_query(self):
self = yaro.Request object at 0x2b94a690
self.__dict__ = {'_start_response': built-in method start_response of 
mod_wsgi.Adapter object at 0x2ab218a0, 'content_length': '', 
'content_type': '', 'environ': {'DOCUMENT_ROOT': 
'/www/sites/mcia.cc/html', 'GATEWAY_INTERFACE': 'CGI/1.1', 
'HTTP_ACCEPT': 
'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plai
n;q=0.8,image/png,*/*;q=0.5', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 
'HTTP_ACCEPT_LANGUAGE': 'en-us', 'HTTP_CACHE_CONTROL': 'max-age=0', 
'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': 'sid=55UGS64T', 
'HTTP_HOST': 'mcia.cc', 'HTTP_REFERER': 'http://mcia.cc/wtest/menu', 
...}, 'exc_info': None, 'extra_props': None, 'method': 'GET', 'query': 
{}, 'res': yaro.Response object at 0x2b94a710, 
'start_response_called': False, ...}
attr = 'non_existent_key'
type 'exceptions.KeyError': 'non_existent_key'

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File /www/sites/mcia.cc/files/wsgi/test.wsgi, line 214, in error
return cgitb.text(sys.exc_info())
  File cgitb.py, line 217, in text
vars = scanvars(reader, frame, locals)
  File cgitb.py, line 84, in scanvars
value = getattr(parent, token, __UNDEF__)
  File /www/sites/mcia.cc/files/wsgi/yaro.py, line 217, in __getattr__
return self.__dict__[attr]
KeyError: 'non_existent_key'
--
http://mail.python.org/mailman/listinfo/python-list


Re: Extreme Yaro weirdness

2009-02-02 Thread Ron Garret
In article mailman.8612.1233589195.3487.python-l...@python.org,
 Gabriel Genellina gagsl-...@yahoo.com.ar wrote:

 En Mon, 02 Feb 2009 06:59:16 -0200, Ron Garret rnospa...@flownet.com  
 escribió:
 
  I'm running the following WSGI app under Yaro:
 
  def error(req):
try:
  req.non_existent_key
except:
  try:
return cgitb.html(sys.exc_info())
  except:
return 'foo'
 
  The result of running this is 'foo'.  In other words, the reference to
  the non-existent key generates an exception as expected, but then the
  generation of the traceback generates ANOTHER exception, which I would
  not have expected.  If I add another TRY/EXCEPT block to capture this
  exception, the result is attached at the bottom of this message.
 
 Unqualified excepts are evil -- see this recent post (mine)
 http://groups.google.com/group/comp.lang.python/msg/05e822f694b6421c
 
 But in this case you hit a known bug in cgitb - see  
 http://bugs.python.org/issue4643 for a solution.

Aha!  Thank you!  That explains everything, except this:  why does the 
problem go away when I run under wsgiref and capture the request in a 
global variable?

Feel free to treat that as a rhetorical question :)

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


Re: Sloooooowwwww WSGI restart

2009-01-30 Thread Ron Garret
In article 
146f6796-37b5-4220-bdb1-5119cb3ac...@z6g2000pre.googlegroups.com,
 Graham Dumpleton graham.dumple...@gmail.com wrote:

 On Jan 30, 9:53 am, Ron Garret rnospa...@flownet.com wrote:
  In article 498171a5$0$3681$426a7...@news.free.fr,
   Bruno Desthuilliers bruno.42.desthuilli...@websiteburo.invalid
 
   wrote:
   Ron Garret a écrit :
In article mailman.8228.1233179089.3487.python-l...@python.org,
 Aleksandar Radulovic a...@a13x.net wrote:
   (snip)
Secondly, why are you restarting apache after code changes? In normal
circumstances, you shouldn't have to do that.
 
I thought (and experiment confirms) that only the main WSGI app file
gets reloaded automatically when it changes, not the libraries.
 
   Depends on how you configure mod_wsgi. Read the part about Process
   Reloading Mechanism here:
  http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
 
  I'm running Debian Etch, which means I have an older version of
  mod_wsgi, which means I don't have the process reloading mechanism.
 
 Back port available at:
 
   http://packages.debian.org/etch-backports/libapache2-mod-wsgi
 
 Graham

Cool!  Thanks!

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


Re: More mod_wsgi weirdness: process restarts on redirect

2009-01-30 Thread Ron Garret
In article 
63cf7deb-f15c-4259-aa24-1b8da8468...@r41g2000prr.googlegroups.com,
 Graham Dumpleton graham.dumple...@gmail.com wrote:

 On Jan 30, 11:01 am, Ron Garret rnospa...@flownet.com wrote:
  In article mailman.8321.1233272610.3487.python-l...@python.org,
   Joshua Kugler jos...@joshuakugler.com wrote:
 
   Ron Garret wrote:
My question is: is this supposed to be happening?  Or is this an
indication that something is wrong, and if so, what?
 
   You are probably just hitting a different instance of Apache, thus the
   different process ID.
 
  Yep, that's what it turned out to be.  I thought I had a
  WSGIDaemonProcess processes=1 directive in my config, but I had it in
  the wrong place (a different vhost) so it wasn't actually active.
  http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading
  But that leaves me wondering why the redirect would reliably trigger
  switching processes.  The reason I thought that I had the correct
  configuration and only had one process is that when I reloaded the
  non-redirected page I *always* got the same process ID.  How 
  doesmod_wsgidecide which process  (and which thread for that matter) to 
  use?
 
 Details on process/threading in mod_wsgi available at:
 
   http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading
 
 When using WSGIDaemonProcess directive, if you want a single process
 it is better to allow it to default to a single process and not have
 'processes=1'. As soon as you say 'processes=1' it will trigger
 wsgi.multiprocess to be True rather than default of False. This may
 sound counter intuitive, but is a little back door to allow
 wsgi.multiprocess to be set to True somehow when distributing an
 application across a cluster of machines where it does need to be True
 even if each machine only has a single process for that application.
 Tthat wsgi.multiprocess is True will not usually matter unless you are
 trying to use debugging middleware that require that there only be a
 single process.
 
 As to why you were getting a different process, because you were
 actually running in embedded mode due to WSGIDaemonProcess/
 WSGIProcessGroup being in wrong context, then what process was used
 was really up to Apache and how it works. Specifically it can have
 multiple processes that can listen on the HTTP port (80). Because only
 one should be listening at a time it uses a cross process mutex lock
 to mediate access. When a process handles a request, it gives up the
 lock. If using worker MPM then another thread in same process may get
 lock, or for either worker MPM or prefork MPM, then another process
 could get it. Which actually gets it is a bit indeterminate as simply
 depends on which process the operating system lets have the lock next.
 So, there is no strict rule one can say as to who would get it next.
 
 Graham
 Graham

Thanks!

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


Re: Sloooooowwwww WSGI restart

2009-01-29 Thread Ron Garret
In article 498171a5$0$3681$426a7...@news.free.fr,
 Bruno Desthuilliers bruno.42.desthuilli...@websiteburo.invalid 
 wrote:

 Ron Garret a écrit :
  In article mailman.8228.1233179089.3487.python-l...@python.org,
   Aleksandar Radulovic a...@a13x.net wrote:
 (snip)
  Secondly, why are you restarting apache after code changes? In normal
  circumstances, you shouldn't have to do that.
  
  I thought (and experiment confirms) that only the main WSGI app file 
  gets reloaded automatically when it changes, not the libraries.
 
 Depends on how you configure mod_wsgi. Read the part about Process 
 Reloading Mechanism here:
 http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode

I'm running Debian Etch, which means I have an older version of 
mod_wsgi, which means I don't have the process reloading mechanism.

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


Re: Sloooooowwwww WSGI restart

2009-01-29 Thread Ron Garret
In article 498170d4$0$23718$426a7...@news.free.fr,
 Bruno Desthuilliers bruno.42.desthuilli...@websiteburo.invalid 
 wrote:

 Ron Garret a écrit :
  I'm running a WSGI app under apache/mod_wsgi and I've noticed that 
  whenever I restart the server after making a code change it takes a very 
  long time (like a minute) before the script is active again.  In other 
  words, I do an apachectl restart, reload the page in my browser, and one 
  minute later it finally comes up.  During this time CPU usage is 
  essentially zero.  Loading all the code manually into a python 
  interpreter is virtually instantaneous, and all subsequence interactions 
  with the app are very fast.
  
  Does anyone have any ideas what might be going on or how to debug this?
 
 Restarting apache (with or without mod_wsgi) can by itself take some time.
 
 Now, if you're running mod_wsgi in daemon mode, you _don't_ have to 
 restart apache to reload your code - just touch the wsgi script file and 
 you'll be done, ie with:
 
 
WSGIProcessGroup myproject.tld
WSGIDaemonProcess myproject.tld user=you group=you
WSGIReloadMechanism Process
WSGIScriptAlias / /var/www/myproject/apache/myapp.py
 
 
 you just have to touch myapp.py to force reload the subinterpreter(s).

Unfortunately, I'm running Debian Etch, which has an older mod_wsgi, 
which does not have the process reloading mechanism.

But I guess if this gets too painful I'll upgrade.

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


More mod_wsgi weirdness: process restarts on redirect

2009-01-29 Thread Ron Garret
I'm running mod_wsgi under apache (on Debian etch so it's a somewhat out 
of date version, though I doubt that has anything to do with this issue).

I have a little test page that displays the process ID under which my 
app is running, and some global state, so I can tell when the wsgi app 
gets reloaded.  This mostly only happens when I restart apache, but it 
also seems to happen when my WSGI app does an HTTP 302 redirect.  (I'm 
actually using Yaro and calling req.redirect, but that only does a 
straightforward HTTP 302 redirect as far as I can tell.)  It not only 
resets the global state, but changes process ID, so it seems to be doing 
a complete restart of mod_wsgi, which seems a little excessive.

My question is: is this supposed to be happening?  Or is this an 
indication that something is wrong, and if so, what?

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Re: More mod_wsgi weirdness: process restarts on redirect

2009-01-29 Thread Ron Garret
In article rnospamon-a73662.15010729012...@news.gha.chartermi.net,
 Ron Garret rnospa...@flownet.com wrote:

 I'm running mod_wsgi under apache (on Debian etch so it's a somewhat out 
 of date version, though I doubt that has anything to do with this issue).
 
 I have a little test page that displays the process ID under which my 
 app is running, and some global state, so I can tell when the wsgi app 
 gets reloaded.  This mostly only happens when I restart apache, but it 
 also seems to happen when my WSGI app does an HTTP 302 redirect.  (I'm 
 actually using Yaro and calling req.redirect, but that only does a 
 straightforward HTTP 302 redirect as far as I can tell.)  It not only 
 resets the global state, but changes process ID, so it seems to be doing 
 a complete restart of mod_wsgi, which seems a little excessive.
 
 My question is: is this supposed to be happening?  Or is this an 
 indication that something is wrong, and if so, what?
 
 Thanks,
 rg

Here's a standalone WSGI app demonstrating the phenomenon:

def redirect_test(env, start):
  if env['PATH_INFO']:
start('302 Found', [('Location', '/')])
return ['Redirecting']
  else:
start('200 OK', [('Content-type', 'text/plain')])
return ['PID', str(os.getpid())]
  pass

application = redirect_test


Fire this up under mod_wsgi and observe that the process ID stays the 
same when you reload the app.  Now add a path component to trigger the 
redirect and observe that process ID changes.

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


Re: More mod_wsgi weirdness: process restarts on redirect

2009-01-29 Thread Ron Garret
In article mailman.8321.1233272610.3487.python-l...@python.org,
 Joshua Kugler jos...@joshuakugler.com wrote:

 Ron Garret wrote:
  My question is: is this supposed to be happening?  Or is this an
  indication that something is wrong, and if so, what?
 
 You are probably just hitting a different instance of Apache, thus the
 different process ID.

Yep, that's what it turned out to be.  I thought I had a 
WSGIDaemonProcess processes=1 directive in my config, but I had it in 
the wrong place (a different vhost) so it wasn't actually active.

But that leaves me wondering why the redirect would reliably trigger 
switching processes.  The reason I thought that I had the correct 
configuration and only had one process is that when I reloaded the 
non-redirected page I *always* got the same process ID.  How does 
mod_wsgi decide which process  (and which thread for that matter) to use?

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


Sloooooowwwww WSGI restart

2009-01-28 Thread Ron Garret
I'm running a WSGI app under apache/mod_wsgi and I've noticed that 
whenever I restart the server after making a code change it takes a very 
long time (like a minute) before the script is active again.  In other 
words, I do an apachectl restart, reload the page in my browser, and one 
minute later it finally comes up.  During this time CPU usage is 
essentially zero.  Loading all the code manually into a python 
interpreter is virtually instantaneous, and all subsequence interactions 
with the app are very fast.

Does anyone have any ideas what might be going on or how to debug this?

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Sloooooowwwww WSGI restart

2009-01-28 Thread Ron Garret
In article mailman.8228.1233179089.3487.python-l...@python.org,
 Aleksandar Radulovic a...@a13x.net wrote:

 Hi there,
 
 On Wed, Jan 28, 2009 at 9:35 PM, Ron Garret rnospa...@flownet.com wrote:
  I'm running a WSGI app under apache/mod_wsgi and I've noticed that
 
 Off the bat, there's no reason to run an app under apache/mod_wsgi
 while developing it,
 ie. if u use Pylons or TurboGears, there's an easier way to serve the
 app (using paster
 or cherrypy).

Yes, I know.  I guess I'm just a masochist.  But this would be an issue 
in production as well.  I don't want to have to go down for a minute 
every time I push a new release.

 Secondly, why are you restarting apache after code changes? In normal
 circumstances, you shouldn't have to do that.

I thought (and experiment confirms) that only the main WSGI app file 
gets reloaded automatically when it changes, not the libraries.

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


Re: Sloooooowwwww WSGI restart

2009-01-28 Thread Ron Garret
In article mailman.8227.1233179051.3487.python-l...@python.org,
 Jean-Paul Calderone exar...@divmod.com wrote:

 On Wed, 28 Jan 2009 13:35:56 -0800, Ron Garret rnospa...@flownet.com wrote:
 I'm running a WSGI app under apache/mod_wsgi and I've noticed that
 whenever I restart the server after making a code change it takes a very
 long time (like a minute) before the script is active again.  In other
 words, I do an apachectl restart, reload the page in my browser, and one
 minute later it finally comes up.  During this time CPU usage is
 essentially zero.  Loading all the code manually into a python
 interpreter is virtually instantaneous, and all subsequence interactions
 with the app are very fast.
 
 Does anyone have any ideas what might be going on or how to debug this?
 
 strace is nice.  It sounds like some blocking network operation.  rdns can
 often cause things like this.  If you're lucky, strace will point right at
 the problem.
 
 Jean-Paul

That's a good idea.  Thanks!

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


Re: Sloooooowwwww WSGI restart

2009-01-28 Thread Ron Garret
In article 
4cd232ff-ba8b-47aa-8ee6-d8d9712db...@s1g2000prg.googlegroups.com,
 Graham Dumpleton graham.dumple...@gmail.com wrote:

 On Jan 29, 8:35 am, Ron Garret rnospa...@flownet.com wrote:
  I'm running a WSGI app under apache/mod_wsgiand I've noticed that
  whenever I restart the server after making a code change it takes a very
  long time (like a minute) before the script is active again.  In other
  words, I do an apachectl restart, reload the page in my browser, and one
  minute later it finally comes up.  During this time CPU usage is
  essentially zero.  Loading all the code manually into a python
  interpreter is virtually instantaneous, and all subsequence interactions
  with the app are very fast.
 
  Does anyone have any ideas what might be going on or how to debug this?
 
 The better place to discuss this is the mod_wsgi list.
 
   http://groups.google.com/group/modwsgi?hl=en

The reason I don't go there is that I'm using an NNTP client.  I find 
Google Groups' web interface to be very annoying because there's no way 
to keep track of read messages.

 As to the problem, you need to distinguish between whether it is
 Apache that is taking a long time to restart and ready to handle
 requests, or whether the delay is on the first subsequent request made
 against your WSGI application.
 
 When Apache restarts, it doesn't by default load your WSGI
 application, it only does that the first time a request comes in
 directed at it. Thus, if after you restart Apache you do a request of
 a static file, do you get a response straight away?

I thought I did, but having poked at it more I now realize that I was 
just getting a cached page.  It does appear to be an apache issue, not a 
WSGI issue.  Sorry for the false alarm.

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


Yaro vs WebOb

2009-01-19 Thread Ron Garret
I'm selecting infrastructure for a web development and I've found two 
lightweight frameworks that seem to offer a lot of bang-for-the-byte: 
Yaro and WebOb.  I'm wondering if anyone here has used either or both 
and has opinions about them.  What has been your experience with them?  
Which do you prefer?

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


wsgi silently swallows errors

2009-01-19 Thread Ron Garret
Consider the following wsgi app:

def application(env, start_response):
  start_response('200 OK',[('Content-type','text/plain')])
  yield hello
  x=1/0
  yield world

The result of this is that the web browser displays hello and an error 
message ends up in the web log.  But there is no other indication that 
an error has occurred.

Is there any way to get WSGI to not silently swallow errors that occur 
after start_response has been called?

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


WSGI question: reading headers before message body has been read

2009-01-18 Thread Ron Garret
I'm writing a WSGI application and I would like to check the content-
length header before reading the content to make sure that the content
is not too big in order to prevent denial-of-service attacks.  So I do
something like this:

def application(environ, start_response):
status = 200 OK
headers = [('Content-Type', 'text/html'), ]
start_response(status, headers)
if int(environ['CONTENT_LENGTH'])1000: return 'File too big'

But this doesn't seem to work.  If I upload a huge file it still waits
until the entire file has been uploaded before complaining that it's
too big.

Is it possible to read the HTTP headers in WSGI before the request
body has been read?

Thanks,
rg

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


Re: WSGI question: reading headers before message body has been read

2009-01-18 Thread Ron Garret
On Jan 18, 11:29 am, Diez B. Roggisch de...@nospam.web.de wrote:
 Ron Garret schrieb:



  I'm writing a WSGI application and I would like to check the content-
  length header before reading the content to make sure that the content
  is not too big in order to prevent denial-of-service attacks.  So I do
  something like this:

  def application(environ, start_response):
      status = 200 OK
      headers = [('Content-Type', 'text/html'), ]
      start_response(status, headers)
      if int(environ['CONTENT_LENGTH'])1000: return 'File too big'

  But this doesn't seem to work.  If I upload a huge file it still waits
  until the entire file has been uploaded before complaining that it's
  too big.

  Is it possible to read the HTTP headers in WSGI before the request
  body has been read?

 AFAIK that is nothing that WSGI defines - it's an implementation-detail
 of your server. Which one do you use?

Apache at the moment, with lighttpd as a contender to replace it.

rg

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


Re: WSGI question: reading headers before message body has been read

2009-01-18 Thread Ron Garret
On Jan 18, 11:43 am, Petite Abeille petite.abei...@gmail.com wrote:
 On Jan 18, 2009, at 8:01 PM, Ron Garret wrote:

  def application(environ, start_response):
     status = 200 OK
     headers = [('Content-Type', 'text/html'), ]
     start_response(status, headers)
     if int(environ['CONTENT_LENGTH'])1000: return 'File too big'

 How would that work for chunked transfer-encoding?

It wouldn't.  But many clients don't use chunked-transfer-encoding
when uploading files whose size is known.  In that case it would be
nice to let users know that their upload is going to fail BEFORE they
waste hours waiting for 10GB of data to go down the wire.

rg

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


Re: WSGI question: reading headers before message body has been read

2009-01-18 Thread Ron Garret
On Jan 18, 12:40 pm, Diez B. Roggisch de...@nospam.web.de wrote:
 Ron Garret schrieb:



  On Jan 18, 11:29 am, Diez B. Roggisch de...@nospam.web.de wrote:
  Ron Garret schrieb:

  I'm writing a WSGI application and I would like to check the content-
  length header before reading the content to make sure that the content
  is not too big in order to prevent denial-of-service attacks.  So I do
  something like this:
  def application(environ, start_response):
      status = 200 OK
      headers = [('Content-Type', 'text/html'), ]
      start_response(status, headers)
      if int(environ['CONTENT_LENGTH'])1000: return 'File too big'
  But this doesn't seem to work.  If I upload a huge file it still waits
  until the entire file has been uploaded before complaining that it's
  too big.
  Is it possible to read the HTTP headers in WSGI before the request
  body has been read?
  AFAIK that is nothing that WSGI defines - it's an implementation-detail
  of your server. Which one do you use?

  Apache at the moment, with lighttpd as a contender to replace it.

 Together with mod_wsgi?

 Diez

Yes.  (Is there any other way to run WSGI apps under Apache?)

rg

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


Re: WSGI question: reading headers before message body has been read

2009-01-18 Thread Ron Garret
On Jan 18, 1:21 pm, Graham Dumpleton graham.dumple...@gmail.com
wrote:
 On Jan 19, 6:01 am, Ron Garret r...@flownet.com wrote:

  I'm writing a WSGI application and I would like to check the content-
  length header before reading the content to make sure that the content
  is not too big in order to prevent denial-of-service attacks.  So I do
  something like this:

  def application(environ, start_response):
      status = 200 OK
      headers = [('Content-Type', 'text/html'), ]
      start_response(status, headers)
      if int(environ['CONTENT_LENGTH'])1000: return 'File too big'

 You should be returning 413 (Request Entity Too Large) error status
 for that specific case, not a 200 response.

 You should not be returning a string as response content as it is very
 inefficient, wrap it in an array.

  But this doesn't seem to work.  If I upload a huge file it still waits
  until the entire file has been uploaded before complaining that it's
  too big.

  Is it possible to read the HTTP headers in WSGI before the request
  body has been read?

 Yes.

 The issue is that in order to avoid the client sending the data the
 client needs to actually make use of HTTP/1.1 headers to indicate it
 is expecting a 100-continue response before sending data. You don't
 need to handle that as Apache/mod_wsgi does it for you, but the only
 web browser I know of that supports 100-continue is Opera browser.
 Clients like curl do also support it as well though. In other words,
 if people use IE, Firefox or Safari, the request content will be sent
 regardless anyway.

 There is though still more to this though. First off is that if you
 are going to handle 413 errors in your own WSGI application and you
 are using mod_wsgi daemon mode, then request content is still sent by
 browser regardless, even if using Opera. This is because the act of
 transferring content across to mod_wsgi daemon process triggers return
 of 100-continue to client and so it sends data. There is a ticket for
 mod_wsgi to implement proper 100-continue support for daemon mode, but
 will be a while before that happens.

 Rather than have WSGI application handle 413 error cases, you are
 better off letting Apache/mod_wsgi handle it for you. To do that all
 you need to do is use the Apache 'LimitRequestBody' directive. This
 will check the content length for you and send 413 response without
 the WSGI application even being called. When using daemon mode, this
 is done in Apache child worker processes and for 100-continue case
 data will not be read at all and can avoid client sending it if using
 Opera.

 Only caveat on that is the currently available mod_wsgi has a bug in
 it such that 100-continue requests not always working for daemon mode.
 You need to apply fix in:

  http://code.google.com/p/modwsgi/issues/detail?id=121

 For details on LimitRequestBody directive see:

  http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestbody

 Graham

Thanks for the detailed response!

rg

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


Re: Need help getting MoinMoin to run under WSGI

2008-12-28 Thread Ron Garret
In article rnospamon-79fa22.21571527122...@news.gha.chartermi.net,
 Ron Garret rnospa...@flownet.com wrote:

 I successfully installed MoinMoin as a CGI according to the instructions 
 on the moinmo.in site.  But when I tried to switch over to running it 
 under wsgi it failed thusly:
 
 [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] Traceback (most 
 recent call last):
 [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2]   File 
 /www/wikis/genesisgroup/moin.wsgi, line 49, in ?
 [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] from 
 MoinMoin.server.server_wsgi import WsgiConfig, moinmoinApp
 [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] ImportError: No 
 module named MoinMoin.server.server_wsgi
 
 The problem, I believe, is that I have both Python 2.4 and 2.5 installed 
 (it's a Debian box) and MM is installed under 2.5 but WSGI is using 2.4.  
 I tried to fix this by setting WSGIPythonHome but to no avail.  I can't 
 figure out what to set it to.  The instructions say:
 
 the WSGIPythonHome directive should be used to specify the exact 
 location of the Python installation corresponding to the version of 
 Python compiled against
 
 I have two problems with this.  First, I didn't compile mod_wsgi, I got 
 it pre-built as a Debian module.  Second, what does the exact location 
 of the Python installation even mean?  Python2.5 is spread out in at 
 least three different places: /usr/local/bin, /usr/lib/python2.5, and 
 /usr/local/lib/python2.5.  I've tried setting WSGIPythonHome to all of 
 those (and a few other things as well) and nothing worked.
 
 Also, the version of Python compiled against seems very odd.  What 
 does that mean?  Surely I don't have to recompile mod_wsgi every time I 
 change to a new version of Python?
 
 Help!  Thanks!
 
 rg

So never mind, I figured it out.  I did indeed have to recompile 
mod_wsgi from source to get it to use Python 2.5.  (That turned out to 
be a major hassle.  I had to do it twice.  The first time through it 
made Apache dump core.  I still don't know why.)

Seems to be working now though.

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


Re: Need help getting MoinMoin to run under WSGI

2008-12-28 Thread Ron Garret
In article 
f97e6514-1d36-42ed-b0f7-98e2b3162...@d36g2000prf.googlegroups.com,
 Graham Dumpleton graham.dumple...@gmail.com wrote:

 On Dec 28, 7:22 pm, Ron Garret rnospa...@flownet.com wrote:
  In article rnospamon-79fa22.21571527122...@news.gha.chartermi.net,
   Ron Garret rnospa...@flownet.com wrote:
 
 
 
   I successfully installed MoinMoin as a CGI according to the instructions
   on the moinmo.in site.  But when I tried to switch over to running it
   under wsgi it failed thusly:
 
   [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] Traceback (most
   recent call last):
   [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2]   File
   /www/wikis/genesisgroup/moin.wsgi, line 49, in ?
   [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2]     from
   MoinMoin.server.server_wsgi import WsgiConfig, moinmoinApp
   [Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] ImportError: No
   module named MoinMoin.server.server_wsgi
 
   The problem, I believe, is that I have both Python 2.4 and 2.5 installed
   (it's a Debian box) and MM is installed under 2.5 but WSGI is using 2.4. 
    
   I tried to fix this by setting WSGIPythonHome but to no avail.  I can't
   figure out what to set it to.  The instructions say:
 
   the WSGIPythonHome directive should be used to specify the exact
   location of the Python installation corresponding to the version of
   Python compiled against
 
   I have two problems with this.  First, I didn't compilemod_wsgi, I got
   it pre-built as a Debian module.  Second, what does the exact location
   of the Python installation even mean?  Python2.5 is spread out in at
   least three different places: /usr/local/bin, /usr/lib/python2.5, and
   /usr/local/lib/python2.5.  I've tried setting WSGIPythonHome to all of
   those (and a few other things as well) and nothing worked.
 
   Also, the version of Python compiled against seems very odd.  What
   does that mean?  Surely I don't have to recompilemod_wsgievery time I
   change to a new version of Python?
 
   Help!  Thanks!
 
   rg
 
  So never mind, I figured it out.  I did indeed have to 
  recompilemod_wsgifrom source to get it to use Python 2.5.  (That turned out 
  to
  be a major hassle.  I had to do it twice.  The first time through it
  made Apache dump core.  I still don't know why.)
 
  Seems to be working now though.
 
 It probably crashed the first time because you didn't do a full stop
 of Apache and instead just did a reload. Doing a reload may not unload
 the Python libraries from Apache process correctly and so would have
 been a mix of code for different versions of Python in same process.
 
 Graham

Yes, I don't specifically recall exactly what happened now, but that 
seems likely.

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Need help getting MoinMoin to run under SCGI

2008-12-28 Thread Ron Garret
So I have a MoinMoin installation running as a cgi and also under wsgi.  
Since I was on a roll I decided to press my luck and try running it 
under scgi.  Following a suggestion in the following article:

 http://www.linuxjournal.com/article/9310

I wrote this little server adapter:



from MoinMoin.server.server_cgi import CgiConfig, run

class Config(CgiConfig):
name = 'moin'

import scgi
import scgi.scgi_server

class MoinHandler(scgi.scgi_server.SCGIHandler):
def produce_cgilike(self, env, bodysize):
run(Config)

server = scgi.scgi_server.SCGIServer(
handler_class=MoinHandler,
port=4000
)

server.serve()



It works -- sort of.  I can fire it up and get to the login page, but it 
won't actually let me log in.  I'm guessing this is because I haven't 
munged the CGI form data properly.  I thought I'd ask if anyone with 
experience using SCGI can just tell me what I'm doing wrong before I 
dive into debugging this.

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Need help getting MoinMoin to run under WSGI

2008-12-27 Thread Ron Garret
I successfully installed MoinMoin as a CGI according to the instructions 
on the moinmo.in site.  But when I tried to switch over to running it 
under wsgi it failed thusly:

[Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] Traceback (most 
recent call last):
[Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2]   File 
/www/wikis/genesisgroup/moin.wsgi, line 49, in ?
[Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] from 
MoinMoin.server.server_wsgi import WsgiConfig, moinmoinApp
[Sat Dec 27 21:44:14 2008] [error] [client 66.214.189.2] ImportError: No 
module named MoinMoin.server.server_wsgi

The problem, I believe, is that I have both Python 2.4 and 2.5 installed 
(it's a Debian box) and MM is installed under 2.5 but WSGI is using 2.4.  
I tried to fix this by setting WSGIPythonHome but to no avail.  I can't 
figure out what to set it to.  The instructions say:

the WSGIPythonHome directive should be used to specify the exact 
location of the Python installation corresponding to the version of 
Python compiled against

I have two problems with this.  First, I didn't compile mod_wsgi, I got 
it pre-built as a Debian module.  Second, what does the exact location 
of the Python installation even mean?  Python2.5 is spread out in at 
least three different places: /usr/local/bin, /usr/lib/python2.5, and 
/usr/local/lib/python2.5.  I've tried setting WSGIPythonHome to all of 
those (and a few other things as well) and nothing worked.

Also, the version of Python compiled against seems very odd.  What 
does that mean?  Surely I don't have to recompile mod_wsgi every time I 
change to a new version of Python?

Help!  Thanks!

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


Re: CTypes on a 64 bit machine truncates pointers to 32 bits?

2008-09-19 Thread Ron Garret
In article [EMAIL PROTECTED],
 Martin v. Löwis [EMAIL PROTECTED] wrote:

  foolib = cdll.LoadLibrary('foo.so')
  foolib.foo(0xF)
  0
 
 Shouldn't you tell ctypes that the argument and the result
 of foo is a pointer?

Yeah... that's it.  Default return type is int, which I assumed would be 
64 bits on a 64 bit machine, but turns out it's 32.  Stupid.

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

CTypes on a 64 bit machine truncates pointers to 32 bits?

2008-09-18 Thread Ron Garret
CTypes on a 64-bit machine appears to be truncating pointers to 32 bits:

[EMAIL PROTECTED]:~]$ uname -a
Linux monster1 2.6.18-6-amd64 #1 SMP Mon Jun 16 22:30:01 UTC 2008 x86_64 
GNU/Linux
[EMAIL PROTECTED]:~]$ cat foo.c
void* foo(void* x) { return x; }
[EMAIL PROTECTED]:~]$ gcc -fPIC -shared foo.c -o foo.so
[EMAIL PROTECTED]:~]$ file foo.so
foo.so: ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not 
stripped
[EMAIL PROTECTED]:~]$ python
Python 2.5 (release25-maint, Jul 23 2008, 18:15:29) 
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type help, copyright, credits or license for more information.
 from ctypes import *
 foolib = cdll.LoadLibrary('foo.so')
 foolib.foo(0xF)
0
 sizeof(c_void_p)
8
 

I am aware of http://bugs.python.org/issue1703286 but I get the same 
result in Python2.5.2:

[EMAIL PROTECTED]:~]$ py252/bin/python
Python 2.5.2 (r252:60911, Sep 18 2008, 10:48:29) 
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type help, copyright, credits or license for more information.
 from ctypes import *
 foolib = cdll.LoadLibrary('foo.so')
 foolib.foo(0xF)
0
 sizeof(c_void_p)
8

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


Re: Parsing MIME-encoded data in an HTTP request

2008-07-06 Thread Ron Garret
In article [EMAIL PROTECTED],
 Michael Ströder [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  In article [EMAIL PROTECTED],
   Ron Garret [EMAIL PROTECTED] wrote:
  
  In article [EMAIL PROTECTED],
   Michael Ströder [EMAIL PROTECTED] wrote:
 
  Ron Garret wrote:
  I'm writing a little HTTP server and need to parse request content that 
  is mime-encoded.  All the MIME routines in the Python standard library 
  seem to have been subsumed into the email package, which makes this 
  operation a little awkward.
  How about using cgi.parse_multipart()?
 
  Unfortunately cgi.parse_multipart doesn't handle nested multiparts, 
  which the requests I'm getting have.  You have to use a FieldStorage 
  object to do that, and that only works if you're actually in a cgi 
  environment, which I am not.  The server responds to these requests 
  directly.
 
  Anyway, thanks for the idea.
  
  Hm, it actually seems to work if I manually pass in the outerboundary 
  parameter and environ={'REQUEST_METHOD':'POST'}  That seems like the 
  Right Answer.
 
 I'm also using it to parse form parameters in a message body received by 
 POST.
 
 CIao, Michael.

Just for the record, here's the incantation I ended up with:


class post_handler(BaseHTTPRequestHandler):
  def do_POST(self):
form = cgi.FieldStorage(fp=self.rfile, headers=self.headers,
environ={'REQUEST_METHOD':'POST'})
...


works like a charm.

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

Re: Parsing MIME-encoded data in an HTTP request

2008-07-04 Thread Ron Garret
In article 
[EMAIL PROTECTED],
 [EMAIL PROTECTED] wrote:

 On Jul 3, 3:59 pm, Ron Garret [EMAIL PROTECTED] wrote:
  I'm writing a little HTTP server and need to parse request content that
  is mime-encoded.  All the MIME routines in the Python standard library
  seem to have been subsumed into the email package, which makes this
  operation a little awkward.
 
 To deal with messages of that kind, I've seen modules such as
 'rfc822', and 'mimetools' (which apparently builds itself from
 'rfc822', so it might be more complete). There's also 'mimetypes', in
 case you need to deal with file extensions and their corresponding
 MIME media type.

From the mimetools docs:

Deprecated since release 2.3. The email package should be used in 
preference to the  module. This module is present only to maintain 
backward compatibility.

 
  It seems I have to do the following:
 
  1.  Extract the content-length header from the HTTP request and use that
  to read the payload.
 
  2.  Stick some artificial-looking headers onto the beginning of this
  payload to make it look like an email message (including the
  content-type and content-transfer-encoding headers)
 
  3.  Parse the resulting string into a email message
 
 
 Email? Why does an HTTP server need to build an email message?

It shouldn't.  That's my whole point.  But see the docs excerpt above.

 I remember doing things like that some time ago when building an HTTP
 server myself (http://code.google.com/p/sws-d/). Incidentally, I
 resisted the urge to use much of the Python's library facilities (most
 things are done manually; am I a knucklehead or what!? :). You might
 wanna take a look to get some ideas.

I'd much prefer not to reinvent this particular wheel.

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


Re: Parsing MIME-encoded data in an HTTP request

2008-07-04 Thread Ron Garret
In article [EMAIL PROTECTED],
 Michael Ströder [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  I'm writing a little HTTP server and need to parse request content that 
  is mime-encoded.  All the MIME routines in the Python standard library 
  seem to have been subsumed into the email package, which makes this 
  operation a little awkward.
 
 How about using cgi.parse_multipart()?
 
 Ciao, Michael.

Unfortunately cgi.parse_multipart doesn't handle nested multiparts, 
which the requests I'm getting have.  You have to use a FieldStorage 
object to do that, and that only works if you're actually in a cgi 
environment, which I am not.  The server responds to these requests 
directly.

Anyway, thanks for the idea.

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

Re: Parsing MIME-encoded data in an HTTP request

2008-07-04 Thread Ron Garret
In article [EMAIL PROTECTED],
 Ron Garret [EMAIL PROTECTED] wrote:

 In article [EMAIL PROTECTED],
  Michael Ströder [EMAIL PROTECTED] wrote:
 
  Ron Garret wrote:
   I'm writing a little HTTP server and need to parse request content that 
   is mime-encoded.  All the MIME routines in the Python standard library 
   seem to have been subsumed into the email package, which makes this 
   operation a little awkward.
  
  How about using cgi.parse_multipart()?
  
  Ciao, Michael.
 
 Unfortunately cgi.parse_multipart doesn't handle nested multiparts, 
 which the requests I'm getting have.  You have to use a FieldStorage 
 object to do that, and that only works if you're actually in a cgi 
 environment, which I am not.  The server responds to these requests 
 directly.
 
 Anyway, thanks for the idea.
 
 rg

Hm, it actually seems to work if I manually pass in the outerboundary 
parameter and environ={'REQUEST_METHOD':'POST'}  That seems like the 
Right Answer.

Woohoo!

Thanks Michael!

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

Parsing MIME-encoded data in an HTTP request

2008-07-03 Thread Ron Garret
I'm writing a little HTTP server and need to parse request content that 
is mime-encoded.  All the MIME routines in the Python standard library 
seem to have been subsumed into the email package, which makes this 
operation a little awkward.  It seems I have to do the following:

1.  Extract the content-length header from the HTTP request and use that 
to read the payload.

2.  Stick some artificial-looking headers onto the beginning of this 
payload to make it look like an email message (including the 
content-type and content-transfer-encoding headers)

3.  Parse the resulting string into a email message

That works, but it feels way too hackish for my tastes.  Surely there 
must be a better/more standard way of doing this?

Thanks,
rg
--
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a way to change the default string encoding?

2007-08-21 Thread Ron Garret
In article [EMAIL PROTECTED],
 Peter Otten [EMAIL PROTECTED] wrote:

 If all else fails there's
 
  sys.setdefaultencoding(latin1)
  Andre\xe9 Ramel.decode()
 u'Andre\xe9 Ramel'
 
 but that's an evil hack, you should rather talk to the maintainer of the
 offending code to update it to accept unicode.

Yes, but I need to hack around it until I can get it fixed.

Thanks!

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


Is there a way to change the default string encoding?

2007-08-20 Thread Ron Garret
Is there a way to change the default string encoding used by the 
string.encode() method?  My default environment is utf-8 but I need it 
to be latin-1 to avoid errors like this:

 'Andr\xe9 Ramel'.decode() 
Traceback (most recent call last):
  File stdin, line 1, in module
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 4: 
ordinal not in range(128)

I can't change the code to pass an encoding argument to the decode 
method because it's someone else's code.

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Is wsgi ready for prime time?

2007-05-17 Thread Ron Garret
The wsgiref module in Python 2.5 seems to be empty:

[EMAIL PROTECTED]:~/Sites/modpy]$ python
Python 2.5 (r25:51908, Mar  1 2007, 10:09:05) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type help, copyright, credits or license for more information.
 import wsgiref
 dir(wsgiref)
['__builtins__', '__doc__', '__file__', '__name__', '__path__']
 

So... is wsgi considered ready for production use, or is it still on the 
bleeding edge?  And if the former, which implementation should one use?

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


Re: Is wsgi ready for prime time?

2007-05-17 Thread Ron Garret
In article [EMAIL PROTECTED],
 Stargaming [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  The wsgiref module in Python 2.5 seems to be empty:
  
  [EMAIL PROTECTED]:~/Sites/modpy]$ python
  Python 2.5 (r25:51908, Mar  1 2007, 10:09:05) 
  [GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
  Type help, copyright, credits or license for more information.
  
 import wsgiref
 dir(wsgiref)
  
  ['__builtins__', '__doc__', '__file__', '__name__', '__path__']
  
  
  So... is wsgi considered ready for production use, or is it still on the 
  bleeding edge?  And if the former, which implementation should one use?
  
  rg
 
   help(wsgiref)
 Help on package wsgiref:
 
 NAME
  wsgiref - wsgiref -- a WSGI (PEP 333) Reference Library
 
 DESCRIPTION
  Current Contents:
 
  * util -- Miscellaneous useful functions and wrappers
 
  * headers -- Manage response headers
 
  * handlers -- base classes for server/gateway implementations
 
  * simple_server -- a simple BaseHTTPServer that supports WSGI
 
  * validate -- validation wrapper that sits between an app and a server
to detect errors in either
 
  To-Do:
 
  * cgi_gateway -- Run WSGI apps under CGI (pending a deployment 
 standard)
 
  * cgi_wrapper -- Run CGI apps under WSGI
 
  * router -- a simple middleware component that handles URL traversal
 
 PACKAGE CONTENTS
  handlers
  headers
  simple_server
  util
  validate
 
 Reading the documentation can be useful sometimes. Recommending 
 http://docs.python.org/lib/module-wsgiref.html, too.

I did read the documentation, but the documentation does not seem to 
reflect reality, e.g.:

 wsgiref.util 
Traceback (most recent call last):
  File stdin, line 1, in module
AttributeError: 'module' object has no attribute 'util'
 wsgiref.headers
Traceback (most recent call last):
  File stdin, line 1, in module
AttributeError: 'module' object has no attribute 'headers'
 wsgiref.handlers
Traceback (most recent call last):
  File stdin, line 1, in module
AttributeError: 'module' object has no attribute 'handlers'
 

Hence my question.

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


Re: Select weirdness

2007-04-23 Thread Ron Garret
In article [EMAIL PROTECTED],
 Irmen de Jong [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  I don't understand why socketserver calling select should matter.  (And 
  BTW, there are no calls to select in SocketServer.py.  I'm using 
  Python2.5.)
 
 You don't *need* a select at all.

Yes I do, because what I'm really writing is a dispatching proxy that 
has to serve many simultaneous connections.

Here's the full story in case you're interested: We have an application 
that is currently fielded as a cgi.  We have a development server that 
needs to run multiple copies of the application at the same time.  This 
is so that developers can push changes into their private sandboxes 
for evaluation before going into the main development branch.  Each 
sandbox has its own source tree, its own database, and its own URL 
namespace.

There are a small number of URLs in the application that are performance 
bottlenecks (they are used to serve AJAX updates).  In order to 
alleviate that bottleneck without having to rewrite the whole 
application to run under mod_python or some such thing we've written a 
special dedicated server that handles only the AJAX requests.

The tricky part is that each developer needs to have their own copy of 
this server running because each developer can have different code that 
needs to run to serve those requests.  Assigning each developer a 
dedicated IP port would be a configuration nightmare, so these servers 
serve run on unix sockets rather than TCP sockets.

I have not been able to find a proxy server that can proxy to unix 
sockets, so I need to write my own.  Conceptually its a very simple 
thing: read the first line of an HTTP request, parse it with a regexp to 
extract the sandbox name, connect to the appropriate unix server socket, 
and then bidirectionally pipe bytes back and forth.  But it has to do 
this for multiple connections simultaneously, which is why I need select.

  Anyway, try the following instead:
 
  
  That won't work for POST requests.
 
 
 Why not?

Because POST requests can be very complicated.

 Just add some more code to deal with the POST request body.

I was really hoping to avoid having to write a fully HTTP-aware proxy.

 There should be a content-length header to tell you how many
 bytes to read after the header section has finished.

Not if the content-transfer-encoding is chunked.  Or if there are 
multiple file attachments.

Also, even GET requests can become very complicated (from a protocol 
point of view) in HTTP 1.1.

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


Re: Select weirdness

2007-04-23 Thread Ron Garret
In article [EMAIL PROTECTED],
 Gabriel Genellina [EMAIL PROTECTED] wrote:

 En Mon, 23 Apr 2007 04:33:22 -0300, Ron Garret [EMAIL PROTECTED]  
 escribió:
 
  I have not been able to find a proxy server that can proxy to unix
  sockets, so I need to write my own.  Conceptually its a very simple
  thing: read the first line of an HTTP request, parse it with a regexp to
  extract the sandbox name, connect to the appropriate unix server socket,
  and then bidirectionally pipe bytes back and forth.  But it has to do
  this for multiple connections simultaneously, which is why I need select.
 
 No. This is what the *server* should do, not the *handler*. The server  
 listens on incoming requests, and creates a new handler for each one.  
 Inside a handler, you don't have to worry about multiple connections.
 If you want to process simultaneous connections, inherit your server from  
 ThreadingMixIn or ForkingMixIn (or use one of the predefined server  
 classes).

Ah, good point.

But that still leaves the problem of keep-alive connections.  I still 
need to be able to forward data in both directions without knowing ahead 
of time when it will arrive.

(I think I can solve the problem by using send and recv directly BTW.)

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

Re: Select weirdness

2007-04-23 Thread Ron Garret
In article [EMAIL PROTECTED],
 Jean-Paul Calderone [EMAIL PROTECTED] wrote:

 Twisted does this out of the box, for what it's worth.

Thanks.  I will look at that.

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


Re: Select weirdness

2007-04-23 Thread Ron Garret
In article [EMAIL PROTECTED],
 Donn Cave [EMAIL PROTECTED] wrote:

 In article [EMAIL PROTECTED],
  Ron Garret [EMAIL PROTECTED] wrote:
 
  The answer is obvious: select is looking only at the underlying socket, 
  and not at the rfile buffers.
  
  So... is this a bug in select?  Or a bug in my code?
 
 Yes.
 
 I don't see any specific followup to this point, but it is or
 at least should be a well known limitation of C library I/O and
 select.  select() is an operating system function that has no
 way to know the state of your process I/O buffers, nor do the C
 stdio buffers don't come with a standard way to inspect that state.
 Therefore, if you mix C I/O with select(), you're more or less out
 of luck.  This applies directly to Python, because it calls the
 operating system select() function and it uses C stdio buffers for
 its file object (and entices you to make this mistake by supporting
 a file object as an input to select().)
 
 This conflict can be relieved after a fashion by eliminating the
 buffer.  The now unbuffered C fgets / Python readline won't store
 extra lines that select can't see, but the semantics of the operation
 are still a poor fit with the usual application of select.  The
 number of system-level I/O calls is significantly greater as you
 transfer data one byte at a time, which may add a lot of overhead
 if you transfer a lot of data, and your readline() function still
 can't return until it gets that '\n', so a half line can block your
 application.
 
 It isn't a lot of work to read data with operating system functions
 that are compatible with select - os.read(), socket.recv() - and
 break it up into lines on your own, and this completely and efficiently
 resolves the problem.

Yep, this is pretty much the conclusion I've come to.

As an editorial comment, I think it's quite confusing for Python's 
select to accept file objects without complaint if it's not going to do 
the Right Thing with them.

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


Select weirdness

2007-04-22 Thread Ron Garret
Here's my code.  It's a teeny weeny little HTTP server.  (I'm not really 
trying to reinvent the wheel here.  What I'm really doing is writing a 
dispatching proxy server, but this is the shortest way to illustrate the 
problem I'm having):

from SocketServer import *
from socket import *
from select import select

class myHandler(StreamRequestHandler):
  def handle(self):
print ''
while 1:
  sl = select([self.rfile],[],[])[0]
  if sl:
l = self.rfile.readline()
if len(l)3: break
print l,
pass
  pass
printself.wfile, 'HTTP/1.0 200 OK'
printself.wfile, 'Content-type: text/plain'
printself.wfile
printself.wfile, 'foo'
self.rfile.close()
self.wfile.close()
print ''
pass
  pass

def main():
  server = TCPServer(('',8080), myHandler)
  server.serve_forever()
  pass

if __name__ == '__main__': main()


If I telnet into this server and type in an HTTP request manually it 
works fine.  But when I try to access this with a browser (I've tried 
Firefox and Safari -- both do the same thing) it hangs immediately after 
reading the first line in the request (i.e. before reading the first 
header).

When I click the stop button in the browser it breaks the logjam and 
the server reads the headers (but then of course it dies trying to write 
the response to a now-closed socket).

The only difference I can discern is that the browser send \r\n for 
end-of-line while telnet just sends \n.  But I don't see why that should 
make any difference.  So I'm stumped.  Any clues would be much 
appreciated.

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Select weirdness

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Bjoern Schliessmann [EMAIL PROTECTED] 
 wrote:

  The only difference I can discern is that the browser send \r\n
  for end-of-line while telnet just sends \n.  
...
  But I don't see why that should make any difference.  
 
 Easy. If you only accept \r\n as EOL, you'll wait forever unless
 you really receive it.

But it's SELECT that is hanging.  Select knows (or ought to know) 
nothing of end-of-line markers.  Readline (when it is called) is doing 
the Right Thing, and my end-of-request test is (currently) reading a 
line less than 3 characters long.  All that is working.  The problem is 
that select is saying there is no input (and therefore hanging) when in 
fact there is input.

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


Re: Select weirdness

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Irmen de Jong [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  Here's my code.  It's a teeny weeny little HTTP server.  (I'm not really 
  trying to reinvent the wheel here.  What I'm really doing is writing a 
  dispatching proxy server, but this is the shortest way to illustrate the 
  problem I'm having):
  
  from SocketServer import *
  from socket import *
  from select import select
  
  class myHandler(StreamRequestHandler):
def handle(self):
  print ''
  while 1:
sl = select([self.rfile],[],[])[0]
if sl:
  l = self.rfile.readline()
  if len(l)3: break
  print l,
  pass
pass
  printself.wfile, 'HTTP/1.0 200 OK'
  printself.wfile, 'Content-type: text/plain'
  printself.wfile
  printself.wfile, 'foo'
  self.rfile.close()
  self.wfile.close()
  print ''
  pass
pass
 
 
 You shouldn't use a select() of your own inside the handle method.
 The socketserver takes care of that for you.

I don't understand why socketserver calling select should matter.  (And 
BTW, there are no calls to select in SocketServer.py.  I'm using 
Python2.5.)

 What you need to do is read the input from the socket until you've reached
 the end-of-input marker. That marker is an empty line containing just \r\n
 when dealing with HTTP GET requests.

 Any reason don't want to use the BasicHTTPServer that comes with Python?

Yes, but it's a long story.  What I'm really doing is writing a 
dispatching proxy.  It reads the HTTP request and then redirects it to a 
number of different servers depending on the URL.  The servers are all 
local and served off of unix sockets, not TCP sockets (which is why I 
can't just configure Apache to do this).

The reason I'm running this weird configuration (in case you're 
wondering) is because this is a development machine and multiple copies 
of the same website run on it simultaneously.  Each copy of the site 
runs a customized server to handle AJAX requests efficiently.

 
 Anyway, try the following instead:
 

That won't work for POST requests.

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


Re: Select weirdness

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Ron Garret [EMAIL PROTECTED] wrote:

 Here's my code.  It's a teeny weeny little HTTP server.  (I'm not really 
 trying to reinvent the wheel here.  What I'm really doing is writing a 
 dispatching proxy server, but this is the shortest way to illustrate the 
 problem I'm having):
 
 from SocketServer import *
 from socket import *
 from select import select
 
 class myHandler(StreamRequestHandler):
   def handle(self):
 print ''
 while 1:
   sl = select([self.rfile],[],[])[0]
   if sl:
 l = self.rfile.readline()
 if len(l)3: break
 print l,
 pass
   pass
 printself.wfile, 'HTTP/1.0 200 OK'
 printself.wfile, 'Content-type: text/plain'
 printself.wfile
 printself.wfile, 'foo'
 self.rfile.close()
 self.wfile.close()
 print ''
 pass
   pass
 
 def main():
   server = TCPServer(('',8080), myHandler)
   server.serve_forever()
   pass
 
 if __name__ == '__main__': main()
 
 
 If I telnet into this server and type in an HTTP request manually it 
 works fine.  But when I try to access this with a browser (I've tried 
 Firefox and Safari -- both do the same thing) it hangs immediately after 
 reading the first line in the request (i.e. before reading the first 
 header).
 
 When I click the stop button in the browser it breaks the logjam and 
 the server reads the headers (but then of course it dies trying to write 
 the response to a now-closed socket).
 
 The only difference I can discern is that the browser send \r\n for 
 end-of-line while telnet just sends \n.  But I don't see why that should 
 make any difference.  So I'm stumped.  Any clues would be much 
 appreciated.

I have reproduced the problem using Telnet, so that proves it's not an 
EOL issue.  The problem seems to be timing-related.  If I type the 
request in manually it works.  If I paste it in all at once, it hangs.  
It's actually even weirder than that: if I pipe the request into a 
telnet client then it hangs after the request line, just with a browser 
(or wget).  But if I literally paste the request into a window running a 
telnet client, it gets past the request line and four out of seven 
headers before it hangs.

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


Re: Select weirdness

2007-04-22 Thread Ron Garret
I think I've figured out what's going on.

First, here's the smoking gun: I changed the code as follows:

class myHandler(StreamRequestHandler):
  def handle(self):
print ''
while 1:
  sl = select([self.rfile],[],[],1)[0]
  print sl
  l = self.rfile.readline()
  if len(l)3: break
  print l,
  pass

(Rest of code is unchanged.)

In other words, I select on the rfile object and added a timeout.

Here's the result when I cut-and-paste an HTTP request:


[socket._fileobject object at 0x6b110]
GET /foo/baz HTTP/1.1
[socket._fileobject object at 0x6b110]
Accept: */*
[socket._fileobject object at 0x6b110]
Accept-Language: en
[socket._fileobject object at 0x6b110]
Accept-Encoding: gzip, deflate
[socket._fileobject object at 0x6b110]
Cookie: c1=18:19:55.042196; c2=18:19:55.042508
[]
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) 
AppleWebKit/419 (KHTM
[]
L, like Gecko) Safari/419.3
[]
Connection: keep-alive
[]
Host: localhost:8081
[]


As you can see, the select call shows input available for a while (five 
lines) and then shows no input available despite the fact that there is 
manifestly still input available.

The answer is obvious: select is looking only at the underlying socket, 
and not at the rfile buffers.

So... is this a bug in select?  Or a bug in my code?

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


Bug in select (was: Re: Select weirdness)

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Ron Garret [EMAIL PROTECTED] wrote:

 The answer is obvious: select is looking only at the underlying socket, 
 and not at the rfile buffers.

Here is conclusive proof that there's a bug in select:

from socket import *
from select import select
s=socket(AF_INET, SOCK_STREAM)
s.bind(('',8080))
s.listen(5)
f = s.accept()[0].makefile()
# Now telnet to port 8080 and enter two lines of random text
f.readline()
select([f],[],[],1)
f.readline()

Here's the sample input:

[EMAIL PROTECTED]:~/devel/sockets]$ telnet localhost 8081
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
123
321


And this is the result:

 f.readline()
'123\r\n'
 select([f],[],[],1)
# After one second...
([], [], [])
 f.readline()
'321\r\n'
 


So this is clearly a bug, but surely I'm not the first person to have 
encountered this?  Is there a known workaround?

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


Re: Bug in select

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Erik Max Francis [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
 
  So this is clearly a bug, but surely I'm not the first person to have 
  encountered this?  Is there a known workaround?
 
 It's hard to see how this demonstrates a bug in anything, since you're 
 telnetting to the wrong port in your example.

Geez you people are picky.  Since I ran this several times I ran into 
the TIM_WAIT problem.  Here's the actual transcript:

Python 2.5 (r25:51908, Mar  1 2007, 10:09:05) 
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type help, copyright, credits or license for more information.
 from socket import *
 from select import select
 s=socket(AF_INET, SOCK_STREAM)
 s.bind(('',8080))
Traceback (most recent call last):
  File stdin, line 1, in module
  File string, line 1, in bind
socket.error: (48, 'Address already in use')
 s.bind(('',8081))
 s.listen(5)
 f = s.accept()[0].makefile()
 f.readline()
'123\r\n'
 select([f],[],[],1)
([], [], [])
 f.readline()
'321\r\n'
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Bug in select

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Erik Max Francis [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
 
  Geez you people are picky.  Since I ran this several times I ran into 
  the TIM_WAIT problem.  Here's the actual transcript:
 
 It's not about being picky, it's about making it clear what your problem 
 is.  You're now describing an entirely different problem,

Nope, it's been the same problem all along.  If you don't think so then 
you have misunderstood something.

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


Re: Bug in select (was: Re: Select weirdness)

2007-04-22 Thread Ron Garret
In article [EMAIL PROTECTED],
 Dennis Lee Bieber [EMAIL PROTECTED] wrote:

   Well, on WinXP, Python 2.4, with

I should have specified: I'm running 2.5 on unix.  (I've reproduced the 
problem on both Linux and OS X.)

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


Re: BaseHTTPServer and Apache

2007-04-14 Thread Ron Garret
In article [EMAIL PROTECTED],
 Luis M. González [EMAIL PROTECTED] wrote:

 On Apr 13, 8:44 pm, Ron Garret [EMAIL PROTECTED] wrote:
  In article [EMAIL PROTECTED],
   Ron Garret [EMAIL PROTECTED] wrote:
 
   Does
   anyone know of a straightforward way to get Apache to forward requests
   to a given path to another HTTP server running on a different port?
 
  Never mind, I think I figured it out.  Apparently what I need is the
  ProxyPassReverse directive.
 
  I'd still be interested in hearing about people's experience using
  BaseHTTPServer for real applications.
 
  Thanks,
  rg
 
 
 Some python web frameworks use the aproach you described by means of
 mod_rewrite.
 For example, Karrigell and Cherrypy (although they offer also other
 ways of deployment).
 This page in Karrigell's docs show how: 
 http://karrigell.sourceforge.net/en/apache.htm

Thanks for that pointer.  Using the 502 handler to start the server is a 
nifty trick.

So I've got all that working now.  Next question: how do I set things up 
so that I can communicate to my server through a unix domain socket 
instead of a TCP socket?  (The reason I want to do this is that I'm 
running multiple copies of this server so that multiple engineers can do 
development each in their own sandbox, and assigning each of them their 
own port number is a configuration nightmare.)

I got as far as rewriting the server code to use a unix socket, but then 
I got stuck.

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

BaseHTTPServer and Apache

2007-04-13 Thread Ron Garret
I have a fairly large web app written in Python as a CGI fairly 
elaborate CGI.  All of the requests go through a single CGI script which 
does authentication and session management and then dispatches to one of 
a number of handlers that generate the various pages.

There is one page that is a performance bottleneck (because it is 
accessed automatically once a second by an XMLHTTPRequest, but that's 
another story).  I have fixed this by re-implementing that page using a 
BaseHTTPServer.  So I can fix my problem by redirecting the 
XMLHTTPRequest to a URL that is served by this BaseHTTPServer.

The problem is that this server can't run on port 80 because Apache has 
to be there to serve everything else, and having a Python process 
serving a publicly accessible TCP port makes me a little queasy.  Does 
anyone know of a straightforward way to get Apache to forward requests 
to a given path to another HTTP server running on a different port?

Also, is anyone out there using BaseHTTPServer in an industrial setting?  
What has been your experience with it?  And how do you make it fit in to 
your overall architecture?

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


Re: BaseHTTPServer and Apache

2007-04-13 Thread Ron Garret
In article [EMAIL PROTECTED],
 Ron Garret [EMAIL PROTECTED] wrote:

 Does 
 anyone know of a straightforward way to get Apache to forward requests 
 to a given path to another HTTP server running on a different port?

Never mind, I think I figured it out.  Apparently what I need is the 
ProxyPassReverse directive.

I'd still be interested in hearing about people's experience using 
BaseHTTPServer for real applications.

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Python on a mac: how to build pythonw?

2007-03-01 Thread Ron Garret
I'm trying to run the Python examples distributed with XCode and they 
all give me the same error:

Traceback (most recent call last):
  File checktext.py, line 35, in module
main()
  File checktext.py, line 8, in main
pathname = EasyDialogs.AskFileForOpen(message='File to check 
end-of-lines in:')
  File /usr/local/lib/python2.5/plat-mac/EasyDialogs.py, line 650, in 
AskFileForOpen
_interact()
  File /usr/local/lib/python2.5/plat-mac/EasyDialogs.py, line 53, in 
_interact
AE.AEInteractWithUser(5000)
MacOS.Error: (-1713, 'no user interaction is allowed')

Googling reveals that the answer is to use pythonw, but there is no such 
thing installed on my system:

[EMAIL PROTECTED]:~]$ pythonw
-bash: pythonw: command not found

Apparently, pythonw didn't get built when I installed Python 2.5, and I 
can't find any instructions on how to build it.  (The installation 
instructions don't seem to mention it.)

If anyone could spare a clue I would be most grateful.

Thank,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python on a mac: how to build pythonw?

2007-03-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Robert Kern [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  I'm trying to run the Python examples distributed with XCode and they 
  all give me the same error:
  
  Traceback (most recent call last):
File checktext.py, line 35, in module
  main()
File checktext.py, line 8, in main
  pathname = EasyDialogs.AskFileForOpen(message='File to check 
  end-of-lines in:')
File /usr/local/lib/python2.5/plat-mac/EasyDialogs.py, line 650, in 
  AskFileForOpen
  _interact()
File /usr/local/lib/python2.5/plat-mac/EasyDialogs.py, line 53, in 
  _interact
  AE.AEInteractWithUser(5000)
  MacOS.Error: (-1713, 'no user interaction is allowed')
  
  Googling reveals that the answer is to use pythonw, but there is no such 
  thing installed on my system:
  
  [EMAIL PROTECTED]:~]$ pythonw
  -bash: pythonw: command not found
  
  Apparently, pythonw didn't get built when I installed Python 2.5, and I 
  can't find any instructions on how to build it.  (The installation 
  instructions don't seem to mention it.)
 
 It looks like you built Python yourself.

Yep.  I'm a do-it-yourself kind of guy :-)

 The default build does not allow you to
 communicate with the Apple GUI. You need a framework build. I highly 
 recommend
 that you simply use the binary on www.python.org instead of building from
 source. If you do want to build from source, please read the file Mac/README 
 for instructions.

Okeydokey.

 Note that in recent versions of Python, I believe that the pythonw executable 
 is no longer necessary as a workaround.

How recent?  I'm already using 2.5.

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


Re: Python on a mac: how to build pythonw?

2007-03-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Robert Kern [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  In article [EMAIL PROTECTED],
   Robert Kern [EMAIL PROTECTED] wrote:
 
  Note that in recent versions of Python, I believe that the pythonw 
  executable 
  is no longer necessary as a workaround.
  
  How recent?  I'm already using 2.5.
 
 2.5 definitely works.

Yes, once you know the magic incantation:

./configure --enable-universalsdk

:-)

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


Python, readline and OS X

2007-02-01 Thread Ron Garret
I have installed Python 2.5 on my new Intel Mac but I can't for the life 
of me get readline to work.  I have libreadline installed, I've tried 
copying readline.so from my Python 2.3 installation into 2.5, I've 
searched the web, and no joy.  Could someone please give me a clue?

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


Re: Python, readline and OS X

2007-02-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Irmen de Jong [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  I have installed Python 2.5 on my new Intel Mac but I can't for the life 
  of me get readline to work.  I have libreadline installed, I've tried 
  copying readline.so from my Python 2.3 installation into 2.5, I've 
  searched the web, and no joy.  Could someone please give me a clue?
  
  rg
 
 Does the info in a blog article that I wrote help?
 
 http://www.razorvine.net/frog/user/irmen/article/2006-05-08/87

No, because I'm not using Fink.  But maybe I can adapt your solution.

 I used this when I compiled my Python 2.5 on my mac, and
 it seemed to work ;-)
 
 I'm now using the python.org binary distribution though and that seems to
 contain a working readline as well ?

I'll try that too.

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


Re: Python, readline and OS X

2007-02-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 James Stroud [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  I have installed Python 2.5 on my new Intel Mac but I can't for the life 
  of me get readline to work.  I have libreadline installed, I've tried 
  copying readline.so from my Python 2.3 installation into 2.5, I've 
  searched the web, and no joy.  Could someone please give me a clue?
  
  rg
 
 Where have you installed libreadline?

/usr/local/lib

 Is LD_LIBRARY_PATH pointing to the directory libreadline.dylib?

It wasn't, but changing it so it did didn't fix the problem.  (I didn't 
try recompiling Python, just running it.  I'll try rebuilding later.)

 Did you install libreadline with fink?

No, I just got the source from the FSF and did ./configure ; make install

 Bash (OSX default) and similar shells use this silly 2 part syntax:
 
LD_LIBRARY_PATH=/sw/lib
export LD_LIBRARY_PATH

Actually you can do it in one line: export LD_LIBRARY_PATH=whatever

:-)

 Do a locate libreadline.dylib and set the LD_LIBRARY_PATH to the 
 containing directory and then
 
make clean
./configure
make
make install
 
 or similar.

I'll give that a whirl.  Thanks.

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


Re: Python, readline and OS X

2007-02-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 James Stroud [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  In article [EMAIL PROTECTED],
   James Stroud [EMAIL PROTECTED] wrote:
  
 Is LD_LIBRARY_PATH pointing to the directory libreadline.dylib?
  
  
  It wasn't, but changing it so it did didn't fix the problem.  (I didn't 
  try recompiling Python, just running it.  I'll try rebuilding later.)
 
 You must re-compile python, starting with configure so that configure 
 can identify the readline libraries. Otherwise it will compile with no 
 readline, which is your current situation

That did the trick.  Thanks!

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


Functions, callable objects, and bound/unbound methods

2006-12-01 Thread Ron Garret
If I do this:

def f(self): print self

class c1: pass

setattr(c1, 'm1', f)

Then f is automagically transmogrified into the appropriate sort of 
method depending on how it is used:

 c1.m1
unbound method c1.f
 c1().m1
bound method c1.f of __main__.c1 instance at 0x51e738
 c1().m1()
__main__.c1 instance at 0x51ec60

Note that m1 gets passed a self argument.

The same automatic transmogrification does not happen if I use an 
callable instance instead of an actual function object:

class callable:
  def __call__(self, *args, **kw): return args, kw

 setattr(c1, 'm2', callable())
 c1.m2
__main__.callable instance at 0x51e738
 c1().m2
__main__.callable instance at 0x51e738
 c1().m2()
((), {})

Note that no selfarg has been passed to m2.

The reason I want to do this is that I want to implement a trace 
facility that traces only specific class methods.  I want to say:

trace(c1.m1)

and have c1.m1 be replaced with a wrapper that prints debugging info 
before actually calling the old value of m1.  The reason I want that to 
be an instance of a callable class instead of a function is that I need 
a place to store the old value of the method so I can restore it, and I 
don't want to start building a global data structure because that gets 
horribly ugly, and a callable class is the Right Thing -- if there's a 
way to actually make it work.

Is there?  I tried the obvious things (like making callable inherit from 
function, and adding im_func and im_self attribuetes) but they didn't 
work.

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Functions, callable objects, and bound/unbound methods

2006-12-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Kent Johnson [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  The reason I want to do this is that I want to implement a trace 
  facility that traces only specific class methods.  I want to say:
  
  trace(c1.m1)
  
  and have c1.m1 be replaced with a wrapper that prints debugging info 
  before actually calling the old value of m1.  The reason I want that to 
  be an instance of a callable class instead of a function is that I need 
  a place to store the old value of the method so I can restore it, and I 
  don't want to start building a global data structure because that gets 
  horribly ugly, and a callable class is the Right Thing -- if there's a 
  way to actually make it work.
 
 If the only reason for a callable class is to save a single value (the 
 original function), you could instead store it as an attribute of the 
 wrapper function.

I considered that, and I may yet fall back on it, but 1) I wanted to 
understand how these things worked and 2) I need a way to tell when a 
method has been traced, and isinstance(method, tracer) seems less 
hackish to me than hasattr(method, 'saved_function').

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


Re: Functions, callable objects, and bound/unbound methods

2006-12-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Michele Simionato [EMAIL PROTECTED] wrote:

 Duncan Booth wrote:
  Ron Garret [EMAIL PROTECTED] wrote:
 
   I want to say:
  
   trace(c1.m1)
  
   and have c1.m1 be replaced with a wrapper that prints debugging info
   before actually calling the old value of m1.  The reason I want that
   to be an instance of a callable class instead of a function is that I
   need a place to store the old value of the method so I can restore it,
   and I don't want to start building a global data structure because
   that gets horribly ugly, and a callable class is the Right Thing -- if
   there's a way to actually make it work.
  
   Is there?  I tried the obvious things (like making callable inherit
   from function, and adding im_func and im_self attribuetes) but they
   didn't work.
 
  Read Functions and Methods in
  http://users.rcn.com/python/download/Descriptor.htm
 
  You need to implement a __get__ method on your class.
 
 See also
 
 http://groups.google.com/group/comp.lang.python/browse_frm/thread/d691240a5cfe
 bcdf/93503c5b9c66226e?lnk=gstq=simionato+subclassing+FunctionTypernum=1hl=e
 n#93503c5b9c66226e
 
 for an example and some discussion.
 
  Michele Simionato

Thanks!

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


Re: Is there a reason not to do this?

2006-12-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Carl Banks [EMAIL PROTECTED] wrote:

 The principle behind this is pretty much it was just a language design
 decision.

Yes, and I'm not taking issue with the decision, just pointing out that 
the desire to do things differently is not necessarily perverse.

 P.S. If you want to be truly evil, you could use a class hook to get
 the modifying in-place behavior:
 
 def modify_in_place(name,bases,clsdict):
 cls = globals()[name]
 for attr,val in clsdict.iteritems():
 setattr(cls,attr,val)
 return cls
 
 # Replace second C2 class above with this
 class C2:
 __metaclass__ = modify_in_place
 def m1(self): h()

Doesn't work for me:

 c2  
__main__.C2 instance at 0x51e850
 c2.m1()
G
 class C2:
...   __metaclass__ = modify_in_place
...   def m1(self): print 'Q'
... 
 c2.m1()
G
 C2().m1()
Q

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


Re: Is there a reason not to do this?

2006-12-01 Thread Ron Garret
In article [EMAIL PROTECTED],
 Michele Simionato [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  One of the things I find annoying about Python is that when you make a
  change to a method definition that change is not reflected in existing
  instances of a class (because you're really defining a new class when
  you reload a class definition, not actually redefining it).  So I came
  up with this programming style:
 
  def defmethod(cls):
return lambda (func): type.__setattr__(cls, func.func_name, func)
 
 Why not just ``return lambda func: setattr(cls, func.func_name, func)``
 ?

Because I'm an idiot.  (i.e. yes, that is obviously the right way to do 
it.)

 The only thing I don't like is that all your
 functions/methods will end up begin 'None'.

 I'd rather to be able to use
 the help, so I would write
 
 def defmethod(cls):
 def decorator(func):
 setattr(cls, func.func_name, func)
 return func
 return decorator
 
 @defmethod(C)
 def m1(self, x):pass
 
 help(m1)
 
 
 BTW, for people with a Lisp background I recommend using IPython with
 emacs  and the
 ipython.el mode. It is pretty good, even if not comparable to Slime.
 
  Michele Simionato

Good tips.  Thanks!

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


Is there a reason not to do this?

2006-11-30 Thread Ron Garret

One of the things I find annoying about Python is that when you make a 
change to a method definition that change is not reflected in existing 
instances of a class (because you're really defining a new class when 
you reload a class definition, not actually redefining it).  So I came 
up with this programming style:

def defmethod(cls):
  return lambda (func): type.__setattr__(cls, func.func_name, func)

class c1(object): pass

@defmethod(c1)
def m1(self, x): ...


Now if you redefine m1, existing instances of c1 will see the change.

My question is: is there a reason not to do this?  Does it screw 
something up behind the scenes?  Is it unpythonic?  Why isn't this 
standard operating procedure?

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


Re: Is there a reason not to do this?

2006-11-30 Thread Ron Garret
In article [EMAIL PROTECTED],
 Diez B. Roggisch [EMAIL PROTECTED] wrote:

 Ron Garret schrieb:
  One of the things I find annoying about Python is that when you make a 
  change to a method definition that change is not reflected in existing 
  instances of a class (because you're really defining a new class when 
  you reload a class definition, not actually redefining it).  So I came 
  up with this programming style:
  
  def defmethod(cls):
return lambda (func): type.__setattr__(cls, func.func_name, func)
  
  class c1(object): pass
  
  @defmethod(c1)
  def m1(self, x): ...
  
  
  Now if you redefine m1, existing instances of c1 will see the change.
  
  My question is: is there a reason not to do this?  Does it screw 
  something up behind the scenes?  Is it unpythonic?  Why isn't this 
  standard operating procedure?
 
 What are you doing that needs this permanent redefinition? I like the 
 repl, yet usually - especially when dealing with classes - I write a 
 text file containing code. So, i just run that on a command line again, 
 if I made some changes, recreating whatever objects I want again.
 
 Even if I'd not do that, but used a long-running interpreter inside an 
 IDE (which is what I presume you are doing) - why do you _care_ about 
 the old objects the first place? I mean, you obviously changed the 
 classes for a reason. So, you are not being productive here, but still 
 programming. Which means that you don't _have_ to care about old, 
 unchanged objects too much.
 
 But in the end - it's your code. It will run slower, it looks kinda 
 weird as someone who's reading it has to know what it is for, but if it 
 suits your needs - do it.
 
 Diez

I have two motivations.

First, I'm dealing with some classes whose instances take a long time to 
construct, which makes for a long debug cycle if I have to reconstruct 
them after every code change.

Second, the design just naturally seems to break down that way.  I have 
a library that adds functionality (persistence) to a set of existing 
classes.  The persistence code stores the objects in a relational DB, so 
it's pretty hairy code, and it has nothing to do with the functionality 
that the classes actually provide.  The original classes are useful even 
with the persistence code, and I'm trying to keep things lightweight.

If there's a better way to accomplish all this I'm all ears.

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


Re: Is there a reason not to do this?

2006-11-30 Thread Ron Garret
In article [EMAIL PROTECTED],
 Hendrik van Rooyen [EMAIL PROTECTED] wrote:

  Ron Garret [EMAIL PROTECTED] wrote:
 
 
 
  One of the things I find annoying about Python is that when you make a
  change to a method definition that change is not reflected in existing
  instances of a class (because you're really defining a new class when
  you reload a class definition, not actually redefining it).  So I came
  up with this programming style:
 
 I would have thought that not changing yesterday was the very essence of
 dynamism (dynamicness ??) - but that when you change something - it applies 
 from that point in time forwards...

I don't want to get into a philosophical debate.  I'll just point you to 
CLOS as an example of an object system that already works this way.

 What do you propose to do about the outputs from such classes that have 
 already happened?

The ability to change methods on the fly will be used mainly for 
debugging I expect.

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


Re: Is there a reason not to do this?

2006-11-30 Thread Ron Garret
In article [EMAIL PROTECTED],
 Ron Garret [EMAIL PROTECTED] wrote:

 In article [EMAIL PROTECTED],
  Hendrik van Rooyen [EMAIL PROTECTED] wrote:
 
   Ron Garret [EMAIL PROTECTED] wrote:
  
  
  
   One of the things I find annoying about Python is that when you make a
   change to a method definition that change is not reflected in existing
   instances of a class (because you're really defining a new class when
   you reload a class definition, not actually redefining it).  So I came
   up with this programming style:
  
  I would have thought that not changing yesterday was the very essence of
  dynamism (dynamicness ??) - but that when you change something - it applies 
  from that point in time forwards...
 
 I don't want to get into a philosophical debate.

Actually, I changed my mind.  Consider:

def g(): print 'G'

def h(): print 'H'

def f(): g()

class C1:
  def m1(self): f()

class C2:
  def m1(self): g()

c1 = C1()
c2 = C2()

def f(): h()

class C2:
  def m1(self): h()

c1.m1()  # Prints H
c2.m1()  # Prints G

On what principled basis can you justify two different outputs in this 
case?  Why should I be able to change the definition of f and not have 
to go back and recompile all references to it, but not m1?

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


Re: Is there a reason not to do this?

2006-11-30 Thread Ron Garret
In article [EMAIL PROTECTED],
 Paul McGuire [EMAIL PROTECTED] wrote:

 Carl Banks [EMAIL PROTECTED] wrote in message 
 news:[EMAIL PROTECTED]
 
  A straightforward, Pythonic way to do it would be to create an
  intermediate representation that understands both the existing class
  interfaces and the RDB stuff, but that could lead to synchronizing
  problems and a big hit in performance.  And it's probably a lot of work
  compared to tacking on methods.  OTOH, it could help with hairiness you
  mention.  (I recently did something similar in one of my projects,
  though the intermediary was transient.)
 
 I would second Carl's recommendation that you find some way to persist an 
 interim version of these expensive-to-create objects, so you can quickly 
 load debuggable instances to accelerate your development process.  With 
 luck, you can get by with out-of-the-box marshal/unmarshal using the pickle 
 module.  We've done this several times in my office with objects that an 
 application creates only after some extensive GUI interaction - it just 
 slows down development too much without some quick import of debuggable 
 instances.
 
 Even though this seems like a sidetrack, it's a pretty direct shortcut, 
 without too much unusual technology or design work.

These objects can be parts of huge networks of massively linked data 
structures.  They are in constant flux.  It is not uncommon to hit a bug 
after many minutes, sometimes hours, of computation.  Having to store 
the whole shlemobble after every operation would slow things down by 
orders of magnitude.  And writing code to be clever and only store the 
dirty bits would be a pain in the ass.  I think I'll stick with Plan A.

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


Why doesn't this work?

2006-10-21 Thread Ron Garret
Python 2.3.5 (#1, Jan 30 2006, 13:30:29) 
[GCC 3.3 20030304 (Apple Computer, Inc. build 1819)] on darwin
Type help, copyright, credits or license for more information.
 from datetime import datetime
 class ts(datetime):
...   def __init__(self): pass
... 
 ts()
Traceback (most recent call last):
  File stdin, line 1, in ?
TypeError: function takes at least 3 arguments (0 given)

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


Re: Why doesn't this work?

2006-10-21 Thread Ron Garret
In article [EMAIL PROTECTED],
 Larry Bates [EMAIL PROTECTED] wrote:

 Because datetime is a new-style class:

Ah.

 The Constructor __new__
 
 If you are like me, then you probably always thought of the __init__ method 
 as
 the Python equivalent of what is called a constructor in C++. This isn't the
 whole story.
 
 When an instance of a class is created, Python first calls the __new__ method 
 of
 the class. __new__ is a static method that is called with the class as its 
 first
 argument. __new__ returns a new instance of the class.
 
 The __init__ method is called afterwards to initialize the instance. In some
 situations (think unplickling!), no initialization is performed. Also,
 immutable types like int and str are completely constructed by the __new__
 method; their __init__ method does nothing. This way, it is impossible to
 circumvent immutability by explicitly calling the __init__ method after
 construction.
 
 
 I think what you wanted was:
 
  class ts(datetime):
 ...   def __new__(self): pass
 ...   
  a=ts()
 
 -Larry

Thanks!

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


Re: BaseHTTPServer weirdness

2006-09-12 Thread Ron Garret
In article [EMAIL PROTECTED],
 Steve Holden [EMAIL PROTECTED] wrote:

 I wouldn't necessarily say you are wrong here, It's just that the cgi 
 module has sort of just growed, so it isn't conveniently factyored for 
 reusability in other contexts. Several people (including me) have taken 
 a look at it with a view to possible re-engineering and backed away 
 because of the difficulty of maintaining compatibility. Python 3K will 
 be an ideal oppoertunity to replace it, but until then it's probably 
 going to stay in the same rather messy but working state.

It's not necessary to re-engineer cgi, just cutting and pasting and 
editing the code as I've done would seem to suffice.

But all I'm really looking for here at this point is confirmation that 
I'm not in fact doing something stupid.  In the past I've found that 
nine times out of ten if I find myself wanting to rewrite or add 
something to a Python module it's an indication that I'm doing something 
wrong.

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


BaseHTTPServer weirdness

2006-09-11 Thread Ron Garret
I'm trying to figure out how to use BaseHTTPServer.  Here's my little 
test app:

=

#!/usr/bin/python

from BaseHTTPServer import *

import cgi

class myHandler(BaseHTTPRequestHandler):

  def do_GET(r):
s = ''
try:
  s = cgi.parse_qs(r.rfile.read(int(r.headers.get 
(Content-length))), 1)
except:
  pass

r.send_response(200)
r.send_header(Content-type, text/html)
r.end_headers()
r.wfile.write(
form method=post action=foo
input type=text name=text1 value=
input type=text name=text2 value=
input type=submit
/form %s
 % s)

  def do_POST(r):
r.do_GET()


d = HTTPServer(('', 1024), myHandler)
d.serve_forever()

===

Two questions:

1.  The line:

s = cgi.parse_qs(r.rfile.read(int(r.headers.get(Content-length))), 1)

feels like a horrible hack.  It seems like this would be a better 
alternative:

s = cgi.parse(r.rfile)

but that doesn't actually work.  Why?  What is the Right Way to parse 
form data in a BaseHTTPServer?

2.  Despite the fact that I'm passing a 1 for the keep_blank_values 
argument to cgi.parse_qs, it doesn't actually keep blank values.  Is 
this a bug, or am I doing something wrong?

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: BaseHTTPServer weirdness

2006-09-11 Thread Ron Garret
In article [EMAIL PROTECTED],
 Steve Holden [EMAIL PROTECTED] wrote:

 The normal way is
 
 s = cgi.parse()
 
 since the CGI script sees the client network socket (after consumption 
 of HTTP headers) as its standard input.

Doesn't work.  (I even tried sys.stdin=r.rfile; s=cgi.parse())  Don't 
forget, this is not a CGI script, it's a handler for a BaseHTTPServer.


  2.  Despite the fact that I'm passing a 1 for the keep_blank_values 
  argument to cgi.parse_qs, it doesn't actually keep blank values.  Is 
  this a bug, or am I doing something wrong?
  
 Sounds like a bug, but then since your parsing looks buggy I'm surprised 
 you get anything at all. Try using a keyword argument 
 keep_blank_values=1 just in case the order has changed or something 
 daft. But fix your parsing first.
 
 The other thing to note is that since you are putting a dictionary's 
 string representation out straight into your HTML if there are odd 
 characters in it this may give you strange output in the browser, so you 
 should view the page source to ensure that's not the case. Which it 
 probably isn't ...

I know that's not a problem because it does work when I use parse_qs.  
(I know about escaping HTML and all that, but this is just a little test 
program.)

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


Re: BaseHTTPServer weirdness

2006-09-11 Thread Ron Garret
In article [EMAIL PROTECTED],
 Steve Holden [EMAIL PROTECTED] wrote:

 But basically, you aren't providing a CGI environment, and that's why 
 cgi.parse() isn't working.

Clearly.  So what should I be doing?  Surely I'm not the first person to 
have this problem?

I have managed to work around this for now by copying and modifying the 
code in cgi.parse, but this still feels like a Horrible Hack to me.

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


Re: BaseHTTPServer weirdness

2006-09-11 Thread Ron Garret
In article [EMAIL PROTECTED],
 Steve Holden [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  In article [EMAIL PROTECTED],
   Steve Holden [EMAIL PROTECTED] wrote:
  
  
 But basically, you aren't providing a CGI environment, and that's why 
 cgi.parse() isn't working.
  
  
  Clearly.  So what should I be doing?  Surely I'm not the first person to 
  have this problem?
  
  I have managed to work around this for now by copying and modifying the 
  code in cgi.parse, but this still feels like a Horrible Hack to me.
  
 Let me get this right. You are aware that CGIHTTPServer module exists. 
 But you don't want to use that.

That's right.  I don't want to run CGI scripts.  I don't want to launch 
a new process for every request.  I want all requests handled in the 
server process.

 Instead you want to use your own code.

No, the whole reason I'm asking this question is because I *don't* want 
to write my own code.  It seems to me that the code to do what I want 
ought to be out there (or in there) somewhere and I shouldn't have to 
reinvent this wheel.  But I can't find it.

 So you have ended up duplicating some of the functionality of the cgi 
 library. And it feels like a hack.

Yep.

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


Re: BaseHTTPServer weirdness

2006-09-11 Thread Ron Garret
In article [EMAIL PROTECTED],
 Kent Johnson [EMAIL PROTECTED] wrote:

 Steve Holden wrote:
  Ron Garret wrote:
  In article [EMAIL PROTECTED],
   Steve Holden [EMAIL PROTECTED] wrote:
 
 
  But basically, you aren't providing a CGI environment, and that's why 
  cgi.parse() isn't working.
 
  Clearly.  So what should I be doing?  Surely I'm not the first person to 
  have this problem?
 
  I have managed to work around this for now by copying and modifying the 
  code in cgi.parse, but this still feels like a Horrible Hack to me.
 
  Let me get this right. You are aware that CGIHTTPServer module exists. 
  But you don't want to use that. Instead you want to use your own code. 
  So you have ended up duplicating some of the functionality of the cgi 
  library. And it feels like a hack.
  
  Have I missed anything? :-)
 
 Hey, be nice. Wanting to write a request handler that actually handles a 
 POST request doesn't seem so unreasonable.
 
 Except...when there are about a bazillion Python web frameworks to 
 choose from, why start from BaseHTTPServer? Why not use one of the 
 simpler frameworks like Karrigell or Snakelets or CherryPy?

It may come to that.  I just thought that what I'm trying to do is so 
basic that it ought to be part of the standard library.  I mean, what do 
people use BaseHTTPServer for if you can't parse form input?

 Here is the query-handling code from Karrigell's CustomHTTPServer.py, 
 good at least for a second opinion:
 
  def do_POST(self):
  Begin serving a POST request. The request data must be readable
  on a file-like object called self.rfile
  ctype, pdict = 
 cgi.parse_header(self.headers.getheader('content-type'))
  self.body = cgi.FieldStorage(fp=self.rfile,
  headers=self.headers, environ = {'REQUEST_METHOD':'POST'},
  keep_blank_values = 1, strict_parsing = 1)
  # throw away additional data [see bug #427345]
  while select.select([self.rfile._sock], [], [], 0)[0]:
  if not self.rfile._sock.recv(1):
  break
  self.handle_data()
 
 Here is CherryPy's version from CP 2.1:
 
  # Create a copy of headerMap with lowercase keys because
  # FieldStorage doesn't work otherwise
  lowerHeaderMap = {}
  for key, value in request.headerMap.items():
  lowerHeaderMap[key.lower()] = value
 
  # FieldStorage only recognizes POST, so fake it.
  methenv = {'REQUEST_METHOD': POST}
  try:
  forms = _cpcgifs.FieldStorage(fp=request.rfile,
headers=lowerHeaderMap,
environ=methenv,
keep_blank_values=1)
 
 where _cpcgifs.FieldStorage is cgi.FieldStorage with some extra accessors.

Here's what I actually ended up doing:

def parse(r):
  ctype = r.headers.get('content-type')
  if not ctype: return None
  ctype, pdict = cgi.parse_header(ctype)
  if ctype == 'multipart/form-data':
return cgi.parse_multipart(r.rfile, pdict)
  elif ctype == 'application/x-www-form-urlencoded':
clength = int(r.headers.get('Content-length'))
if maxlen and clength  maxlen:
  raise ValueError, 'Maximum content length exceeded'
return cgi.parse_qs(r.rfile.read(clength), 1)
  else:
return None

which is copied more or less directly from cgi.py.  But it still seems 
to me like this (or something like it) ought to be standardized in one 
of the *HTTPServer.py modules.

But what do I know?

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


Re: BaseHTTPServer weirdness

2006-09-11 Thread Ron Garret
In article [EMAIL PROTECTED],
 Damjan [EMAIL PROTECTED] wrote:

  But basically, you aren't providing a CGI environment, and that's why
  cgi.parse() isn't working.
  
  Clearly.  So what should I be doing? 
 
 Probably you'll need to read the source of cgi.parse_qs (like Steve did) and
 see what it needs from os.environ and then provide that (either in
 os.environ or in a custom environ dictionary).

I ended up just copying and hacking the code.  It was only a dozen lines 
or so.  But it still feels wrong.

 BUT why don't you use WSGI?

Because BaseHTTPServer does everything I need except for this one thing.  
Why use a sledge hammer to squish a gnat?

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


Parsing form input in a BaseHTTPServer

2006-09-01 Thread Ron Garret
I'm write a web server using BaseHTTPServer.  It can't be a CGI because 
it has to do some weird server-push stuff as database updates come in.  
But I still need to process form inputs as if it were a CGI.  But the 
cgi module only works in a CGI environment.  Is there something with the 
equivalent functionality of cgi.FieldStorage for parsing form input in a 
non-CGI environment such as a BaseHTTPServer?  I looked at the cgi 
module code but it looked like it was pretty heavily intertwingled with 
the CGI environment variables.

Thanks,
rg
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: What is Expressiveness in a Computer Language

2006-06-19 Thread Ron Garret
In article [EMAIL PROTECTED],
 Marshall [EMAIL PROTECTED] wrote:

 The conversation I would *really* like to have is the one where we
 discuss what all the differences are, functionally, between the two,
 and what the implications of those differences are, without trying
 to address which approach is right or better, because those are
 dependent on the problem domain anyway, and because I can
 make up my own mind just fine about which one I prefer.
 
 The comp.lang.functional and comp.lang.lisp people are probably
 two of the smartest groups on usenet. (I do not consider myself
 a member of either group.) You wouldn't *think* that conversation
 would be *so* hard to have.

It's hard to have because there's very little to say, which leaves the 
academics without enough to do to try to justify their existence.  This 
is the long and the short of it:

1.  There are mismatches between the desired behavior of code and its 
actual behavior.  Such mismatches are generally referred to as bugs or 
errors (and, occasionally, features).

2.  Some of those mismatches can be detected before the program runs.  
Some can be detected while the program runs.  And some cannot be 
detected until after the program has finished running.

3.  The various techniques for detecting those mismatches impose varying 
degrees of burden upon the programmer and the user.

That's it.  Everything else, including but not limited to quibbling over 
the meaning of the word type, is nothing but postmodernist claptrap.

IMHO of course.

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


Re: WTF? Printing unicode strings

2006-05-19 Thread Ron Garret
In article [EMAIL PROTECTED],
 Serge Orlov [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
I'm using an OS X terminal to ssh to a Linux machine.
  
   In theory it should work out of the box. OS X terminal should set
   enviromental variable LANG=en_US.utf-8, then ssh should transfer this
   variable to Linux and python will know that your terminal is utf-8.
   Unfortunately AFAIK OS X terminal doesn't set that variable and most
   (all?) ssh clients don't transfer it between machines. As a workaround
   you can set that variable on linux yourself . This should work in the
   command line right away:
  
   LANG=en_US.utf-8 python -c print unichr(0xbd)
  
   Or put the following line in ~/.bashrc and logout/login
  
   export LANG=en_US.utf-8
 
  No joy.
 
  [EMAIL PROTECTED]:~$ LANG=en_US.utf-8 python -c print unichr(0xbd)
  Traceback (most recent call last):
File string, line 1, in ?
  UnicodeEncodeError: 'ascii' codec can't encode character u'\xbd' in
  position 0: ordinal not in range(128)
  [EMAIL PROTECTED]:~$
 
 What version of python and what shell do you run? What the following
 commands print:
 
 python -V
 echo $SHELL
 $SHELL --version

[EMAIL PROTECTED]:~$ python -V
Python 2.3.4
[EMAIL PROTECTED]:~$ echo $SHELL
/bin/bash
[EMAIL PROTECTED]:~$ $SHELL --version
GNU bash, version 2.05b.0(1)-release (i386-pc-linux-gnu)
Copyright (C) 2002 Free Software Foundation, Inc.
[EMAIL PROTECTED]:~$
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: WTF? Printing unicode strings

2006-05-19 Thread Ron Garret
In article [EMAIL PROTECTED],
 Serge Orlov [EMAIL PROTECTED] wrote:

 Ron Garret wrote:
  In article [EMAIL PROTECTED],
   Serge Orlov [EMAIL PROTECTED] wrote:
 
   Ron Garret wrote:
  I'm using an OS X terminal to ssh to a Linux machine.

 In theory it should work out of the box. OS X terminal should set
 enviromental variable LANG=en_US.utf-8, then ssh should transfer this
 variable to Linux and python will know that your terminal is utf-8.
 Unfortunately AFAIK OS X terminal doesn't set that variable and most
 (all?) ssh clients don't transfer it between machines. As a workaround
 you can set that variable on linux yourself . This should work in the
 command line right away:

 LANG=en_US.utf-8 python -c print unichr(0xbd)

 Or put the following line in ~/.bashrc and logout/login

 export LANG=en_US.utf-8
   
No joy.
   
[EMAIL PROTECTED]:~$ LANG=en_US.utf-8 python -c print unichr(0xbd)
Traceback (most recent call last):
  File string, line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character u'\xbd' in
position 0: ordinal not in range(128)
[EMAIL PROTECTED]:~$
  
   What version of python and what shell do you run? What the following
   commands print:
  
   python -V
   echo $SHELL
   $SHELL --version
 
  [EMAIL PROTECTED]:~$ python -V
  Python 2.3.4
  [EMAIL PROTECTED]:~$ echo $SHELL
  /bin/bash
  [EMAIL PROTECTED]:~$ $SHELL --version
  GNU bash, version 2.05b.0(1)-release (i386-pc-linux-gnu)
  Copyright (C) 2002 Free Software Foundation, Inc.
  [EMAIL PROTECTED]:~$
 
 That's recent enough. I guess the distribution you're using set LC_*
 variables for no good reason.

Nope:

[EMAIL PROTECTED]:~$ export | grep LC
[EMAIL PROTECTED]:~$ 

 Either unset all enviromental variables
 starting with LC_ and set LANG variable or overide LC_CTYPE variable:
 
 LC_CTYPE=en_US.utf-8 python -c print unichr(0xbd)
 
 Should be working now :)

Nope:

[EMAIL PROTECTED]:~$ LC_CTYPE=en_US.utf-8 python -c print unichr(0xbd)
Traceback (most recent call last):
  File string, line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode character u'\xbd' in 
position 0: ordinal not in range(128)

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


  1   2   >