Re: Catching exceptions from Python 2.4 to 3.x

2012-11-16 Thread Cameron Simpson
On 17Nov2012 03:12, Steven D'Aprano  
wrote:
| Oh for the day I can drop support for Python 2.4 and 2.5... 
| 
| 
| I have some code that needs to run in any version of Python from 2.4 
| onwards. Yes, it must be a single code base.
| 
| I wish to catch an exception and bind the exception to a name.
| 
| In Python 2.6 onwards, I can do:
| 
| try:
| something()
| except Exception as err:
| process(err)
| 
| But in 2.4 and 2.5 "as err" gives me a SyntaxError, and I have to write:
| 
| try:
| something()
| except Exception, err:
| process(err)
| 
| 
| Is there some other trick to grab the current exception from inside an 
| except block?

sys.exc_info ?
-- 
Cameron Simpson 

Peeve:  Going to our favorite breakfast place, only to find that they were
hit by a car...AND WE MISSED IT.
- Don Baldwin, 
-- 
http://mail.python.org/mailman/listinfo/python-list


Catching exceptions from Python 2.4 to 3.x

2012-11-16 Thread Steven D'Aprano
Oh for the day I can drop support for Python 2.4 and 2.5... 


I have some code that needs to run in any version of Python from 2.4 
onwards. Yes, it must be a single code base.

I wish to catch an exception and bind the exception to a name.

In Python 2.6 onwards, I can do:

try:
something()
except Exception as err:
process(err)

But in 2.4 and 2.5 "as err" gives me a SyntaxError, and I have to write:

try:
something()
except Exception, err:
process(err)


Is there some other trick to grab the current exception from inside an 
except block?


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


Re: StandardError in Python 2 -> 3

2012-11-16 Thread Ian Kelly
On Fri, Nov 16, 2012 at 6:30 PM, Steven D'Aprano
 wrote:
> Does anyone use StandardError in their own code? In Python 2, I normally
> inherit from StandardError rather than Exception. Should I stop and just
> inherit from Exception in both 2 and 3?

According to the docs, StandardError is for built-in exceptions, and
user-defined exceptions are meant to inherit from Exception.

http://docs.python.org/2/library/exceptions.html#exceptions.Exception
-- 
http://mail.python.org/mailman/listinfo/python-list


StandardError in Python 2 -> 3

2012-11-16 Thread Steven D'Aprano
The exception hierarchy in Python 3 is shallower than in Python 2.

Here is a partial list of exceptions in Python 2:


BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
  +-- StandardError
  |+-- AttributeError
  |+-- ImportError
  |+-- NameError
  |+-- TypeError
  |+-- ValueError 
  +-- Warning

and the same again in Python 3:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
  +-- AttributeError
  +-- ImportError
  +-- NameError
  +-- SystemError
  +-- TypeError
  +-- ValueError
  +-- Warning


Note that StandardError is gone. 

Does anyone use StandardError in their own code? In Python 2, I normally 
inherit from StandardError rather than Exception. Should I stop and just 
inherit from Exception in both 2 and 3?


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


Re: latin1 and cp1252 inconsistent?

2012-11-16 Thread Ian Kelly
On Fri, Nov 16, 2012 at 5:33 PM, Nobody  wrote:
> If you need to support either, you can parse it as ISO-8859-1 then
> explicitly convert C1 codes to their Windows-1252 equivalents as a
> post-processing step, e.g. using the .translate() method.

Or just create a custom codec by taking the one in
Lib/encodings/cp1252.py and modifying it slightly.


>>> import codecs
>>> import cp1252a
>>> codecs.register(lambda n: cp1252a.getregentry() if n == "cp1252a" else None)
>>> b'\x81\x8d\x8f\x90\x9d'.decode('cp1252a')
'♕♖♗♘♙'
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: latin1 and cp1252 inconsistent?

2012-11-16 Thread Nobody
On Fri, 16 Nov 2012 13:44:03 -0800, buck wrote:

> When a user agent [browser] would otherwise use a character encoding given
> in the first column [ISO-8859-1, aka latin1] of the following table to
> either convert content to Unicode characters or convert Unicode characters
> to bytes, it must instead use the encoding given in the cell in the second
> column of the same row [windows-1252, aka cp1252].

It goes on to say:

The requirement to treat certain encodings as other encodings according
to the table above is a willful violation of the W3C Character Model
specification, motivated by a desire for compatibility with legacy
content. [CHARMOD]

IOW: Microsoft's "embrace, extend, extinguish" strategy has been too
successful and now we have to deal with it. If HTML content is tagged as
using ISO-8859-1, it's more likely that it's actually Windows-1252 content
generated by someone who doesn't know the difference.

Given that the only differences between the two are for code points which
are in the C1 range (0x80-0x9F), which should never occur in HTML, parsing
ISO-8859-1 as Windows-1252 should be harmless.

If you need to support either, you can parse it as ISO-8859-1 then
explicitly convert C1 codes to their Windows-1252 equivalents as a
post-processing step, e.g. using the .translate() method.

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


Re: latin1 and cp1252 inconsistent?

2012-11-16 Thread Ian Kelly
On Fri, Nov 16, 2012 at 4:27 PM,   wrote:
> They are indeed undefined: ftp://std.dkuug.dk/JTC1/sc2/wg3/docs/n411.pdf
>
> """ The shaded positions in the code table correspond
> to bit combinations that do not represent graphic
> characters. Their use is outside the scope of
> ISO/IEC 8859; it is specified in other International
> Standards, for example ISO/IEC 6429.

It gets murkier than that.  I don't want to spend time hunting down
the relevant documents, so I'll just quote from Wikipedia:

"""
In 1992, the IANA registered the character map ISO_8859-1:1987, more
commonly known by its preferred MIME name of ISO-8859-1 (note the
extra hyphen over ISO 8859-1), a superset of ISO 8859-1, for use on
the Internet. This map assigns the C0 and C1 control characters to the
unassigned code values thus provides for 256 characters via every
possible 8-bit value.
"""

http://en.wikipedia.org/wiki/ISO/IEC_8859-1#History

>> You can use a non-strict error handling scheme to prevent the error.
>> >>> b'hello \x81 world'.decode('cp1252', 'replace')
>> 'hello \ufffd world'
>
> This creates a non-reversible encoding, and loss of data, which isn't 
> acceptable for my application.

Well, what characters would you have these bytes decode to,
considering that they're undefined?  If the string is really CP-1252,
then the presence of undefined characters in the document does not
signify "data".  They're just junk bytes, possibly indicative of data
corruption.  If on the other hand the string is really Latin-1, and
you *know* that it is Latin-1, then you should probably forget the
aliasing recommendation and just decode it as Latin-1.

Apparently this Latin-1 -> CP-1252 encoding aliasing is already
commonly performed by modern user agents.  What do IE and Firefox do
when presented with a Latin-1 encoding and undefined CP-1252 codings?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Subprocess puzzle and two questions

2012-11-16 Thread Nobody
On Thu, 15 Nov 2012 20:07:38 -0500, Roy Smith wrote:

>>> gethostbyname() and getaddrinfo() use the NSS (name-service switch)
>> mechanism, which is configured via /etc/nsswitch.conf. Depending upon
>> configuration, hostnames can be looked up via a plain text file
>> (/etc/hosts), Berkeley DB files, DNS, NIS, NIS+, LDAP, WINS, etc.
> 
> Gethostbyname() long predates NSS.

Before NSS there was host.conf, which provided similar functionality
except that the set of mechanisms was fixed (they were built into libc
rather than being dynamically-loaded libraries) and it only applied to
hostnames (NSS is also used for getpwent(), getprotoent(), etc).

> For that matter, I think it even predates DNS (i.e. back to the days
> when /etc/hosts was the *only* way to look up a hostname).
> 
> But, that's a nit.

Indeed; the main point is that gethostbyname() has never been specific to
DNS.

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


Re: latin1 and cp1252 inconsistent?

2012-11-16 Thread Dave Angel
On 11/16/2012 06:27 PM, b...@yelp.com wrote:
> (doublespaced nonsense deleted.  GoogleGropups strikes again.)
> This creates a non-reversible encoding, and loss of data, which isn't
> acceptable for my application. 

So tell us more about your application.  If you have data which is
invalid, and you encode it to some other form, you have to expect that
it won't be reversible.  But maybe your data isn't really characters at
all, and you're just trying to manipulate bytes?

Without a use case, we really can't guess.  The fact that you are
waffling between latin1 and 1252 indicates this isn't really character data.

Also, while you're at it, please specify the Python version and OS
you're on.  You haven't given us any code to guess it from.

-- 

DaveA

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


Re: latin1 and cp1252 inconsistent?

2012-11-16 Thread buck
On Friday, November 16, 2012 2:34:32 PM UTC-8, Ian wrote:
> On Fri, Nov 16, 2012 at 2:44 PM,   wrote:
> 
> > Latin1 has a block of 32 undefined characters.
> 
> 
> These characters are not undefined.  0x80-0x9f are the C1 control
> codes in Latin-1, much as 0x00-0x1f are the C0 control codes, and
> their Unicode mappings are well defined.

They are indeed undefined: ftp://std.dkuug.dk/JTC1/sc2/wg3/docs/n411.pdf

""" The shaded positions in the code table correspond
to bit combinations that do not represent graphic
characters. Their use is outside the scope of
ISO/IEC 8859; it is specified in other International
Standards, for example ISO/IEC 6429.


However it's reasonable for 0x81 to decode to U+81 because the unicode standard 
says: http://www.unicode.org/versions/Unicode6.2.0/ch16.pdf

""" The semantics of the control codes are generally determined by the 
application with which they are used. However, in the absence of specific 
application uses, they may be interpreted according to the control function 
semantics specified in ISO/IEC 6429:1992.


> You can use a non-strict error handling scheme to prevent the error.
> >>> b'hello \x81 world'.decode('cp1252', 'replace')
> 'hello \ufffd world'

This creates a non-reversible encoding, and loss of data, which isn't 
acceptable for my application.
-- 
http://mail.python.org/mailman/listinfo/python-list


'Experimental Design' aka DoE

2012-11-16 Thread Monte Milanuk
Hello,

I'm interested in refining some tests I do for a hobby of mine beyond the
traditional 'one factor at a time' (OFAT) method.  I have been looking at
'design of experiment' (DoE) methods and they look promising.  The problem
is that most of the software packages that aid in the setup and analysis of
this sort of thing are rather expensive (the cheapest is an Excel plugin
that runs ~$250, and they go up from there rapidly).

I've found some limited DoE support in R and SciLab, but I'd like to stick
with Python if possible.  So far though, I haven't been able to find hardly
any mention of the topic, even searching through lists for numpy, scipy,
pydata, statsmodel, etc.

Given the hype that I've always seen about Python being used in science &
engineering fields, it seems like there should be *something* already out
there...

If anyone has any handy links or references I'd greatly appreciate it.

TIA,

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


Re: latin1 and cp1252 inconsistent?

2012-11-16 Thread Ian Kelly
On Fri, Nov 16, 2012 at 2:44 PM,   wrote:
> Latin1 has a block of 32 undefined characters.

These characters are not undefined.  0x80-0x9f are the C1 control
codes in Latin-1, much as 0x00-0x1f are the C0 control codes, and
their Unicode mappings are well defined.

http://tools.ietf.org/html/rfc1345

> Windows-1252 (aka cp1252) fills in 27 of these characters but leaves five 
> undefined: 0x81, 0x8D, 0x8F, 0x90, 0x9D

In CP 1252, these codes are actually undefined.

http://msdn.microsoft.com/en-us/goglobal/cc305145.aspx

> Also, the html5 standard says:
>
> When a user agent [browser] would otherwise use a character encoding given in 
> the first column [ISO-8859-1, aka latin1] of the following table to either 
> convert content to Unicode characters or convert Unicode characters to bytes, 
> it must instead use the encoding given in the cell in the second column of 
> the same row [windows-1252, aka cp1252].
>
> http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#character-encodings-0
>
>
> The current implementation of windows-1252 isn't usable for this purpose (a 
> replacement of latin1), since it will throw an error in cases that latin1 
> would succeed.

You can use a non-strict error handling scheme to prevent the error.

>>> b'hello \x81 world'.decode('cp1252')
Traceback (most recent call last):
  File "", line 1, in 
  File "c:\python33\lib\encodings\cp1252.py", line 15, in decode
return codecs.charmap_decode(input,errors,decoding_table)
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position
6: character maps to 

>>> b'hello \x81 world'.decode('cp1252', 'replace')
'hello \ufffd world'
>>> b'hello \x81 world'.decode('cp1252', 'ignore')
'hello  world'
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: error importing smtplib

2012-11-16 Thread Terry Reedy

On 11/16/2012 2:37 PM, Eric Frederich wrote:

So I inspected the process through /proc//maps
That seemed to show what libraries had been loaded (though there is
probably an easier way to do this).



In any case, I found that if I import smtplib before logging in I see
these get loaded...

 /opt/foo/python27/lib/python2.7/lib-dynload/_ssl.so
 /lib64/libssl.so.0.9.8e

Then after logging in, I see this other .so get loaded...

 /opt/bar/lib64/libssl.so.0.9.7


That version appears to be about a decade old. Why is bar using it?


So that is what happens when when things are well and I don't get any
error messages.
However, when I do the log in first I see the /opt/bar .so file loaded first

 /opt/bar/lib64/libssl.so.0.9.7

Then after importing smtplib I see the other two show up...

 /opt/foo/python27/lib/python2.7/lib-dynload/_ssl.so
 /lib64/libssl.so.0.9.8e


What I know is that hashlib.py imports _hashlib (compilied .c) and that 
the latter wraps libssl, or calls _ssl.so which wraps libssl. In *nix 
this is expected to already be on the system, so in not distributed with 
python. Furthermore, hashlib requires a version recent enough to have 
the latest (best) hash functions. I suspect decade-old 9.9.7 does not 
qualify.


What I don't know is how .so loading and linking works. It seems that 
two version get loaded but linking gets messed up. This reminds me of 
'dll hell' on Windows ;-). I don't know either if modifying the loading 
of ...9.7 in for or bar code could do anything.



So I'm guessing the problem is that after I log in, the process has
a conflicting libssl.so file loaded.
Then when I try to import smtplib it tries getting things from there and
that is where the errors are coming from.

The question now is how do I fix this?


[easy] Do the import before the function call, which is the proper order 
and the one that works.


Remove ...9.7 from bar/lib64/ and have bar use the up-to-date system 
version, like python does. An alternative is to replace ...9.7 with a 
duplicate ...9.8e (and probably better, only load it if there is no 
system version).



What else should I be checking?


Thinking more, you can look at sys.modules, but this does not have any 
info about non-module libraries wrapped by modules, even if the latter 
are C-coded.


--
Terry Jan Reedy

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


latin1 and cp1252 inconsistent?

2012-11-16 Thread buck
Latin1 has a block of 32 undefined characters.
Windows-1252 (aka cp1252) fills in 27 of these characters but leaves five 
undefined: 0x81, 0x8D, 0x8F, 0x90, 0x9D

The byte 0x81 decoded with latin gives the unicode 0x81.
Decoding the same byte with windows-1252 yields a stack trace with 
`UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 0: 
character maps to `

This seems inconsistent to me, given that this byte is equally undefined in the 
two standards.

Also, the html5 standard says:

When a user agent [browser] would otherwise use a character encoding given in 
the first column [ISO-8859-1, aka latin1] of the following table to either 
convert content to Unicode characters or convert Unicode characters to bytes, 
it must instead use the encoding given in the cell in the second column of the 
same row [windows-1252, aka cp1252].

http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#character-encodings-0


The current implementation of windows-1252 isn't usable for this purpose (a 
replacement of latin1), since it will throw an error in cases that latin1 would 
succeed.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a simpler way to modify all arguments in a function before using the arguments?

2012-11-16 Thread Ethan Furman

bruceg113...@gmail.com wrote:

On Thursday, November 15, 2012 11:16:08 PM UTC-5, Ethan Furman wrote:

Emile van Sebille wrote:


Using a decorator works when named arguments are not used. When named 
arguments are used, unexpected keyword error is reported. Is there a 
simple fix?

Extend def wrapper(*args) to handle *kwargs as well
Emile

Code:
-
from functools import wraps
def fix_args(fn):
@wraps(fn)
def wrapper(*args):

so this line ^ becomes

def wrapper(*args, **kwargs):


args = (arg.replace('_', '') for arg in args)

and add a line

for k, v in kwargs:

kwargs[k] = v.replace('_', '')


return fn(*args)

and this line ^ becomes

return fn(*args, **kwargs)


return wrapper



~Ethan~



Ethan,

I tried you code suggestions but got errors.


Right, my 'for k, v in kwargs' should have been 'for k, v in kwargs.items()'

Glad you were able to make it work!

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


Re: Understanding Code

2012-11-16 Thread subhabangalore
On Tuesday, November 13, 2012 4:12:52 PM UTC+5:30, Peter Otten wrote:
> subhabangal...@gmail.com wrote:
> 
> 
> 
> > Dear Group,
> 
> > To improve my code writing I am trying to read good codes. Now, I have
> 
> > received a code,as given below,(apology for slight indentation errors) the
> 
> > code is running well. Now to comprehend the code, I am looking to
> 
> > understand it completely.
> 
> > 
> 
> > class Calculate:
> 
> >   def __init__(self):
> 
> > self.prior = {}
> 
> > self.total = {}
> 
> > self.count = 0
> 
> >   def add(self, cls, obs):
> 
> > self.prior[cls] = self.prior.get(cls, 0) + 1
> 
> > for idx, val in enumerate(obs):
> 
> > key = cls, idx, val
> 
> > self.total[key] = self.total.get(key, 0) + 1
> 
> > self.count += 1
> 
> >   def discr(self, cls, obs):
> 
> > result = self.prior[cls]/self.count
> 
> > for idx, val in enumerate(obs):
> 
> > freq = self.total.get((cls, idx, val), 0)
> 
> > result *= freq/self.prior[cls]
> 
> > return result
> 
> >   def classify(self, obs):
> 
> > candidates = [(self.discr(c, obs), c) for c in self.prior]
> 
> > return max(candidates)[1]
> 
> > 
> 
> > I am not understanding many parts of it, I am understanding many parts of
> 
> > it also.
> 
> > 
> 
> > So I am looking for an exercise what are the things I should know to
> 
> > understand it, (please do not give answers I would get back with the
> 
> > answers in a week and would discuss even how to write better than this).
> 
> 
> 
> Start with running the code for the simplest piece of the class:
> 
> >>> c = Calculate()
> 
> >>> c.add("x", [1,2,3])
> 
> 
> 
> Then inspect the attributes:
> 
> 
> 
> >>> c.prior
> 
> {'x': 1}
> 
> >>> c.total
> 
> {('x', 2, 3): 1, ('x', 1, 2): 1, ('x', 0, 1): 1}
> 
> >>> c.count
> 
> 
> 
> Now read the code for Calculate.add(). Do you understand what
> 
> 
> 
> > self.prior[cls] = self.prior.get(cls, 0) + 1
> 
> 
> 
> does? Experiment with a dict and its get() method in the interactive 
> 
> interpreter. Next to the loop.
> 
> 
> 
> > for idx, val in enumerate(obs):
> 
> > key = cls, idx, val
> 
> > self.total[key] = self.total.get(key, 0) + 1
> 
> > self.count += 1
> 
> 
> 
> Do you understand what enumerate() does? If not read its documentation with
> 
> 
> 
> >>> help(enumerate)
> 
> 
> 
> Do you understand what key looks like? If you don't add a print statement
> 
> 
> 
> > for idx, val in enumerate(obs):
> 
> > key = cls, idx, val
> 
>   print key
> 
> > self.total[key] = self.total.get(key, 0) + 1
> 
> > self.count += 1
> 
> 
> 
> What does
> 
> 
> 
> > self.total[key] = self.total.get(key, 0) + 1
> 
> 
> 
> do? Note that this line is very similar to
> 
> 
> 
> > self.prior[cls] = self.prior.get(cls, 0) + 1
> 
> 
> 
> which you have studied before.
> 
> 
> 
> > self.count += 1
> 
> 
> 
> This like the rest of your class is left as an exercise. The routine is 
> 
> always the same: 
> 
> 
> 
> - break parts that you don't understand into smaller parts
> 
> - consult the documentation on unknown classes, functions, methods, 
> 
> preferrably with help(some_obj) or dir(some_obj)
> 
> - run portions of the code or similar code in the interactive interpreter or 
> 
> with a little throw-away script.
> 
> - add print statements to inspect variables at interesting points in your 
> 
> script.

Dear Sir,

Thank you for your kind guidance.
I tried to do the following exercises,

(i) On dict.get():

>>> tel = {'jack': 4098, 'sape': 4139, 'obama':3059,'blair':3301}
>>> dict.get('obama')

>>> tel.get('obama')
3059

>>> for i in tel:
x1=tel.get(i)
print x1


4139
3301
4098
3059
>>> 
>>> tel.get('blair',0)
3301
>>> 
>>> tel.get('blair',0)+1
3302
>>>  


(ii) On enumerate:
>>> list1=["Man","Woman","Gentleman","Lady","Sir","Madam"]
>>> for i,j in enumerate(list1):
print i,j


0 Man
1 Woman
2 Gentleman
3 Lady
4 Sir
5 Madam
>>> 

(iii) Trying to check the values individually:
>>> class Calculate:
def __init__(self):
self.prior = {}  
self.total = {}  
self.count = 0   
def add(self, cls, obs):
self.prior[cls] = self.prior.get(cls, 0) + 1
for idx, val in enumerate(obs):
key = cls, idx, val
print key
self.total[key] = self.total.get(key, 0) + 1
self.count += 1


>>> x1=Calculate()
>>> x1.add("x", [1,2,3])
('x', 0, 1)
('x', 1, 2)
('x', 2, 3)

>>> class Calculate:

def __init__(self):
self.prior = {}  
self.total = {}  
self.count = 0   

def add(self, cls, obs):
self.prior[cls] = self.prior.get(cls, 0) + 1
for idx, val in enumerate(obs):
key = cls, idx, val
self.total[key] = self.total.get(key

Re: error importing smtplib

2012-11-16 Thread Dieter Maurer
Eric Frederich  writes:

> I created some bindings to a 3rd party library.
> I have found that when I run Python and import smtplib it works fine.
> If I first log into the 3rd party application using my bindings however I
> get a bunch of errors.
>
> What do you think this 3rd party login could be doing that would affect the
> ability to import smtp lib.
>
> Any suggestions for debugging this further.  I am lost.
>
> This works...
>
> import smtplib
> FOO_login()
>
> This doesn't...
>
> FOO_login()
> import smtplib
>
> Errors.
>
 import smtplib
> ERROR:root:code for hash sha224 was not found.
> Traceback (most recent call last):
>   File "/opt/foo/python27/lib/python2.7/hashlib.py", line 139, in 
> globals()[__func_name] = __get_hash(__func_name)
>   File "/opt/foo/python27/lib/python2.7/hashlib.py", line 103, in
> __get_openssl_constructor
> return __get_builtin_constructor(name)
>   File "/opt/foo/python27/lib/python2.7/hashlib.py", line 91, in
> __get_builtin_constructor
> raise ValueError('unsupported hash type %s' % name)
> ValueError: unsupported hash type sha224

>From the error, I suppose it does something bad
for hash registries.

When I have analysed problems with "hashlib" (some time ago,
my memory may not be completely trustworthy), I got the
impression that "hashlib" essentially delegates to the
"openssl" libraries for the real work and especially
the supported hash types. Thus, I suspect that
your "FOO_login()" does something which confuses "openssl".
One potential reason could be that it loads a bad version
of an "openssl" shared library.

I would use the "trace" (shell) command to find out what operating system
calls are executed during "FOO_login()", hoping that one of them
give me a clue.

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


Re: error importing smtplib

2012-11-16 Thread Eric Frederich
So I inspected the process through /proc//maps
That seemed to show what libraries had been loaded (though there is
probably an easier way to do this).

In any case, I found that if I import smtplib before logging in I see these
get loaded...

/opt/foo/python27/lib/python2.7/lib-dynload/_ssl.so
/lib64/libssl.so.0.9.8e

Then after logging in, I see this other .so get loaded...

/opt/bar/lib64/libssl.so.0.9.7

So that is what happens when when things are well and I don't get any error
messages.
However, when I do the log in first I see the /opt/bar .so file loaded first

/opt/bar/lib64/libssl.so.0.9.7

Then after importing smtplib I see the other two show up...

/opt/foo/python27/lib/python2.7/lib-dynload/_ssl.so
/lib64/libssl.so.0.9.8e

So I'm guessing the problem is that after I log in, the process has a
conflicting libssl.so file loaded.
Then when I try to import smtplib it tries getting things from there and
that is where the errors are coming from.

The question now is how do I fix this?




On Thu, Nov 15, 2012 at 4:37 PM, Terry Reedy  wrote:

> On 11/15/2012 1:48 PM, Eric Frederich wrote:
>
>> Thanks for the idea.
>> sys.path was the same before and after the login
>>
>
> Too bad. That seems to be a typical cause of import failure.
>
>
>  What else should I be checking?
>>
>
> No idea. You are working beyond my knowledge. But I might either look at
> the foo-login code carefully, or disable (comment out) parts of it to see
> what makes the import fail.
>
>
> --
> Terry Jan Reedy
>
> --
> http://mail.python.org/**mailman/listinfo/python-list
>
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: editing conf file

2012-11-16 Thread rusi
On Nov 16, 7:08 pm, Roy Smith  wrote:
> These days, if I was writing something that needed a config file and I
> didn't want to do "import settings" for whatever reason, I would go with
> YAML.  It seems to give an attractive mix of:
>
> * supporting complex data structures
> * easy to for humans to hand-edit
> * easy for humans to read
> * safe from code injection attacks

+1 except for a caveat on the last:
Use safe_load and safe_dump.
dump and load are vulnerable to code injection attacks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lazy Attribute

2012-11-16 Thread Demian Brecht

> There is a ready made and well tested lazy decorator at 
> http://pypi.python.org/pypi/lazy. I even has a better name. ;-)

I was ignorantly unaware of this module. You've saved me a few lines of code 
every time I want to achieve lazy loading - thanks :)

> Since people seem to come up with their own implementations on a bi-weekly 
> basis, I am seriously wondering how to improve its visibility. Putting it on 
> PyPI alone does not cut it, apparently.


This was a good start ;)

Demian Brecht
@demianbrecht
http://demianbrecht.github.com




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


Re: Is there a simpler way to modify all arguments in a function before using the arguments?

2012-11-16 Thread bruceg113355
On Thursday, November 15, 2012 11:16:08 PM UTC-5, Ethan Furman wrote:
> Emile van Sebille wrote:
> 
> 
> > 
> 
> >> Using a decorator works when named arguments are not used. When named 
> 
> >> arguments are used, unexpected keyword error is reported. Is there a 
> 
> >> simple fix?
> 
> > 
> 
> > Extend def wrapper(*args) to handle *kwargs as well
> 
> > 
> 
> > Emile
> 
> > 
> 
> >> Code:
> 
> >> -
> 
> >>
> 
> >> from functools import wraps
> 
> >>
> 
> >> def fix_args(fn):
> 
> >> @wraps(fn)
> 
> >> def wrapper(*args):
> 
> so this line ^ becomes
> 
> def wrapper(*args, **kwargs):
> 
> >> args = (arg.replace('_', '') for arg in args)
> 
> and add a line
> 
> for k, v in kwargs:
> 
> kwargs[k] = v.replace('_', '')
> 
> >> return fn(*args)
> 
> and this line ^ becomes
> 
> return fn(*args, **kwargs)
> 
> >> return wrapper
> 
> 
> 
> ~Ethan~


Ethan,

I tried you code suggestions but got errors.
However, this works:

from functools import wraps

def fix_args(fn):
@wraps(fn)
def wrapper(*args, **kwargs): 
args = (arg.replace('_', '') for arg in args)
for kv in kwargs:
kwargs[kv] = kwargs[kv].replace('_', '') 
return fn(*args, **kwargs) 
return wrapper
   
@fix_args
def foo(a1="", a2="", b1="", b2=""):
 print(a1)
 print(a2)
 print(b1)
 print(b2)
 print ""
 

 
foo ('a1a1_x', 'a2a2_x', 'b1b1_x', 'b2b2_x')
foo (a1='a1a1_x', a2='a2a2_x', b1='b1b1_x', b2='b2b2_x') 
foo ('a1a1_x', 'a2a2_x', b1='b1b1_x', b2='b2b2_x') 

Bruce



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


Re: editing conf file

2012-11-16 Thread Roy Smith
 Ulrich Eckhardt  wrote:
> in general importing configuration data by loading and 
> executing code is a questionable approach. The problem is in particular 
> that the code parser is always more strict with the syntax than a 
> configuration file should be. Also, it presents the danger of code 
> injection, especially when exec'ing or importing untrusted code.

chip9munk <"chip9munk[SSSpAm"@gmail.com> wrote:
> huh... ok, the thing is that there will actually be no code in the 
> config file, just some variables and values.. it will be more like a 
> "setting file"... so no execution of the config file is necessary, just 
> getting and setting variables...

I've been using django for the past couple of years, and I have to say 
I'm really addicted to their style of executable config files.  The 
ability to put conditional logic in your settings.py file is extremely 
powerful.  Even simple stuff like:

DEBUG = songza.config['build_type'] != 'production'

adds value.

But, yes, Ulrich is 100% correct that it can lead to code injection 
attacks if you allow reading configs from untrusted sources.  Like all 
powerful tools, it needs to be used with care.

These days, if I was writing something that needed a config file and I 
didn't want to do "import settings" for whatever reason, I would go with 
YAML.  It seems to give an attractive mix of:

* supporting complex data structures
* easy to for humans to hand-edit
* easy for humans to read
* safe from code injection attacks
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: editing conf file

2012-11-16 Thread Tim Chase
On 11/16/12 07:04, Thomas Bach wrote:
> On Fri, Nov 16, 2012 at 01:48:49PM +0100, chip9munk wrote:
>> configparser has four functions: get, getboolean, getfloat and getint.
>>
>> how do I get list from cfg file?!
> 
> AFAIK you have to parse the list yourself. Something like
> 
> my_list = [ s.strip() for s in cp.get('section', 'option').split(',') ]
> 
> if you use a comma as a separator.

For slightly more complex option text, you can use the CSV module to
do the heavy lifting, so if you have something like

  [section]
  option="one, one, one",two,3

then you can have Python give you

  my_list = next(csv.reader([cp.get("section", "option")]))

or alternatively use the shlex module and separate them like shell
options:

  [section]
  option="one, one, one" two 3

then do

  my_list = list(shlex.shlex(cp.get("section", "option")))

Or yet one more way using Python list syntax for literals:

  [section]
  option=["one, one, one", "two", 3]

and get them with

  my_list = ast.literal_eval(cp.get("section", "option))

Lots of fun (and batteries-included) ways depending on how you want
to represent the list in the config file and what sorts of data it
can contain.

-tkc





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


Re: editing conf file

2012-11-16 Thread chip9munk

On 11/16/2012 2:04 PM, Thomas Bach wrote:

On Fri, Nov 16, 2012 at 01:48:49PM +0100, chip9munk wrote:

configparser has four functions: get, getboolean, getfloat and getint.

how do I get list from cfg file?!


AFAIK you have to parse the list yourself. Something like

my_list = [ s.strip() for s in cp.get('section', 'option').split(',') ]

if you use a comma as a separator.


yes i guess this is needed, thanks!


Have a look at YAML if this is not enough for you, as I think lists
are supported there. Haven't had a look myself though, yet.



I will check it out!

Thank you!


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


Re: editing conf file

2012-11-16 Thread chip9munk

On 11/16/2012 2:02 PM, Ulrich Eckhardt wrote:

Am 16.11.2012 13:06, schrieb chip9munk:

I would like to use conf file to get all the variables in my code. And
it works great. I use the following (simple example):

execfile("example.conf", config)
 print config["value1"]

and it works like a charm.


This works, but in general importing configuration data by loading and
executing code is a questionable approach. The problem is in particular
that the code parser is always more strict with the syntax than a
configuration file should be. Also, it presents the danger of code
injection, especially when exec'ing or importing untrusted code.


huh... ok, the thing is that there will actually be no code in the 
config file, just some variables and values.. it will be more like a 
"setting file"... so no execution of the config file is necessary, just 
getting and setting variables...




That said, if you really want full programmability inside that
configuration and are aware of the implications, you can do that. In
that case, I would rather call this a Python module though and instead
"from settings.py import *" to import any setting from this module (this
is similar to exec(), but less hack-ish). I use something similar to
import settings for automated tests, but still wouldn't recommend it for
general use.


thank you for the tip!


If you don't want that, use a configuration file parser instead. Python
comes with one, see the section "13.2 Configuration file parser" at
http://docs.python.org/2/library/, which can both read and write simple
configuration files.


yes I will use it


I should also mention that I use Python 3.. so some of the solutions I
came across are not compatible...


No you don't, Above code clearly uses a print statement instead of a
print function. :P


Yes i do :) i just did not c/p code from my script but from some webpage 
:)) i have print (config["value1"])



Anyhow, concerning the link above, replace the 2 with
a 3 and skip to section 14.2.


thank you i am using configparser... the only problem as i mention in 
another post is that it reads lists as string... so some additional 
parsing is necessary..


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


Re: editing conf file

2012-11-16 Thread Ulrich Eckhardt

Am 16.11.2012 13:06, schrieb chip9munk:

I would like to use conf file to get all the variables in my code. And
it works great. I use the following (simple example):

execfile("example.conf", config)
 print config["value1"]

and it works like a charm.


This works, but in general importing configuration data by loading and 
executing code is a questionable approach. The problem is in particular 
that the code parser is always more strict with the syntax than a 
configuration file should be. Also, it presents the danger of code 
injection, especially when exec'ing or importing untrusted code.


That said, if you really want full programmability inside that 
configuration and are aware of the implications, you can do that. In 
that case, I would rather call this a Python module though and instead 
"from settings.py import *" to import any setting from this module (this 
is similar to exec(), but less hack-ish). I use something similar to 
import settings for automated tests, but still wouldn't recommend it for 
general use.


If you don't want that, use a configuration file parser instead. Python 
comes with one, see the section "13.2 Configuration file parser" at 
http://docs.python.org/2/library/, which can both read and write simple 
configuration files.




I should also mention that I use Python 3.. so some of the solutions I
came across are not compatible...


No you don't, Above code clearly uses a print statement instead of a 
print function. :P Anyhow, concerning the link above, replace the 2 with 
a 3 and skip to section 14.2.


Uli

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


Re: editing conf file

2012-11-16 Thread Thomas Bach
On Fri, Nov 16, 2012 at 01:48:49PM +0100, chip9munk wrote:
> configparser has four functions: get, getboolean, getfloat and getint.
> 
> how do I get list from cfg file?!

AFAIK you have to parse the list yourself. Something like

my_list = [ s.strip() for s in cp.get('section', 'option').split(',') ]

if you use a comma as a separator.

Have a look at YAML if this is not enough for you, as I think lists
are supported there. Haven't had a look myself though, yet.

Regards,
Thomas Bach.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: editing conf file

2012-11-16 Thread chip9munk

On 11/16/2012 1:35 PM, rusi wrote:

And there may be better options (allows nested sections)
http://www.voidspace.org.uk/python/configobj.html



but it does not seem to work with python 3

I have an issue...
configparser has four functions: get, getboolean, getfloat and getint.

how do I get list from cfg file?!

any ideas?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Lazy Attribute

2012-11-16 Thread Stefan H. Holek
On 16.11.2012, at 11:54, Andriy Kornatskyy wrote:

>> Subject: Re: Lazy Attribute
>> From: ste...@epy.co.at
>> Date: Fri, 16 Nov 2012 11:45:32 +0100
>> To: python-list@python.org
>> 
>> On 16.11.2012, at 11:29, Steven D'Aprano wrote:
>> 
>>> I'm very vaguely leaning towards this as the least-worst solution to
>>> invalidating the cached value:
>>> 
>>> refresh(obj, 'attr') # pass the instance and the name
>> 
>> This it exactly how lazy handles invalidation. 
>> http://lazy.readthedocs.org/en/latest/
> 
> @property is a solution to evaluate something that is dynamic. @attribute is 
> good for immutable objects. Even if we assume refresh is a good idea... how I 
> would know when it is valid to `refresh`? What is criteria?
> 
> Andriy

I had to implement invalidation anyway in order to write tests. I decided to 
expose the mechanism to keep users from having to invent their own SHOULD the 
need arise. I was not advocating invalidation in any way with my reply. All I 
wanted was to confirm the "least bad" solution. ;-)

Stefan

-- 
Stefan H. Holek
ste...@epy.co.at

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


Re: editing conf file

2012-11-16 Thread rusi
On Nov 16, 5:15 pm, chip9munk <"chip9munk[SSSpAm"@gmail.com> wrote:
> ok, I've got it:http://docs.python.org/3.1/library/configparser.html
>
> works like a charm!
>
> Sorry for the unnecessary question. :/

Not an issue.

And there may be better options (allows nested sections)
http://www.voidspace.org.uk/python/configobj.html

A more broadbased comparison
http://wiki.python.org/moin/ConfigParserShootout
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: editing conf file

2012-11-16 Thread chip9munk

ok, I've got it:
http://docs.python.org/3.1/library/configparser.html

works like a charm!

Sorry for the unnecessary question. :/



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


editing conf file

2012-11-16 Thread chip9munk

Hi all!

I would like to use conf file to get all the variables in my code. And 
it works great. I use the following (simple example):


execfile("example.conf", config)
print config["value1"]

and it works like a charm.

Now the problem is I do not know how to edit the conf file...
let us say that I calculate something and would like to save it in the 
conf file so that it is set for the next run of some program.


How do I edit a specific value in the conf file? (I would like to avoid 
editing txt if possible)...


I should also mention that I use Python 3.. so some of the solutions I 
came across are not compatible...


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


Re: Lazy Attribute

2012-11-16 Thread Stefan H. Holek
On 15.11.2012, at 20:33, Andriy Kornatskyy wrote:

> A lazy attribute is an attribute that is calculated on demand and only once.
> 
> The post below shows how you can use lazy attribute in your Python class:
> 
> http://mindref.blogspot.com/2012/11/python-lazy-attribute.html
> 
> Comments or suggestions are welcome.

There is a ready made and well tested lazy decorator at 
http://pypi.python.org/pypi/lazy. I even has a better name. ;-)

Since people seem to come up with their own implementations on a bi-weekly 
basis, I am seriously wondering how to improve its visibility. Putting it on 
PyPI alone does not cut it, apparently.

Stefan

-- 
Stefan H. Holek
ste...@epy.co.at

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


RE: Lazy Attribute

2012-11-16 Thread Andriy Kornatskyy

I believe it is not valid relate a lazy attribute as something `cached` since 
it cause confusion (e.g. delete of attribute cause cached item to be 
re-evaluated...), `cached` and `lazy` have completely different semantic 
meaning... however might overlap, as we see.

Andriy



> From: steve+comp.lang.pyt...@pearwood.info
> Subject: Re: Lazy Attribute
> Date: Fri, 16 Nov 2012 10:29:03 +
> To: python-list@python.org
>
> On Thu, 15 Nov 2012 15:46:19 -0700, Ian Kelly wrote:
>
> > Although you don't go into it in the blog entry, what I like about your
> > approach of replacing the descriptor with an attribute is that, in
> > addition to being faster, it makes it easy to force the object to lazily
> > reevaluate the attribute, just by deleting it.
>
> You just lost me right there. That's a poor UI design -- it violates the
> principle of least surprise. If I delete something, it should be deleted.
> Consider your example:
>
>  del p.display_name
>  p.display_name
> > 'Eliza Smith'
>
> That's very surprising. I am not aware of any other name in Python where
> deleting it does not remove the name from the namespace. (It is possible
> with properties, but I haven't ever come across someone who does that.)
>
> I don't have a good solution for invaliding such lazy attributes. Ideally
> we could have a new statement:
>
> refresh obj.attr # or some other name like "invalidate"
>
> but that won't happen. Other alternatives like:
>
> obj.attr.refresh()
> refresh(obj.attr)
>
> can't work because the function will see the result of the attribute
> lookup, not the lazy attribute itself. This won't do:
>
> obj.__class__.attr.refresh()
>
> because it won't know which instance to invalidate, although this could
> work:
>
> obj.__class__.attr.refresh(obj) # but it's ugly
>
> I'm very vaguely leaning towards this as the least-worst solution to
> invalidating the cached value:
>
> refresh(obj, 'attr') # pass the instance and the name
>
>
> --
> Steven
> --
> http://mail.python.org/mailman/listinfo/python-list
  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lazy Attribute

2012-11-16 Thread Stefan H. Holek
On 16.11.2012, at 11:29, Steven D'Aprano wrote:

> I'm very vaguely leaning towards this as the least-worst solution to 
> invalidating the cached value:
> 
> refresh(obj, 'attr')  # pass the instance and the name

This it exactly how lazy handles invalidation. 
http://lazy.readthedocs.org/en/latest/

Stefan

-- 
Stefan H. Holek
ste...@epy.co.at

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


Re: debugging in eclipse

2012-11-16 Thread Steven D'Aprano
On Thu, 15 Nov 2012 17:10:27 -0800, alex23 wrote:

> On Nov 16, 3:05 am, Steven D'Aprano  +comp.lang.pyt...@pearwood.info> wrote:
>> > ``1/0`` is shorter.  ;-)
>>
>> It is also guaranteed to run, unlike assert.
> 
> Only if they actively pass the command line switch to turn it off,

Not necessarily "actively".

On Linux you can set up command aliases, e.g. `alias python=python -O` 
and I dare say there is some equivalent under Windows. Once you have done 
so (which could be many months in the past, and forgotten about) you no 
longer need to actively specify -O to run with optimization on.

> which
> I'd assume someone intentionally using an assertion wouldn't do.

Provided that they know the side-effect of -O, and that the code contains 
an assertion.

Not all code is executed by the same person who wrote it, and not all 
people remember every fine detail about every script they wrote. I 
couldn't possibly tell you what all my scripts do without checking the 
source code.



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


Re: Lazy Attribute

2012-11-16 Thread Steven D'Aprano
On Thu, 15 Nov 2012 15:46:19 -0700, Ian Kelly wrote:

> Although you don't go into it in the blog entry, what I like about your
> approach of replacing the descriptor with an attribute is that, in
> addition to being faster, it makes it easy to force the object to lazily
> reevaluate the attribute, just by deleting it.

You just lost me right there. That's a poor UI design -- it violates the 
principle of least surprise. If I delete something, it should be deleted. 
Consider your example:

 del p.display_name
 p.display_name
> 'Eliza Smith'

That's very surprising. I am not aware of any other name in Python where 
deleting it does not remove the name from the namespace. (It is possible 
with properties, but I haven't ever come across someone who does that.)

I don't have a good solution for invaliding such lazy attributes. Ideally 
we could have a new statement:

refresh obj.attr  # or some other name like "invalidate"

but that won't happen. Other alternatives like:

obj.attr.refresh()
refresh(obj.attr)

can't work because the function will see the result of the attribute 
lookup, not the lazy attribute itself. This won't do:

obj.__class__.attr.refresh()

because it won't know which instance to invalidate, although this could 
work:

obj.__class__.attr.refresh(obj)  # but it's ugly

I'm very vaguely leaning towards this as the least-worst solution to 
invalidating the cached value:

refresh(obj, 'attr')  # pass the instance and the name


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


RE: Lazy Attribute

2012-11-16 Thread Andriy Kornatskyy

This is very minor use case. Unlikely useful to add any checks for None, or 
translate one exception to the other... with pretty much the same outcome: it 
makes sense in objects only.

Thanks.

Andriy


> From: rousl...@msn.com
> Subject: Re: Lazy Attribute
> Date: Fri, 16 Nov 2012 05:12:11 -0500
> To: python-list@python.org
>
> On 11/16/2012 04:32 AM, Rouslan Korneychuk wrote:
> > On 11/16/2012 02:49 AM, Andriy Kornatskyy wrote:
> >>> If accessing the descriptor on the class object has no special
> >>> meaning, then the custom is to return the descriptor object itself, as
> >>> properties do.
> >>
> >> If I would satisfy this, I will be forced to check for None 99.9% of
> >> the use cases (it is not None, being applied to an object). Thus it
> >> behaves as designed.
> >
> > That's not true. You can use a try-except block to return the descriptor
> > object when an AttributeError is raised.
>
> Actually, never mind. I just realized the function has to be called
> before the attribute can be set, which can not-only raise any exception,
> but could potentially have undesired side-effects given a parameter it
> doesn't expect.
> --
> http://mail.python.org/mailman/listinfo/python-list
  
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Lazy Attribute

2012-11-16 Thread Andriy Kornatskyy

Same applies to properties... they are seen as an object attributes.

Thanks.

Andriy



> From: steve+comp.lang.pyt...@pearwood.info
> Subject: Re: Lazy Attribute
> Date: Fri, 16 Nov 2012 09:04:39 +
> To: python-list@python.org
>
> On Fri, 16 Nov 2012 10:49:07 +0300, Andriy Kornatskyy wrote:
>
> > Ian,
> >
> > Thank you for the comments.
> >
> >> The name "attribute" is not very descriptive. Why not "lazy_attribute"
> >> instead?
> >
> > It just shorter and still descriptive.
>
> It is not descriptive. EVERYTHING accessed used dot notation obj.thing is
> an attribute. What makes your "attribute" different from ordinary
> attributes, properties, dynamic attributes calculated with __getattr__,
> methods, etc?
>
>
>
> --
> Steven
> --
> http://mail.python.org/mailman/listinfo/python-list
  
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Lazy Attribute

2012-11-16 Thread Andriy Kornatskyy

from wheezy.core.descriptors import attribute as lazy

@lazy
def display_name...

Thanks.

Andriy Kornatskyy



> Date: Fri, 16 Nov 2012 09:56:41 +0200
> From: s...@mweb.co.za
> To: python-list@python.org
> Subject: Re: Lazy Attribute
>
> On 2012/11/16 09:49 AM, Andriy Kornatskyy wrote:
>
> >> The name "attribute" is not very descriptive. Why not "lazy_attribute" 
> >> instead?
> >
> > It just shorter and still descriptive.
>
> Shorter, but not descriptive.
>
> --
> Regards
> Alex
> --
> http://mail.python.org/mailman/listinfo/python-list
  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lazy Attribute

2012-11-16 Thread Rouslan Korneychuk

On 11/16/2012 04:32 AM, Rouslan Korneychuk wrote:

On 11/16/2012 02:49 AM, Andriy Kornatskyy wrote:

If accessing the descriptor on the class object has no special
meaning, then the custom is to return the descriptor object itself, as
properties do.


If I would satisfy this, I will be forced to check for None 99.9% of
the use cases (it is not None, being applied to an object). Thus it
behaves as designed.


That's not true. You can use a try-except block to return the descriptor
object when an AttributeError is raised.


Actually, never mind. I just realized the function has to be called 
before the attribute can be set, which can not-only raise any exception, 
but could potentially have undesired side-effects given a parameter it 
doesn't expect.

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


Re: Lazy Attribute

2012-11-16 Thread Rouslan Korneychuk

On 11/16/2012 02:49 AM, Andriy Kornatskyy wrote:

If accessing the descriptor on the class object has no special
meaning, then the custom is to return the descriptor object itself, as
properties do.


If I would satisfy this, I will be forced to check for None 99.9% of the use 
cases (it is not None, being applied to an object). Thus it behaves as designed.


That's not true. You can use a try-except block to return the descriptor 
object when an AttributeError is raised.

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


Re: Lazy Attribute

2012-11-16 Thread Steven D'Aprano
On Fri, 16 Nov 2012 10:49:07 +0300, Andriy Kornatskyy wrote:

> Ian,
> 
> Thank you for the comments.
> 
>> The name "attribute" is not very descriptive. Why not "lazy_attribute"
>> instead?
> 
> It just shorter and still descriptive.

It is not descriptive. EVERYTHING accessed used dot notation obj.thing is 
an attribute. What makes your "attribute" different from ordinary 
attributes, properties, dynamic attributes calculated with __getattr__, 
methods, etc?



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


Re: Understanding '?' in regular expressions

2012-11-16 Thread Ian Kelly
On Fri, Nov 16, 2012 at 12:28 AM,   wrote:
> Can someone explain the below behavior please?
>
 re1 = re.compile(r'(?:((?:1000|1010|1020))[ ]*?[\,]?[ ]*?){1,3}')
 re.findall(re_obj,'1000,1020,1000')
> ['1000']
 re.findall(re_obj,'1000,1020, 1000')
> ['1020', '1000']

Try removing the grouping parentheses to see the full strings being matched:

>>> re1 = re.compile(r'(?:(?:1000|1010|1020)[ ]*?[\,]?[ ]*?){1,3}')
>>> re.findall(re1,'1000,1020,1000')
['1000,1020,1000']
>>> re.findall(re1,'1000,1020, 1000')
['1000,1020,', '1000']

In the first case, the regular expression is matching the full string.
 It could also match shorter expressions, but as only the space
quantifiers are non-greedy and there are no spaces to match anyway, it
does not.  With the grouping parentheses in place, only the *last*
value of the group is returned, which is why you only see the last
'1000' instead of all three strings in the group, even though the
group is actually matching three different substrings.

In the second case, the regular expression finds first the '1000,1020'
and then the '1000' as two separate matches.  The reason for this is
the space.  Since the quantifier on the space is non-greedy, it first
tries *not* matching the space, finds that it has a valid match, and
so does not backtrack.  The '1000' is then identified as a separate
match.  As before, with the grouping parentheses in place you see only
the '1020' and the last '1000' because the group only reports the last
substring it matched for that particular match.


> However when I use "[\,]??" instead of "[\,]?" as below, I see a different 
> result
 re2 = re.compile(r'(?:((?:1000|1010|1020))[ ]*?[\,]??[ ]*?){1,3}')
 re.findall(re_obj,'1000,1020,1000')
> ['1000', '1020', '1000']
>
> I am not able to understand what's causing the difference of behavior here, I 
> am assuming it's not 'greediness' if "?"

The difference is the non-greediness of the comma quantifier.  When it
comes time for it to match the comma, because the quantifier is
non-greedy, it first tries *not* matching the comma, whereas before it
first tried to match it.  As with the space above, when the comma is
not matched, it finds that it has a valid match anyway if it just
stops matching immediately.  So it does not need to backtrack, and in
this case it ends up terminating each match early upon the comma and
returning all three numbers as separate matches.

What exactly is it that you're trying to do with this regular
expression?  I suspect that it the solution actually a lot simpler
than you're making it.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Understanding '?' in regular expressions

2012-11-16 Thread Jussi Piitulainen
krishna.k.kish...@gmail.com writes:

> Can someone explain the below behavior please?
> 
> >>> re1 = re.compile(r'(?:((?:1000|1010|1020))[ ]*?[\,]?[ ]*?){1,3}')
> >>> re.findall(re_obj,'1000,1020,1000')
> ['1000']
> >>> re.findall(re_obj,'1000,1020, 1000')
> ['1020', '1000']
> 
> However when I use "[\,]??" instead of "[\,]?" as below, I see a
> different result
> >>> re2 = re.compile(r'(?:((?:1000|1010|1020))[ ]*?[\,]??[ ]*?){1,3}')
> >>> re.findall(re_obj,'1000,1020,1000')
> ['1000', '1020', '1000']

Those re_obj should be re1 and re2, respectively. With that
correction, the behaviour appears to be as you say.

> I am not able to understand what's causing the difference of
> behavior here, I am assuming it's not 'greediness' if "?"

But the greed seems to be the only the difference.

I can't wrap my mind around this (at the moment at least) and I need
to rush away, but may I suggest the removal of all that is not
relevant to the problem at hand. Study these instead:

>>> re.findall(r'(10.0,?){1,3}', '1000,1020,1000')
['1000']
>>> re.findall(r'(10.0,??){1,3}', '1000,1020,1000')
['1000', '1020', '1000']
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lazy Attribute

2012-11-16 Thread Alex Strickland

On 2012/11/16 09:49 AM, Andriy Kornatskyy wrote:


The name "attribute" is not very descriptive. Why not "lazy_attribute" instead?


It just shorter and still descriptive.


Shorter, but not descriptive.

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