Re: ANN: Beginning Python (Practical Python 2.0)
In article [EMAIL PROTECTED], Dennis Lee Bieber wrote: [snip] Must be printed on thinner paper... Both run around 600 pages, but the older book is a third thicker... G Heh. Yeah. The new book has more material, too (new chapters, among other things), so I guess the new layout also has an effect. -- Magnus Lie HetlandPreparing to stand by. http://hetland.org-- Microsoft Windows -- http://mail.python.org/mailman/listinfo/python-list
ANN: Beginning Python (Practical Python 2.0)
I guess it has actually been out for a while -- I just haven't received my copies yet... Anyways: My book, Beginning Python: From Novice to Professional (Apress, 2005) is now out. It is an expanded and revised version of Practical Python (Apress, 2002). More information can be found at http://hetland.org/writing/beginning-python Thanks, - Magnus -- Magnus Lie HetlandPreparing to stand by. http://hetland.org-- Microsoft Windows -- http://mail.python.org/mailman/listinfo/python-announce-list Support the Python Software Foundation: http://www.python.org/psf/donations.html
ANN: Beginning Python (Practical Python 2.0)
I guess it has actually been out for a while -- I just haven't received my copies yet... Anyways: My book, Beginning Python: From Novice to Professional (Apress, 2005) is now out. It is an expanded and revised version of Practical Python (Apress, 2002). More information can be found at http://hetland.org/writing/beginning-python Thanks, - Magnus -- Magnus Lie HetlandPreparing to stand by. http://hetland.org-- Microsoft Windows -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 350: Codetags
In article [EMAIL PROTECTED], Terry Hancock wrote: [snip] The terminator is evil. People will hate that. If there are no fields, you should just be able to leave it off. This will have an additional advantage in that many will already have compliant codetags if you leave off this requirement. I heartily agree. I use codetags like these all the time -- *except* that I don't add the at the end. You worry over the need to detect the end of the block, but wouldn't '\n\n' be a much more natural delimiter? I.e.: That would make perfect sense, and is in no way restrictive. # TODO: This is a multi-line todo tag. # You see how I've gone to the next line. # This, on the other hand is an unrelated comment. You can tell it's not # related, because there is an intervening blank line. I think people # do this naturally when writing comments (I know I do -- I'm fairly # certain I've seen other people do it). # # Whereas, as you can see, a mere paragraph break can be represented by # a blank comment line. Indeed. # Whitespace formatting, after all, is VERY PYTHONIC. ;-) # Delimiters on the other hand -- well, we prefer not to mention # the sort of languages that use those, right? ;-) shudder IMO, the syntax could be really simple: One comment (one or more contiguous comment lines) that start with # FOO: (with FOO being any of the tags) is grouped along with the tag. One can dhen optionally add the ... stuff at the end. (Not sure if that would be my preferred syntax for it, but I won't complain as much about that as about the empty '' thing :) -- Magnus Lie Hetland The early bird may get the worm but the second http://hetland.org mouse gets the cheese. -- Willie Nelson -- http://mail.python.org/mailman/listinfo/python-list
Re: Limited XML tidy
In article [EMAIL PROTECTED], Toby White wrote: [snip] I do similar stuff in the new (upcoming) version of Atox (atox.sf.net), which works with potentially ill-formed, partial XML (in the form of PYX events) internally, and can take partial, ill-formed XML as input. The problem is that when the sax handler raises an exception, I can't see how to find out why. What I want to do is for DodgyErrorHandler to do something different depending on where we are in the course of parsing. Is there anyway to get that information back from xml.sax (or indeed from any other sax handler?) What I ended up doing was using an SGML parser (sgmlop) instead. It's highly forgiving (even of illegal entities and the like) but gives me the information I need. Might be worth a look in your app too? Toby -- Magnus Lie Hetland http://hetland.org -- http://mail.python.org/mailman/listinfo/python-list
Python Challenge on BBC
Just saw this on the BBC World program Click Online: http://bbcworld.com/content/template_clickonline.asp?pageid=665co_pageid=6 I must say, I think this is the first time I've heard Python discussed on TV at all... Cool :) (Now maybe I'll have to finish the rest of those P.C. levels... ;) -- Magnus Lie HetlandFall seven times, stand up eight http://hetland.org [Japanese proverb] -- http://mail.python.org/mailman/listinfo/python-list
./pyconfig.h?
It seems that in my Solaris installation, sysconfig.get_config_h_filename() returns './pyconfig.h', which is, of course, in most cases just wrong... :) Shouldn't this return an absolute path (in all cases)? I've use an absolute path in the --prefix of ./configure -- but I guess I was standing in that very directory when compiling; maybe there's some mix-up there? -- Magnus Lie HetlandFall seven times, stand up eight http://hetland.org [Japanese proverb] -- http://mail.python.org/mailman/listinfo/python-list
Re: Positions of regexp groups
In article [EMAIL PROTECTED], Tim Peters wrote: [Magnus Lie Hetland] Just a quick question: Does anyone have a simple way of finding the positions (start, end) of the groups in a regexp match? AFAICS, the re API can only return the contents...? Read the docs for match objects, esp. the start(), end(), and span() methods. Right. I was just now editing the regex-stuff in my book for the second edition, and found that I had, in fact, written about just this behaviour. blush/ Oh, well. I guess it's a feature I don't use much :} Thanks, anyway. -- Magnus Lie HetlandFall seven times, stand up eight http://hetland.org [Japanese proverb] -- http://mail.python.org/mailman/listinfo/python-list
Positions of regexp groups
Just a quick question: Does anyone have a simple way of finding the positions (start, end) of the groups in a regexp match? AFAICS, the re API can only return the contents...? -- Magnus Lie HetlandFall seven times, stand up eight http://hetland.org [Japanese proverb] -- http://mail.python.org/mailman/listinfo/python-list
Re: Pre-PEP: Dictionary accumulator methods
In article [EMAIL PROTECTED], Raymond Hettinger wrote: I would like to get everyone's thoughts on two new dictionary methods: def count(self, value, qty=1): try: self[key] += qty except KeyError: self[key] = qty Yes, yes, YES! *Man*, this would be useful. def appendlist(self, key, *values): try: self[key].extend(values) except KeyError: self[key] = list(values) Woohoo! *Just* as useful. I'd *definitely* use these. Hot 100% sure about the names, though. (add() and append() seem like more natural names -- but they may be confusing, considering their other uses...) +1 on both (possibly allowing for some naming discussion...) -- Magnus Lie Hetland Time flies like the wind. Fruit flies http://hetland.org like bananas. -- Groucho Marx -- http://mail.python.org/mailman/listinfo/python-list
Re: sgmlop: malformed charrefs?
In article [EMAIL PROTECTED], Fredrik Lundh wrote: Magnus Lie Hetland wrote: [snip] with sgmlop 1.1, the following script class entity_handler: def handle_entityref(self, entityref): print ENTITY, repr(entityref) parser = sgmlop.XMLParser() parser.register(entity_handler()) parser.feed(-10;/()=?;) prints: ENTITY '-10' ENTITY '/()=?' OK, thanks. I guess I just wasn't creative enough in my entity naming :) And another thing... For the case where a numeric reference is too high (i.e. it can't be translated into a Unicode character) -- is it possible to ignore it (or replace it, as with encode/decode)? if you don't do anything, it is ignored. if you specify a handle_charref hook, the part between # and ; is passed to that method. I see -- it's just if the default behaviour of transforming it to text kicks in that there is trouble? (That makes sense, of course.) if you have a handle_entityref hook, but no handle_charref, the part between and ; is passed to handle_entityref. Strange. It doesn't seem to work that way for me... Here is an example: .. from xml.parsers.sgmlop import SGMLParser, XMLParser, XMLUnicodeParser class Handler: def handle_data(self, data): print 'DATA', data def handle_entityref(self, data): print 'ENTITY', data for parser in [SGMLParser(), XMLParser(), XMLUnicodeParser()]: parser.register(Handler()) try: parser.feed('#99;') except Exception, e: print e .. When I run this, I get: character reference #x540be3ff; exceeds ASCII range character reference #x540be3ff; exceeds ASCII range character reference #x540be3ff; exceeds sys.maxunicode (0x) If I remove the handle_data, nothing happens. /F -- Magnus Lie Hetland Time flies like the wind. Fruit flies http://hetland.org like bananas. -- Groucho Marx -- http://mail.python.org/mailman/listinfo/python-list
Re: sgmlop: malformed charrefs?
In article [EMAIL PROTECTED], Fredrik Lundh wrote: [snip] are the PyXML folks shipping the latest sgmlop? I don't know. The last history entry marked fl is from 2000-07-05... Perhaps I should just get the effbot version. (And perhaps file a bug report about this behaviour in PyXML.) I'm pretty sure they've forked the code (there's no UnicodeParser in the effbot.org edition), Does it deal with Unicode at all? I.e., can I, for example, feed it a Unicode object? and I have no idea how things work in the fork. I see. -- Magnus Lie Hetland Time flies like the wind. Fruit flies http://hetland.org like bananas. -- Groucho Marx -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 246 revision
In article [EMAIL PROTECTED], S?bastien Boisg?rault wrote: [snip] Agreed. Consistency matters. But precisely because Python looks in the type of the object (and not the object itself), I don't need to explicitely check the type myself: the code adapt = getattr(protocol, '__adapt__') will find the method type(protocol).__adapt__ anyway. This misses the point! :) If you re-read my explanation, perhaps you'll see the difference, but I'll try to state it differently, again using the __call__ example (because it is a very clear case). Let's say we have a class A (a subtype of object, say) which implements a __call__ method. Now, we call this object (that is, the class-object) in order to create instances. Your approach (described in your paragraph above) would be: call = getattr(A, '__call__') a = call() Now, this is clearly wrong. A.__call__ is *not* what we want to call here; that is, after all, only meant to define the behavior of *instances* (i.e., the behavior of a(), in this case). What we *do* want to call is object.__call__ -- and the only way of getting that here, would be the equivalent of this: call = getattr(type(A), '__call__') a = call() So there is a need to *explicitly* bypass the attributes of the object itself and do a lookup *directly* in its type when looking for special methods (as opposed to normal methods). [snip] Finally, the code adapt = getattr(protocol, '__adapt__') would work: 1. if protocol is the instance of a class that implements __adapt__, Not if the instance itself has an attribute/method with the name __adapt__, in which case your code (again, erroneously IMO) would use that. 2. if protocol is a class that implements __adapt__. Yes, but then it would use protocol.__adapt__ -- which you don't want, unless you want to break consistency. This would be like using protocol.__call__ to instantiate protocol (which is *not* how things work). [snip] Agreed. But I'd like to use the classes directly :) ... and you're right it is mainly a matter of taste. I feel that a class *is* a kind of protocol ... Yes, I can agree with you there. But I don't see any problems adapting objects to classes... The problem lies in using an objects own attributes as special methods (in this case, the attributes of a class object). Buuut... Then again, a foolish consistency is the hobgoblin of little minds -- or something. I guess if it is useful to use the __adapt__ method of a class in order to adapt objects to it, then one could certainly argue that it's worth breaking the rule that applies to other magic methods... Have you read the BDFL's Python Optional Typechecking Redux ? Yes. (http://www.artima.com/weblogs/viewpost.jsp?thread=89161) It's usage of adapt assumes that a class is a protocol, so I guess that it does not work with the new version of PEP 246. Why not? There's nothing wrong with classes (or anything else) being protocols...? AFAIK, the current version of the PEP was specifically rewritten in order to fit the BDFL blog (as stated in the PEP). [snip] I don't quite see the conflict (between the blog and the PEP) here... -- Magnus Lie Hetland Time flies like the wind. Fruit flies http://hetland.org like bananas. -- Groucho Marx -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 246 revision
In article [EMAIL PROTECTED], [EMAIL PROTECTED] wrote: I had a look at the new reference implementation of PEP 246 (Object Adaptation) and I feel uneasy with one specific point of this new version. I don't fully understand why it checks if *the type of* the protocol has a method __adapt__: ... # (c) then check if protocol.__adapt__ exists likes obj adapt = getattr(type(protocol), '__adapt__', None) ... As a consequence of this change, you can't define a protocol as a class that implements __adapt__ anymore. How about an instance of such a class? class Protocol(object): def __adapt__(self, obj): ... If you instantiate this class, the object's type will have the __adapt__ attribute... This is the way it works with other special methods (i.e. __foo__-methods) in Python, too. Instead of looking in the object (or class) in question, Python checks the *type* of the object (or class). That's the general rule -- no reason to make an exception here. (In fact, there is every reason *not* to make an exception, IMO.) A good example of why this makes sense is the __call__ method. Imagine what would happen if Python looked for this in the object itself, instead of in the type of the object... Now imagine we defined this class: class Foo(object): def __call__(self): print Howdy! If, under the new lookup rule, we tried to instantiate this class, we'd get: foo = Foo() Howdy! ... and no instance. We're calling the Foo-object, and the __call__-method we defined gets called. Instead, of course, Python has the wisdom to check the *type* of the object for such special calls -- and thus uses object.__call__ instead, which (obviously) instantiates the class just like we want it to. So: The scenario needn't be as complex as in your example, as long as you use instances instead of classes as protocols. (I guess the case could be made for using classes as protocols, but I suspect the case would be mainly syntactical...) - M -- Magnus Lie Hetland Time flies like the wind. Fruit flies http://hetland.org like bananas. -- Groucho Marx -- http://mail.python.org/mailman/listinfo/python-list