Re: cause __init__ to return a different class?

2011-09-14 Thread Ryan Kelly
On 15/09/11 15:35, Chris Rebert wrote:
> On Wed, Sep 14, 2011 at 10:20 PM, Matthew Pounsett
>  wrote:
>> I'm wondering if there's a way in python to cause __init__ to return a class 
>> other than the one initially specified.  My use case is that I'd like to 
>> have a superclass that's capable of generating an instance of a random 
>> subclass.
> 
>> Is there a way to do this?
> 
> Override __new__() instead:
> http://docs.python.org/reference/datamodel.html#object.__new__


The above will do exactly what you want, but it's generally bad style
unless you have a very specific use-case.  Is there a particular reason
you need to "magically" return a subclass, rather than making this
explicit in the code?

To be friendlier to others reading your code, I would consider using a
classmethod to create an alternative constructor:


   class MyBaseClass(object):

@classmethod
def get_random_subclass(cls, *args, **kwds)
subcls = random.choice(cls.__subclasses__())
return subcls(*args, **kwds)


To me, this reads pretty cleanly and makes it obvious that something
unusual is going on:

obj = MyBaseClass.get_random_subclass()

While this hides the intention of the code and would require additional
documentation or comments:

obj = MyBaseClass()  # note: actually returns a subclass!



Just a thought :-)


  Cheers,

Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details





signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


PyCon Australia 2011: Registration Closing Soon!

2011-08-10 Thread Ryan Kelly

Hi Everyone,


Registrations for PyCon Australia 2011 are closing soon!

The conference is just over a week away, so we need final numbers in the
next few days.  If you're planning to attend, please register now!

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:
 
 1. Registration Closing Soon
 2. Coffee
 3. Hosting Panel
 4. More Sponsors Announced
 
Please pass this message on to those you feel may be interested.

 

Registration Closing Soon
=

Full Registrations for the conference will be closing on:

Monday 15th August:  Full Registrations close

That's only five days away, so register now to be sure you don't
miss out.

By request, we will still allow latecomers to register until just before
the conference.  However, since it's after the deadline for catering and
printing, you won't be entitled to a T-shirt or a seat at the conference
dinner:

Thursday 18th August:  Last-Minute Registrations close

Please note that we will *not* accept registrations at the door.

So don't delay, register now at:

http://pycon-au.org/reg



Coffee
==

Thanks to gold sponsors Arclight, we will be able to provide one of the
most requested additions to this year's conference:  Coffee!

Yes, Arclight have generously agreed to provide a free coffee cart for
the duration of the conference.  And there was much rejoicing.



Hosting Panel
=

Saturday evening will feature an informal panel discussion with several
hosting providers.  Come and hear from our hosting panel about why their
services are right for hosting your next Python project! Each group will
give a quick 5 minute spiel, to be followed by a casual drink before the
conference dinner.

This event is happening in a private area at Mr B's pub, across the street
from the SMC. As this is a licensed venue anyone under 18 will have to be
accompanied by a parent or guardian.



More Sponsors Announced
===

We are delighted to confirm that the Django Software Foundation and Ninefold
have joined as Silver sponsors.  In addition, Arclight have upgraded to Gold
Sponsorship, Anchor have agreed to sponsor video production, and GitHub will
be sponsoring internet access.

Thanks once again to the following companies for their continuing support of
Python and for helping to make PyCon Australia 2011 a reality:


Gold:  Google <http://www.google.com.au/>
Gold:  ComOps <http://www.comops.com.au/>
Gold:  Arclight   <http://www.arclight.com.au/>
 
Video:  Anchor<http://anchor.com.au/>

Silver:  Enthought<http://www.enthought.com/>
Silver:  Python Software Foundation   <http://www.python.org/psf/>
Silver:  WingWare <http://www.wingware.com/>
Silver:  Bitbucket by Atlassian   <http://bitbucket.org/>
Silver:  Microsoft<http://www.microsoft.com/>
Silver:  Django Software Foundation   <http://www.djangoproject.com>
Silver:  Ninefold <http://ninefold.com/>

Internet:  GitHub <http://github.com/>


Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.



Ryan Kelly
PyCon Australia 2011



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details

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


Re: import hooks (PEP 302) broken in Python >=2.5?

2011-08-07 Thread Ryan Kelly
On Sun, 2011-08-07 at 11:11 -0700, Josh Haberman wrote:
> When reading about import hooks, I came across a blog entry comment
> that says:
> 
>   One additional thing to note about ihooks is that it's
>   somewhat seriously broken on Python 2.5 and newer and there
>   seems to be little or no interest in fixing it. It's
>   probably worth *always* avoiding when writing new code.
> 
> --http://orestis.gr/blog/2008/12/20/python-import-hooks/#c264
> 
> Does anyone know what this is referring to?  Should I be wary of
> relying on import hooks?

I believe that comment is referring specifically to "ihooks" the stdlib
module, not "import hooks" the general concept as defined in PEP302.
The former pre-dates the later.

I use custom PEP302 loaders all the time and they work fine in at least
2.6, 2.7 and 3.2.


  Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Code War at PyCon Au 2011

2011-08-01 Thread Ryan Kelly


A huge hit at PyCon-Au last year, Code War is back!

Eight teams, onstage knockout rounds of short programming bouts, loud  
crowd...mildly impressive prizes. Any language allowed, no holds  
bared. Think of it like cage fighting for coders.

Originally based on an idea from the book PeopleWare, CodeWar has been  
run in conjunction with the Sydney WebDU conference since 2008 with  
great success. To help share the mayhem we're proud to bring CodeWar  
to PyCon-au 2011, with experienced CodeWar compare Robin Hilliard from  
RocketBoots on the microphone to keep a wry eye on proceedings.
All comers welcome -- no conference ticket required. Come to compete  
or just come to watch. RSVP now!

If you want to enter a team read on...


Tourney Rules
-

The competition will consist of three rounds:
  * 8 teams of 3-5 people
  * 1 laptop per team connected to projector on stage.
  * Rounds are first-past-the-post simple programming challenges
  * Any programming language you want.

We guarantee this won't be mind twisting problems for algorithm heads.  
It will help to have a team with a mix of skills, a clever and/or  
intimidating team name and vocal cheer squad.

For example: "Here is the complete text of pride and prejudice on this  
usb key. Be the first to print out the 7th and 25th sentances that  
contain both 'Elizabeth'and 'Darcy'". See a list of questions from  
recent code war events.

If you're registering a team, the team leader should get 1 team leader  
ticket and the team members a RSVP ticket. Don't forget to bring your  
team and single laptop on the day.

If all the team slots are gone register your standby team in case of a  
no-show.

http://codewarpyconau.eventbrite.com/



Thanks to Dylan Jay of PretaWeb for organising CodeWar this year.


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


PyCon Australia 2011: Registration Back Online

2011-07-27 Thread Ryan Kelly


Hi Everyone,


After a brief hiatus, registrations for PyCon Australia 2011 are back
online!  We have extended some registration deadlines to compensate
for the outage.

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:

 1. Registration Back Online
 2. Call for Volunteers
 3. Convore Group
 4. Thanks to our Sponsors
 
Please pass this message on to those you feel may be interested.

 

Registration Back Online


Registrations are back online after a brief PayPal outage:

http://pycon-au.org/reg


Our apologies to those inconvenienced.  PayPal put a temporary lock on 
our account while they were reviewing our status as a non-profit.  Many
thanks to the hard-working folks at Linux Australia for following up with
all the necessary paperwork.

To compensate for the outage we have adjusted some of our registration
deadlines.  The new dates are:

  1st August:   T-Shirt order finalised
  8th August:   Special dietary needs finalised
  15th August:  Last chance to get tickets!

Remember, registrations must close on Monday the 15th of August, and we will
not be accepting registrations at the door.

So don't delay, register now at:

http://pycon-au.org/reg



Call for Volunteers
===

A community conference such as PyCon just can't run without the work of
many generous volunteers.  If you're interested in helping out, please 
send us an email at:

pycon-...@pycon-au.org


We're currently looking for people to help with the following:

  * Session Staff
(see http://pycon-au.org/2011/helping/session_staff/)

  * Bag Packers
(Friday afternoon; also just general setup of the venue)

  * Registration Desk



Convore Group
=

We've set up a group on Convore for anyone wanting to chat about the 
conference:

https://convore.com/pycon-au-2011/


There are already some good tips from Sydney-siders who know the area
around the venue.  If you have any more, please share!

Don't forget, you can also follow us on Twitter for the latest updates:

https://twitter.com/pyconau
https://twitter.com/#!/search/pyconau



Thanks to our Sponsors
==


Thanks once again to the following companies for their continuing support 
of Python and for helping to make PyCon Australia 2011 a reality:


Gold:  Google  <http://www.google.com.au/>
Gold:  ComOps  <http://www.comops.com.au/>
 
Silver:  Anchor<http://anchor.com.au/>
Silver:  Enthought <http://www.enthought.com/>
Silver:  Python Software Foundation<http://www.python.org/psf/>
Silver:  WingWare  <http://www.wingware.com/>
Silver:  Arclight  <http://www.arclight.com.au/>
Silver:  Bitbucket by Atlassian<http://bitbucket.org/>
Silver:  Microsoft <http://www.microsoft.com/>


Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.
 



Ryan Kelly
PyCon Australia 2011


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


PyCon Australia 2011: Registration Deadlines

2011-07-23 Thread Ryan Kelly


Hi Everyone,


Registrations for PyCon Australia 2011 are closing soon!

The conference is now less than a month away, so we need to start
finalising numbers for shirts, catering and the venue itself.  If 
you're planning to attend, please register now so you don't miss out.

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:
 
 1. Registration Deadlines
 2. More Sponsors Announced
 
Please pass this message on to those you feel may be interested.

 

Registration Deadlines
==

Registrations for the conference will be closing soon, as we have the
following deadlines approaching fast:

  29th July:T-Shirt order finalised
  8th August:   Special dietary needs finalised
  15th August:  Last chance to get tickets!


If you're looking forward to adding a PyCon Au 2011 T-Shirt to your
collection, please complete your registration *this week* so we can get
one in your size.  We will be sending the order through to the printers
based on the sizes requested so far.

If you have special dietary needs (e.g. vegetarian, vegan, gluten-free)
then please complete your registration by Monday the 8th of August.  We
cannot accommodate special dietary orders submitted after this time.

All registrations will close on Monday the 15th of August, so that we 
can confirm final numbers with the venue and catering.  There will be
*no* registrations accepted after this date.

In particular, we will *not* accept registrations at the door.

So don't delay, register now at:

http://pycon-au.org/reg



More Sponsors Announced
===


We are delighted to confirm that Microsoft will be joining us this year
as a Silver Sponsor.  Thanks once again to the following companies for
their continuing support of Python and for helping to make PyCon
Australia 2011 a reality:


Gold:  Google  <http://www.google.com.au/>
Gold:  ComOps  <http://www.comops.com.au/>
 
Silver:  Anchor<http://anchor.com.au/>
Silver:  Enthought <http://www.enthought.com/>
Silver:  Python Software Foundation<http://www.python.org/psf/>
Silver:  WingWare  <http://www.wingware.com/>
Silver:  Arclight  <http://www.arclight.com.au/>
Silver:  Bitbucket by Atlassian<http://bitbucket.org/>
Silver:  Microsoft <http://www.microsoft.com/>


Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.
 



Ryan Kelly
PyCon Australia 2011


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


Re: Inconsistencies between zipfile and tarfile APIs

2011-07-21 Thread Ryan Kelly
On Fri, 2011-07-22 at 01:45 -0400, Terry Reedy wrote:
> On 7/22/2011 12:48 AM, rantingrick wrote:
> > On Jul 21, 11:13 pm, Corey Richardson  wrote:
> >> Excerpts from rantingrick's message of Thu Jul 21 23:46:05 -0400 2011:
> >>
> >>> I may have found the mother of all inconsitency warts when comparing
> >>> the zipfile and tarfile modules. Not only are the API's different, but
> >>> the entry and exits are differnet AND zipfile/tarfile do not behave
> >>> like proper file objects should.
> >>
> >> I agree, actually.
> 
> Hmm. Archives are more like directories than files. Windows, at least, 
> seems to partly treat zipfiles as more or less as such. Certainly, 7zip 
> present a directory interface. So opening a zipfile/tarfile would be 
> like opening a directory, which we normally do not do. On the other 
> hand, I am not sure I like python's interface to directories that much.

Indeed.  Actually, I'd say that archives are more like *entire
filesystems* than either files or directories.

We have a pretty nice ZipFS implementation as part of the PyFilesystem
project:

  http://packages.python.org/fs/


If anyone cares enough to whip up a TarFS implementation it would be
gratefully merged into trunk.  (There may even be the start of one in
the bugtracker somewhere, I don't recall...)


  Cheers,

Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


PyCon Australia 2011: Schedule Announced

2011-07-13 Thread Ryan Kelly
Hi Everyone,


The official schedule for PyCon Australia 2011 has been announced!

This year's conference will feature 3 fantastic keynotes, 7
introductory classroom sessions, and 26 presentations on topics as
diverse as web programming, benchmarking, social issues and API design.

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:
 
 1. Conference Schedule Announced
 2. More Sponsors Announced
 
Please pass this message on to those you feel may be interested.

 

Conference Schedule Announced
=

The detailed conference schedule has been completed and can now be
viewed at the following URL:

http://pycon-au.org/2011/conference/schedule/

There's even an iCal version for you to plug the schedule straight into
your calendar of choice:

http://pycon-au.org/2011/conference/schedule/ical/


Thanks again to all our presenters for some outstanding talk proposals
this year.

  Standard Talks:

A Python on the Couch  (Mark Rees)
Behaviour Driven Development  (Malcolm Tredinnick)
Benchmarking stuff made ridiculously easy  (Tennessee Leeuwenburg)
Bytecode: What, Why, and How to Hack it  (Ryan Kelly)
Developing Scientific Software in Python  (Duncan Gray)
Fun with App Engine 1.5.0  (Greg Darke)
Hosting Python Web Applications  (Graham Dumpleton)
How Python Evolves (and How You Can Help Make It Happen)  (Nick Coghlan)
Infinite 8-bit Platformer  (Chris McCormick)
Networking Libraries in Python.  (Senthil Kumaran)
Pants - Network Programming Made Easy  (Evan Davis)
Say What You Mean: Meta-Programming a Declarative API  (Ryan Kelly)
State of CPython and Python Ecosystem  (Senthil Kumaran)
Sysadmins vs Developers, a take from the other side of the fence  (Benjamin 
Smith)
Teaching Python to the young and impressionable  (Katie Bell)
The NCSS Challenge: teaching programming via automated testing  (Tim 
Dawborn)
Weather field warping using Python.  (Nathan Faggian)
Zookeepr: Home-grown conference management software  (Brianna Laugher)

  In-Depth Talks:

Ah! I see you have the machine that goes "BING"!  (Graeme Cross)
Easy site migration using Diazo and Funnelweb  (Adam Terrey)
How to maintain big app stacks without losing your mind  (Dylan Jay)
Introduction to the Geospatial Web with GeoDjango  (Javier Candeira)
Pyramid: Lighter, faster, better web apps  (Dylan Jay)
Web micro-framework battle  (Richard Jones)

  Discussion Panels:

Panel: Python 3  (Nick Coghlan, Raymond Hettinger, Richard Jones)
Panel: Python in the webs  (Malcolm Tredinnick, Russell Keith-Magee, Dylan 
Jay, Richard Jones)

  Classroom Track:

Python 101+  (Peter Lovett)
Python's dark corners - the bad bits in Python and how to avoid them  
(Peter Lovett)
Confessions of Joe Developer (Danny Greenfeld)
Meta-matters: using decorators for better Python programming  (Graeme Cross)
Python for Science and Engineering, Part 1  (Edward Schofield)
Python for Science and Engineering, Part 2  (Edward Schofield)
The Zen of Python  (Richard Jones)



More Sponsors Announced
===


We are delighted to announce that Bitbucket by Atlassian has joined us
as a Silver Sponsor.  Thanks once again to the following companies for
their continuing support of Python and for helping to make PyCon
Australia 2011 a reality:


Gold:  Google  <http://www.google.com.au/>
Gold:  ComOps  <http://www.comops.com.au/>
 
Silver:  Anchor<http://anchor.com.au/>
Silver:  Enthought <http://www.enthought.com/>
Silver:  Python Software Foundation<http://www.python.org/psf/>
Silver:  WingWare  <http://www.wingware.com/>
Silver:  Arclight  <http://www.arclight.com.au/>
Silver:  Bitbucket by Atlassian<http://bitbucket.org/>


Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.
 



Ryan Kelly
PyCon Australia 2011






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


PyCon Australia 2011: Sprints

2011-06-28 Thread Ryan Kelly
Hi Everyone,


We have confirmed arrangements for two days of Sprints following PyCon
Au this year.  This will be a great opportunity to contribute to the
Python ecosystem under the guidance of experienced developers, so bring
your laptops!

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:
 
 1. Post-Conference Sprints
 2. Thanks to our Sponsors
 
Please pass this message on to those you feel may be interested.

 

Post-Conference Sprints
===

We are taking up the global PyCon tradition of post-conference sprints
this year at PyCon Au.

A Sprint is an opportunity for people to get together and do focussed
development on a project in a fun and welcoming atmosphere. Experienced
developers will be on hand to help newcomers get started, so bring your
laptops and take this opportunity to contribute to the Python ecosystem!

The sprints will be held on the 22nd and 23rd of August at the Sydney
Masonic Center.  Sprint leaders and topics so far include:

   Nick Coghlan:   Python core development
   Audrey Roy/Danny Greenfeld: Django and/or Packaginator
   Richard Jones:  Python Package Index


For more information and updates see:

http://www.pycon-au.org/2011/sprints/

Please register your interest by emailing pycon-...@pycon-au.org.



Thanks to our Sponsors
==

Thanks once again to the following companies for their continuing
support of Python and for helping to make PyCon Australia 2011 a
reality:

Gold:  Google  <http://www.google.com.au/>
Gold:  ComOps  <http://www.comops.com.au/>
 
Silver:  Anchor<http://anchor.com.au/>
Silver:  Enthought <http://www.enthought.com/>
Silver:  Python Software Foundation<http://www.python.org/psf/>
Silver:  WingWare  <http://www.wingware.com/>
Silver:  Superior Recruitment  <http://superiorrecruitment.com.au/>
 

Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.
 



Ryan Kelly
PyCon Australia 2011




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


Re: doing cross platform file work

2011-06-23 Thread Ryan Kelly
On Wed, 2011-06-22 at 10:44 -0700, Tim Hanson wrote:
> Thanks for your responses to my student question about using OS paths in 
> Python.
> 
> For the more general case, I am a Linux user interested in making my scripts 
> platform neutral, which would include Linux, Unix (including Mac), and 
> Windows.  I have looked at the python.org os segment and didn't get an answer.
> 
> Is there a library (bonus would be some tutorial material) for making sure my 
> Linux scripts access files and directories on the other platforms 
> transparently?  I don't need the information immediately, but at some point...

You could go all out and use the PyFilesystem module:

   http://packages.python.org/fs/


This provides a unified API not only for accessing files on your local
disk in a platform-agnostic manner, but also for accessing files in a
zip archive, on a remote server, in memory, and from a variety of other
sources.

Even if you only ever intend to access local files, I find the API
provided by PyFilesystem much nicer than using the various modules from
the stdlib.


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


PyCon Australia 2011: Early Bird Closing Soon

2011-05-28 Thread Ryan Kelly

Hi Everyone,


A reminder that Early Bird Registrations for PyCon Australia 2011 will
be closing soon.  There are only a few days left to get your tickets at
the discounted rate.

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:
 
 1. Early-Bird Registration Closing Soon
 2. Presentations Selected
 3. More Sponsors Announced
 
Please pass this message on to those you feel may be interested.

 

Early-Bird Registration Closing Soon


Early-bird registration closes at the end of May, so you've only got
a few days left to get your tickets at the special discounted rate.

We offer three levels of registration for PyCon Australia 2011.
Registration provides access to two full days of technical content
presented by Python enthusiasts from around the country, as well as the
new classroom track and a seat at the conference dinner.
  
  Full (Early Bird) - $165
This is the registration rate for regular attendees. We are offering
a limited Early Bird rate for the first 50 registrations until the
end of May.

Once the early-bird period ends, Full Registration will be $198.

  Corporate - $440
If your company is paying for you to attend PyCon, please register
at the corporate rate. You'll be helping to keep the conference
affordable for all.

  Student - $44
For students able to present a valid student card we're offering
this reduced rate, which does not include the conference dinner.

All prices include GST.  For more information or to register, please
visit the conference website.

Register here: http://pycon-au.org/reg



Presentations Selected
==

We have had a fantastic response to our Call For Proposals this year.
While the detailed talk schedule is still being finalised, we are
pleased to announce that the following presentations have been selected
for the conference:

  Standard Talks:

A Python on the Couch  (Mark Rees)
Behaviour Driven Development  (Malcolm Tredinnick)
Benchmarking stuff made ridiculously easy  (Tennessee Leeuwenburg)
Bytecode: What, Why, and How to Hack it  (Ryan Kelly)
Developing Scientific Software in Python  (Duncan Gray)
Fun with App Engine 1.5.0  (Greg Darke)
Hosting Python Web Applications  (Graham Dumpleton)
How Python Evolves (and How You Can Help Make It Happen)  (Nick Coghlan)
Infinite 8-bit Platformer  (Chris McCormick)
Networking Libraries in Python.  (Senthil Kumaran)
Pants - Network Programming Made Easy  (Evan Davis)
Say What You Mean: Meta-Programming a Declarative API  (Ryan Kelly)
State of CPython and Python Ecosystem  (Senthil Kumaran)
Sysadmins vs Developers, a take from the other side of the fence  (Benjamin 
Smith)
Teaching Python to the young and impressionable  (Katie Bell)
The NCSS Challenge: teaching programming via automated testing  (Tim 
Dawborn)
Weather field warping using Python.  (Nathan Faggian)
Zookeepr: Home-grown conference management software  (Brianna Laugher)

  In-Depth Talks:

Ah! I see you have the machine that goes "BING"!  (Graeme Cross)
Easy site migration using Diazo and Funnelweb  (Adam Terrey)
How to maintain big app stacks without losing your mind  (Dylan Jay)
Introduction to the Geospatial Web with GeoDjango  (Javier Candeira)
Panel: Python 3  (Richard Jones)
Panel: Python in the webs  (Richard Jones)
Pyramid: Lighter, faster, better web apps  (Dylan Jay)
Web micro-framework battle  (Richard Jones)

  Classroom Track:

Meta-matters: using decorators for better Python programming  (Graeme Cross)
Python 101+  (Peter Lovett)
Python's dark corners - the bad bits in Python and how to avoid them  
(Peter Lovett)
Python for Science and Engineering, Part 1  (Edward Schofield)
Python for Science and Engineering, Part 2  (Edward Schofield)
The Zen of Python  (Richard Jones)


Thanks again to everyone who submitted a proposal.


 
More Sponsors Announced
===

We are delighted to announce that WingWare and Superior Recruitment have
joined as Silver Sponsors.  Thank you to the following companies for
their continuing support of Python and for helping to make PyCon
Australia 2011 a reality:

Gold:  Google  <http://www.google.com.au/>
Gold:  ComOps  <http://www.comops.com.au/>
 
Silver:  Anchor<http://anchor.com.au/>
Silver:  Enthought <http://www.enthought.com/>
Silver:  Python Software Foundation<http://www.python.org/psf/>
Silver:  WingWare  <http://www.wingware.com/>
Silver:  Superior Recruitmen

Re: Python's super() considered super!

2011-05-27 Thread Ryan Kelly
On Fri, 2011-05-27 at 15:05 +, Duncan Booth wrote:
> sturlamolden  wrote:
> > I really don't like the Python 2 syntax of super, as it violates
> > the DRY principle: Why do I need to write super(type(self),self)
> > when super() will do? Assuming that 'self' will always be named
> > 'self' in my code, I tend to patch __builtins__.super like this:
> > 
> > import sys
> > def super():
> > self = sys._getframe().f_back.f_locals['self']
> > return __builtins__.super(type(self),self)
> > 
> > This way the nice Python 3.x syntax can be used in Python 2.x.
> > 
> > 
> Oh dear, you haven't thought this one through.
>
> ...snip...
>
> >>> C().foo()
> ... infinite recursion follows ...
> 
> Oops. There's a reason why Python 2 requires you to be explicit about 
> the class; you simply cannot work it out automatically at run time. 
> Python 3 fixes this by working it out at compile time, but for Python 2 
> there is no way around it.

Oh?  There's not much that can't be done at runtime if you're willing to
work hard enough.  Let me propose the following awful awful hack:


  import sys

  _builtin_super = __builtins__.super

  _sentinel = object()

  def _auto_super(typ=_sentinel,type_or_obj=_sentinel):
  """Automagically call correct super() at runtime"""
  #  Infer the correct call if used without arguments.
  if typ is _sentinel:
  # We'll need to do some frame hacking.
  f = sys._getframe(1)
  # Get the first positional argument of the function.
  type_or_obj = f.f_locals[f.f_code.co_varnames[0]]
  # Get the MRO for investigation
  try:
  mro = type_or_obj.__mro__
  except AttributeError:
  try:
  mro = type_or_obj.__class__.__mro__
  except AttributeError:
  raise RuntimeError("super() used with old-style class")
  #  Now, find the class owning the currently-executing method.
  for typ in mro:
  for meth in typ.__dict__.itervalues():
  if not isinstance(meth,type(_auto_super)):
  continue
  if meth.func_code is f.f_code:
  # Aha!  Found you.
  break
  else:
  continue
  break
  else:
  raise RuntimeError("super() called outside a method")
  #  Now just dispatch to builtin super.
  if type_or_obj is not _sentinel:
  return _builtin_super(typ,type_or_obj)
  return _builtin_super(typ)


Now, try is with the following:

class Base(object):
def hello(self,msg):
print "hello", msg

class Sub1(Base):
def hello(self,msg):
print "gunna say it"
super().hello(msg)

class Sub2(Base):
def hello(self,msg):
print "yes I am"
super().hello(msg)

class Diamond(Sub1,Sub2):
def hello(self,msg):
print "here we go..."
super().hello(msg)

d = Diamond()
d.hello("autosuper!")


And you get the expected output:

here we go...
gunna say it
yes I am
hello autosuper!


There may well be some cases where this breaks down, but it seems to do
the right thing in simple cases.


Not that I'm recommending anyone use this, of course...




   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


PyCon Australia 2011: cfp closing soon!

2011-04-28 Thread Ryan Kelly
Hi Everyone,


A reminder that the Call for Proposals for PyCon Australia 2011 will be
closing soon.  We've had some great proposals so far, but there is still
time left and program to fill.

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21. See below for more
information and updates on:

1. Call For Proposals
2. More Sponsors Announced

Please pass this message on to those you feel may be interested.



Call For Proposals
==

The deadline for proposal submission is the 2nd of May.
That's only a few days away!

We are looking for proposals for talks on all aspects of Python
programming from novice to advanced levels; applications and frameworks,
or how you have been involved in introducing Python into your
organisation. We're especially interested in short presentations that
will teach conference-goers something new and useful. Can you show
attendees how to use a module? Explore a Python language feature?
Package an application?

We welcome first-time speakers; we are a community conference and we
are eager to hear about your experience. If you have friends or
colleagues who have something valuable to contribute, twist their arms
to tell us about it! Please also forward this Call for Proposals to
anyone that you feel may be interested.

The earlier you submit your proposal, the more time we will have to
review and give you feedback before the program is finalised.

Speakers receive free registration for the conference, including a seat
at the conference dinner.  Don't miss out, submit your proposal today! 

http://pycon-au.org/cfp



More Sponsors Announced
===

We are delighted to announce that ComOps has joined as a Gold Sponsor.
Thank you to the following companies for their continuing support of
Python and for helping to make PyCon Australia 2011 a reality:


   Gold:  Google  <http://www.google.com.au/>
   Gold:  Microsoft   <http://www.microsoft.com.au/>
   Gold:  ComOps  <http://www.comops.com.au/>

   Silver:  Anchor<http://anchor.com.au/>
   Silver:  Enthought <http://www.enthought.com/>
   Silver:  Python Software Foundation<http://www.python.org/psf/>


Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.




   Ryan Kelly
   PyCon Australia 2011





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


Re: Read-write lock for Python

2011-04-28 Thread Ryan Kelly
On Thu, 2011-04-28 at 07:02 -0700, Geoff Bache wrote:
> Hi all,
> 
> I currently find myself needing a Python read-write lock. I note that
> there is none in the standard library, but googling "python read-write
> lock" quickly produced 6 different competing examples, including two
> languishing patch proposals for the standard library.
> 
> I can always pick a random one and hope for the best, but I was hoping
> someone here might have a tip for one that has been used and debugged
> and is likely to work.

I wrote and have used the "SHLock" class in threading2 which should do
what you need.  Don't know about "likely to work" but if it doesn't, I'd
like to hear about it so I can fix it :-)

  `pip install threading2`


  Cheers,

Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: minimal python27.dll?

2011-04-27 Thread Ryan Kelly
On Wed, 2011-04-27 at 22:06 +0200, Martin v. Loewis wrote:
> Am 27.04.2011 12:43, schrieb est:
> > Hi guys,
> > 
> > I need to ship python runtime environment package on Windows, if I
> > want to stripping unnessasery functions from python27.dll to make it
> > as small as possible(and perhaps finally UPX it), which parts of
> > python27.dll do you think can be removed?
> > 
>
> I'd rather go for a static build of Python, and let the linker figure
> out what's needed.

I have vague recollections that pythonXY.dll could not be statically
linked on Windows, or that doing so causes some serious loss of
functionality.  Was this ever true, and is it still?


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


PyCon Australia 2011: registrations now open

2011-04-20 Thread Ryan Kelly
Hi Everyone,


I'm pleased to announce that registrations are now open for PyCon
Australia 2011.

PyCon Australia is Australia's only conference dedicated exclusively to
the Python programming language, and will be held at the Sydney Masonic
Center over the weekend of August 20 and 21.  See below for more
information and updates on:

1. Registration is now open
2. Classroom Track
3. Call For Proposals deadline approaching
4. Sponsors Announced

Please pass this message on to those you feel may be interested.



Registration Is Now Open


We offer three levels of registration for PyCon Australia 2011.
Registration provides access to two full days of technical content
presented by Python enthusiasts from around the country, as well as the
new classroom track and a seat at the conference dinner.

We are currently offering a limited number of early-bird tickets, but
get in quick because they are selling fast! 

  Corporate - $440
If your company is paying for you to attend PyCon, please register
at the corporate rate. You'll be helping to keep the conference
affordable for all.
  
  Full (Early Bird) - $165
This is the registration rate for regular attendees. We are offering
a limited Early Bird rate for the first 50 registrations until the
end of May.

  Student - $44
For students able to present a valid student card we're offering
this reduced rate, which does not include the conference dinner.

All prices include GST.  For more information or to register, please
visit the conference website.

Register here: http://pycon-au.org/reg



Classroom Track
===

In addition to the standard technical talks, this year's conference
will feature a "Classroom Track" designed specifically for tutorial
style presentations.

If you need to get up to speed on some of the latest language features
and tools, this will be a great opportunity to learn fast in a
supportive environment.



Call For Proposals
==

We've had some great initial responses to the Call For Proposals, but
there's still time left and plenty of program to fill.

Remember, the deadline for proposal submission is the 2nd of May.
That's just under two weeks away!

We are looking for proposals for talks on all aspects of Python
programming from novice to advanced levels; applications and frameworks,
or how you have been involved in introducing Python into your
organisation. We're especially interested in short presentations that
will teach conference-goers something new and useful. Can you show
attendees how to use a module? Explore a Python language feature?
Package an application?

We welcome first-time speakers; we are a community conference and we
are eager to hear about your experience. If you have friends or
colleagues who have something valuable to contribute, twist their arms
to tell us about it! Please also forward this Call for Proposals to
anyone that you feel may be interested.

The earlier you submit your proposal, the more time we will have to
review and give you feedback before the program is finalised.

Speakers receive free registration for the conference, including a seat
at the conference dinner.  Don't miss out, submit your proposal today! 

http://pycon-au.org/cfp




Sponsors Announced
==

We are happy to announce our first set of sponsors.  Thank you to the
following companies for their continuing support of Python and for
helping to make PyCon Australia 2011 a reality:


   Gold:  Google  <http://www.google.com.au/>
   Gold:  Microsoft   <http://www.microsoft.com.au/>

   Silver:  Anchor<http://anchor.com.au/>
   Silver:  Enthought <http://www.enthought.com/>
   Silver:  Python Software Foundation<http://www.python.org/psf/>


Thanks also to Linux Australia, who provide the overarching legal and
organisational structure for PyCon Australia.



   Ryan Kelly
   PyCon Australia 2011





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


Re: Pythonic infinite for loop?

2011-04-14 Thread Ryan Kelly
On Fri, 2011-04-15 at 12:34 +1000, Ryan Kelly wrote:
> On Fri, 2011-04-15 at 12:10 +1000, Chris Angelico wrote:
> >
> > 
> > My first draft looks something like this. The input dictionary is
> > called dct, the output list is lst.
> > 
> > lst=[]
> > for i in xrange(1,1000): # arbitrary top, don't like this
> >   try:
> > lst.append(parse_kwdlist(dct["Keyword%d"%i]))
> >   except KeyError:
> > break
> >
> It might be even easier to just iterate through the dictionary keys:
> 
>   for k in sorted(dct.keys()):
>   if k.startswith("Keyword"):
>   lst.append(parse_kwdlist(dct[k]))

Actually sorted() won't work here, since it sorts lexicographically.  So
you'd wind up with "Keyword111" before "Keyword2".  You would have to
sort after extracting the necessary info (assuming order is actually
important in the final list)


   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Pythonic infinite for loop?

2011-04-14 Thread Ryan Kelly
On Fri, 2011-04-15 at 12:10 +1000, Chris Angelico wrote:
> Apologies for interrupting the vital off-topic discussion, but I have
> a real Python question to ask.
> 
> I'm doing something that needs to scan a dictionary for elements that
> have a particular beginning and a numeric tail, and turn them into a
> single list with some processing. I have a function parse_kwdlist()
> which takes a string (the dictionary's value) and returns the content
> I want out of it, so I'm wondering what the most efficient and
> Pythonic way to do this is.
> 
> My first draft looks something like this. The input dictionary is
> called dct, the output list is lst.
> 
> lst=[]
> for i in xrange(1,1000): # arbitrary top, don't like this
>   try:
> lst.append(parse_kwdlist(dct["Keyword%d"%i]))
>   except KeyError:
> break
> 
> I'm wondering two things. One, is there a way to make an xrange object
> and leave the top off? (Sounds like I'm risking the numbers
> evaporating or something.)

There is, use an infinite generator:

  def ints_from(start):
  while True:
  yield start
  start += 1


  for i in ints_from(1):
   ..etc...


But why not just put the while loop inline:

  i = 0
  while True:
  try:
  ...etc...
  except KeyError:
  break
  i += 1

It might be even easier to just iterate through the dictionary keys:

  for k in sorted(dct.keys()):
  if k.startswith("Keyword"):
  lst.append(parse_kwdlist(dct[k]))


>  And two, can the entire thing be turned
> into a list comprehension or something? Generally any construct with a
> for loop that appends to a list is begging to become a list comp, but
> I can't see how to do that when the input comes from a dictionary.

You probably could, but I think it would hurt readability in this case:

  lst = [parse_kwdlist(dct[k]) for k in sorted(dct.keys())
   if k.startswith("Keyword")]


  Cheers,

Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Egos, heartlessness, and limitations

2011-04-13 Thread Ryan Kelly
On Thu, 2011-04-14 at 03:12 +, Steven D'Aprano wrote:
> On Thu, 14 Apr 2011 12:03:15 +1000, Ryan Kelly wrote:
> 
> > On Thu, 2011-04-14 at 11:46 +1000, Chris Angelico wrote:
> >> On Thu, Apr 14, 2011 at 11:29 AM, Ryan Kelly  wrote:
> >> > I weep that your delightful rhetoric is limited to this neglected
> >> > forum, where the guardians of python core deign not to tread, and
> >> > hence denied its rightful place exalted among python's canonical
> >> > lore.
> >> 
> >> Wait... so where do the Python experts hang out?
> > 
> > Don't panic, there are plenty of experts here :-)
> > 
> > It's an oft-cited troll complaint that many python big-wigs (Guido,
> > Raymond H, et al) don't subscribe to python-list.
> 
> Raymond Hettinger frequently posts here, both with interesting code 
> snippets and recipes, and to answer questions.

True.  Sorry Raymond.  You just happened to be the second name that
popped into my head in the "python big-wig" category.

> Personally, I'm glad that most of Python Dev don't hang around here. We 
> are far better off if Python Dev, you know, actually Devs Python, rather 
> than answering (mostly) easy questions and getting stuck in tar-pits.

For the record, I have no personal complaint about anyone's lack of
involvement on python-list.  Just reporting on the perceived state of
affairs.


  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Egos, heartlessness, and limitations

2011-04-13 Thread Ryan Kelly
On Wed, 2011-04-13 at 19:10 -0700, rantingrick wrote:
> On Apr 13, 8:29 pm, Ryan Kelly  wrote:
> > On Wed, 2011-04-13 at 17:39 -0700, rantingrick wrote:
> 
> I would LOVE to improve the doc, however first the student THEN the
> teacher. However in this forsaken land the "teachers" do not exist. We
> are cast off from the elites and left to wither, wandering in dark
> catacombs of source code with many doors but no keys to unlock them.
>
>  [..snip..]
>
> The "elites" have hidden themselves behind an
> impenetrable wall called python-dev. They wish not to speak with the
> peasants.

Funny you should bring that up.  The folks on python-dev are currently
making a substantial push to increase involvement in python core
development through the "Python Mentors" program.

Site here:

http://pythonmentors.com/


To quote from the site:

"""
The mission of the Python Core Mentor Program is to provide an open and
welcoming place to connect students, programmers – and anyone interested
in contributing to the Python Core development. This project is based on
the idea that the best way to welcome new people into any project is a
venue which connects them to a variety of mentors who can assist in
guiding them through the contribution process, including discussions on
lists such as python-dev, and python-ideas, the bug tracker, mercurial
questions, code reviews, etc.
"""

So anyone following along this thread, if you're interested in making a
genuine contribution to python as a language, this is a great time and
place to start.


  Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Egos, heartlessness, and limitations

2011-04-13 Thread Ryan Kelly
On Thu, 2011-04-14 at 11:46 +1000, Chris Angelico wrote:
> On Thu, Apr 14, 2011 at 11:29 AM, Ryan Kelly  wrote:
> > I weep that your delightful rhetoric is limited to this neglected forum,
> > where the guardians of python core deign not to tread, and hence denied
> > its rightful place exalted among python's canonical lore.
> 
> Wait... so where do the Python experts hang out?

Don't panic, there are plenty of experts here :-)

It's an oft-cited troll complaint that many python big-wigs (Guido,
Raymond H, et al) don't subscribe to python-list.

Personally I've never really noticed - even if some of the core devs
don't really hang out here, I've always found python-list full of
helpful and knowledgeable people.

It's also an oft-cited troll conspiracy that Guido hangs out on
python-list and posts under various pseudonyms.  I think it would be
kinda fun if he did...


  Cheers,

 Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Egos, heartlessness, and limitations

2011-04-13 Thread Ryan Kelly
On Wed, 2011-04-13 at 17:39 -0700, rantingrick wrote:
>
> -
> 1. Poor documentation (or lack thereof):
> -
> Everyone knows that dcoumentation is important however at the end of
> the day laziness is the rule of thumb for profesionals and weekend
> teckies alike. But why be a part of any open source community and
> propagate laziness? We must be more strict about doumentation. However
> it seems the age old policies of "it's not what you know, but *who*
> you know" or more correct;y adapted tot he situation at hand..."it's
> not imprtant how well you document a module *unless* you are not a
> goodfella (psst: a memeber of Guido inc).

Oh rr, if only the time you spent formulating such eloquent prose could
be devoted instead to improving the documentation whose state you
bemoan.

I weep that your delightful rhetoric is limited to this neglected forum,
where the guardians of python core deign not to tread, and hence denied
its rightful place exalted among python's canonical lore.


> I have enlightened this group long ago of the
> limitless possibilities of IDLE to be a good primer for our budding
> young programmers however like all my great brain children this one
> has been cast aside like a red headed stepchild.

I can only imagine the hi-jinx that ensure at your yearly great brain
family reunion.


  Ryan 

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is this a safe use of eval?

2011-02-24 Thread Ryan Kelly
On Thu, 2011-02-24 at 20:13 +1100, Ryan Kelly wrote:
> On Thu, 2011-02-24 at 10:48 +0200, Frank Millman wrote:
> > Hi all
> > 
> > I know that the use of 'eval' is discouraged because of the dangers of 
> > executing untrusted code.
> > 
> > Here is a variation that seems safe to me, but I could be missing something.
> > 
> > I have a class, and the class has one or more methods which accept various 
> > arguments and return a result.
> > 
> > I want to accept a method name and arguments in string form, and 'eval' it 
> > to get the result.
> > 
> > Assume I have an instance called my_inst, and a method called 'calc_area', 
> > with arguments w and h.
> > 
> > I then receive my_string  = 'calc_area(100, 200)'.
> > 
> > >>> result = eval('my_inst.{0}'.format(my_string))
> > 
> > This will only work if the string contains a valid method name with valid 
> > arguments.
> > 
> > Can anyone see anything wrong with this?
> 
> Yes.  A serious problem.
>
> 
> But actually it allows all sorts of nasty things.  Watch me open an
> arbitrary file on your system (assuming you have permission of course).
>
> >>> 
> testit('__class__.__mro__[-1].__subclasses__()[58]("/secret/file","w")')
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 2, in testit
>   File "", line 1, in 
> IOError: [Errno 2] No such file or directory: '/secret/file'
> >>>

Just to elaborate a little more.  Once you've got a reference to
'object' the game it pretty much over - you can walk its subclasses to
get to all kinds of nasty things like 'file'.

Since this was a newstyle class, getting to 'object' was easy - it's
always the class's final base class (i.e. __mro__[-1]).

You might think that using an old-style class would save you:

>>> class MyClass:
... pass
... 
>>> inst = MyClass()
>>> inst.__class__.__mro__[-1]
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: class MyClass has no attribute '__mro__'


But there will almost always be a reference to a builtin type hanging
around somewhere.  Builtin types are all newstyle classes, and hence
have 'object' in their mro.  For example:

>>> inst.__dict__.__class__.__mro__[-1]

>>> 

Or perhaps:

>>> inst.__class__.__name__.__class__.__mro__[-1]



It's pretty much impossible to prevent this kind of thing in python.

You might get away with it if you parse the string looking for
suspicious characters e.g. dots.  But that will limit your grammar and I
won't be surprised if there's still a way around it.

> So please, don't do this!  :-)

So what's the alternative?  As suggested by another poster, for simple
cases use the ast.literal_eval function.

For anything more complicated, use PyParsing to generate your own mini
language and interpret it yourself.  It's really pretty simple once you
get in the right head-space.  Try some of the links from this SO post if
you want to start down this path:

   http://stackoverflow.com/questions/1545403/math-expression-evaluation



  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is this a safe use of eval?

2011-02-24 Thread Ryan Kelly
On Thu, 2011-02-24 at 10:48 +0200, Frank Millman wrote:
> Hi all
> 
> I know that the use of 'eval' is discouraged because of the dangers of 
> executing untrusted code.
> 
> Here is a variation that seems safe to me, but I could be missing something.
> 
> I have a class, and the class has one or more methods which accept various 
> arguments and return a result.
> 
> I want to accept a method name and arguments in string form, and 'eval' it 
> to get the result.
> 
> Assume I have an instance called my_inst, and a method called 'calc_area', 
> with arguments w and h.
> 
> I then receive my_string  = 'calc_area(100, 200)'.
> 
> >>> result = eval('my_inst.{0}'.format(my_string))
> 
> This will only work if the string contains a valid method name with valid 
> arguments.
> 
> Can anyone see anything wrong with this?

Yes.  A serious problem.

Here's an example of what you describe:


>>> class MyClass(object):
... def calc_area(self,x,y):
... return 42
... 
>>> inst = MyClass()
>>>
>>> def testit(query):
... return eval("inst.{0}".format(query))
>>>

It works as you expect when used properly:

>>> testit('calc_area(3,4)')
42

But actually it allows all sorts of nasty things.  Watch me open an
arbitrary file on your system (assuming you have permission of course).

First find out how to access the "file" builtin:

>>> testit('__class__.__mro__[-1].__subclasses__().index(file)')
58

Great, plug that in and we're in business:

>>> testit('__class__.__mro__[-1].__subclasses__()[58]("/secret/file","w")')
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in testit
  File "", line 1, in 
IOError: [Errno 2] No such file or directory: '/secret/file'
>>>

So please, don't do this!  :-)


   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: If/then style question

2010-12-16 Thread Ryan Kelly
On Thu, 2010-12-16 at 21:49 +, John Gordon wrote:
> (This is mostly a style question, and perhaps one that has already been
> discussed elsewhere.  If so, a pointer to that discussion will be
> appreciated!)
> 
> When I started learning Python, I wrote a lot of methods that looked like
> this:
> 
> 
>   def myMethod(self, arg1, arg2):
> if some_good_condition:
>   if some_other_good_condition:
> if yet_another_good_condition:
>   do_some_useful_stuff()
>   exitCode = good1
> else:
>   exitCode = bad3
>   else:
> exitCode = bad2
> else:
>   exitCode = bad1
> return exitCode
> 
> 
> But lately I've been preferring this style:
> 
> 
>   def myMethod(self, arg1, arg2):
> if some_bad_condition:
>   return bad1
> elif some_other_bad_condition:
>   return bad2
> elif yet_another_bad_condition:
>   return bad3
> do_some_useful_stuff()
> return good1
> 
> I like this style more, mostly because it eliminates a lot of indentation.
> 
> However I recall one of my college CS courses stating that "one entry,
> one exit" was a good way to write code, and this style has lots of exits.
> 
> Are there any concrete advantages of one style over the other?


"one entry, one exit" has its good points, but it's *way* overquoted and
overused.

Do you raise any exceptions? Do you call any functions that might raise
exceptions?  If so, you've got multiple exit points already.

I think this style a lot more important in a language like C where you
have to be super-careful about cleaning up after yourself.  The single
exit point makes it easier to verify that all cleanup tasks have been
performed.  Assuming you're using "with" or "try-finally" then you just
don't need such guarantees in python.

I'm not a PEP-8 pedant by any means, but I think that the first section
of PEP-8 contains the best advice I've ever read about programming
language style.  In fact, I'm going to quote it right here:



  A Foolish Consistency is the Hobgoblin of Little Minds
  ==
One of Guido's key insights is that code is read much more often than it
is written.  The guidelines provided here are intended to improve the
readability of code and make it consistent across the wide spectrum of
Python code.  As PEP 20 says, "Readability counts".

...snip...

But most importantly: know when to be inconsistent -- sometimes the style
guide just doesn't apply.  When in doubt, use your best judgment.  Look
at other examples and decide what looks best.  And don't hesitate to ask!



In your example, the first style is difficult to read wile the second
style is easy to read.  You don't need any further justification for
preferring the latter.


  Cheers,


 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: performance of tight loop

2010-12-13 Thread Ryan Kelly
On Tue, 2010-12-14 at 08:08 +0100, Ulrich Eckhardt wrote:
> Steven D'Aprano wrote:
> > Replacing "while True" with "while 1" may save a tiny bit of overhead.
> > Whether it is significant or not is another thing.
> 
> Is this the price for an intentional complexity or just a well-known
> optimizer deficiency?

At least on older pythons, you can assign to the name "True" so it's not
possible to optimize that loop - you must look up the name "True" on
each iteration.  For example, in python 2.6 this loop will exit after
one iteration:


>>> while True:
... True = False
...
>>>

To see the difference, take a look at the bytecode python generators for
the type types of loop:


>>> import dis
>>> def while1():
... while 1:
... pass
... 
>>> def whileTrue():
... while True:
... pass
... 
>>> dis.dis(while1)
  2   0 SETUP_LOOP   3 (to 6)

  3 >>3 JUMP_ABSOLUTE3
>>6 LOAD_CONST   0 (None)
  9 RETURN_VALUE
>>>
>>> dis.dis(whileTrue)
  2   0 SETUP_LOOP  12 (to 15)
>>3 LOAD_GLOBAL  0 (True)
  6 JUMP_IF_FALSE4 (to 13)
  9 POP_TOP 

  3  10 JUMP_ABSOLUTE3
>>   13 POP_TOP 
 14 POP_BLOCK
>>   15 LOAD_CONST   0 (None)
 18 RETURN_VALUE
   >>> 


Still, I just can't bring myself to write "while 1" in favour of "while
True" in code.


Python 3 does away with this madness entirely:


>>> while True:
... True = False
... 
  File "", line 2
SyntaxError: assignment to keyword
>>> 

Looking at the bytecode shows that in Python 3, "while 1" and "while
True" are indeed identical.


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Weird try-except vs if behavior

2010-10-15 Thread Ryan Kelly
On Thu, 2010-10-14 at 22:43 -0700, James Matthews wrote:
> Hi,
> 
> I have this code http://gist.github.com/627687 (I don't like pasting
> code into the mailing list).

Yes, but it makes it harder to discuss the ode and makes the archive
that much more useless.  It's only a couple of lines, here ya go:

  def tryway():
  try:
  while True:
  alist.pop()
  except IndexError:
  pass


  def ifway():
  while True:
  if blist == []: 
  break
  else:
  blist.pop()

  if __name__=='__main__':
  alist = range(1000)
  blist = range(1000)
  from timeit import Timer
  print "Testing Try"
  tr = Timer("tryway()","from __main__ import tryway")
  print tr.timeit()
  print "Testing If"
  ir = Timer("ifway()","from __main__ import ifway")
  print ir.timeit()


>  I am wondering why the try except is taking longer. I assume that if
> the IF statement checks every iteration of the loop (1000 times)
> shouldn't it be slower?

You're not measuring what you think.  The way you've structured your
code, "alist" and "blist" are module globals.

Timeit will call the "tryway" function one million times in a loop.  The
first time it works as you expect, popping each element off of "alist"
in turn.  On the other 99 executions, "alist" is already empty
(having been emptied by the first execution) and the IndexError is
raised immediately.

Likewise for the execution of "ifway".

So what you're really measuring is the overhead of catching an exception
versus testing a condition for an *empty* list - no surprise that the
conditional version is faster!

If you re-initialise the list at the beginning of each function, the
try-based version is faster as you expect.  I.e.:

  def tryway(): 
  alist = range(1000) 
  try:
  while True:
  alist.pop()
  except IndexError:
  pass

I get the following times for a thousand iterations (not waiting around
for a million!)

  Testing Try
  0.224129915237
  Testing If
  0.300312995911


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Standardizing RPython - it's time.

2010-10-11 Thread Ryan Kelly
On Mon, 2010-10-11 at 13:01 -0700, John Nagle wrote:
> It may be time to standardize "RPython".
> 
>There are at least three implementations of "RPython" variants - PyPy,
> Shed Skin, and RPython for LLVM.  The first two are up and running.
> There's a theory paper on the subject:
> 
> http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.142.1457&rep=rep1&type=pdf
> 
>All three have somewhat different restrictions:
> 
> PyPy's Rpython:
> http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html
> 
> Shed Skin:
> file:///C:/Users/nagle/AppData/Local/Temp/shedskin-tutorial-0.3.html
> 
> Rpython for LLVM:
> http://code.google.com/p/rpython/
> 
> So a language standardization effort, independent of CPython,
> would be useful.

A similar topic was recently discussed on the pypy-dev mailing list:

  http://codespeak.net/pipermail/pypy-dev/2010q3/006170.html


My interpretation is that the pypy devs are -0 on such a standardisation
effort, as it would give them less flexibility in moulding rpython for
their specific needs.  Adding features to rpython that make it better as
a general-purpose programming language could actually make it *worse* as
a specialised language for building pypy.

OTOH, there does seem to be a growing interest in using rpython as a
stand-alone language.  I've used it for some small projects and it
worked out great.

But the intersection of (people who want rpython as a general-purpose
language) and (people who have the ability to make that happen) seems to
be approximately zero at the moment...


   Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Private variables

2010-09-01 Thread Ryan Kelly
On Thu, 2010-09-02 at 12:06 +1000, Ryan Kelly wrote:
> On Thu, 2010-09-02 at 11:10 +1000, Rasjid Wilcox wrote:
> > Hi all,
> > 
> > I am aware the private variables are generally done via convention
> > (leading underscore), but I came across a technique in Douglas
> > Crockford's book "Javascript: The Good Parts" for creating private
> > variables in Javascript, and I'd thought I'd see how it translated to
> > Python. Here is my attempt.
> > 
> > def get_config(_cache=[]):
> > private = {}
> > private['a'] = 1
> > private['b'] = 2
> > if not _cache:
> > class Config(object):
> > @property
> > def a(self):
> > return private['a']
> > @property
> > def b(self):
> > return private['b']
> > config = Config()
> > _cache.append(config)
> > else:
> > config = _cache[0]
> > return config
> > 
> > >>> c = get_config()
> > >>> c.a
> > 1
> > >>> c.b
> > 2
> > >>> c.a = 10
> > Traceback (most recent call last):
> >   File "", line 1, in 
> > AttributeError: can't set attribute
> > >>> dir(c)
> > ['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
> > '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
> > '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
> > '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']
> > >>> d = get_config()
> > >>> d is c
> > True
> > 
> > I'm not really asking 'is it a good idea' but just 'does this work'?
> > It seems to work to me, and is certainly 'good enough' in the sense
> > that it should be impossible to accidentally change the variables of
> > c.
> > 
> > But is it possible to change the value of c.a or c.b with standard
> > python, without resorting to ctypes level manipulation?
> 
> It's not easy, but it can be done by introspecting the property object
> you created and munging the closed-over dictionary object:
> 
>>>> c = get_config()
>>>> c.a
>1
>>>> c.__class__.__dict__['a'].fget.func_closure[0].cell_contents['a'] = 7
>>>> c.a
>7
>>>> 


Heh, and of course I miss the even more obvious trick of just clobbering
the property with something else:

  >>> c.a
  1
  >>> setattr(c.__class__,"a",7)
  >>> c.a
  7
  >>> 


   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Private variables

2010-09-01 Thread Ryan Kelly
On Thu, 2010-09-02 at 11:10 +1000, Rasjid Wilcox wrote:
> Hi all,
> 
> I am aware the private variables are generally done via convention
> (leading underscore), but I came across a technique in Douglas
> Crockford's book "Javascript: The Good Parts" for creating private
> variables in Javascript, and I'd thought I'd see how it translated to
> Python. Here is my attempt.
> 
> def get_config(_cache=[]):
> private = {}
> private['a'] = 1
> private['b'] = 2
> if not _cache:
> class Config(object):
> @property
> def a(self):
> return private['a']
> @property
> def b(self):
> return private['b']
> config = Config()
> _cache.append(config)
> else:
> config = _cache[0]
> return config
> 
> >>> c = get_config()
> >>> c.a
> 1
> >>> c.b
> 2
> >>> c.a = 10
> Traceback (most recent call last):
>   File "", line 1, in 
> AttributeError: can't set attribute
> >>> dir(c)
> ['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
> '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
> '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
> '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']
> >>> d = get_config()
> >>> d is c
> True
> 
> I'm not really asking 'is it a good idea' but just 'does this work'?
> It seems to work to me, and is certainly 'good enough' in the sense
> that it should be impossible to accidentally change the variables of
> c.
> 
> But is it possible to change the value of c.a or c.b with standard
> python, without resorting to ctypes level manipulation?

It's not easy, but it can be done by introspecting the property object
you created and munging the closed-over dictionary object:

   >>> c = get_config()
   >>> c.a
   1
   >>> c.__class__.__dict__['a'].fget.func_closure[0].cell_contents['a'] = 7
   >>> c.a
   7
   >>> 


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python "why" questions

2010-08-06 Thread Ryan Kelly
On Fri, 2010-08-06 at 22:05 -0500, Default User wrote:
> >From "the emperor's new clothes" department:
> 
> 1)  Why do Python lists start with element [0], instead of element
> [1]?  "Common sense" would seem to suggest that lists should start
> with [1].  

"Common sense" is wrong.  There are many compelling advantages to
numbering from zero instead of one:

  http://lambda-the-ultimate.org/node/1950

> 2)  In Python 3, why is print a function only, so that: print "Hello,
> World" is not okay, but it must be print("Hello, World") instead?
> (Yeah, I know: picky, picky . . . )

The real question is, why was print so special in Python 2 that is can
be called without parentheses?  The answer was "no reason" and it was
fixed in Python 3 to be consistent with the rest of the language.

> 3)  In Python 3, why does 2.0 / 3.0 display as 0., but
> 8 * 3.57 displays as 28.56 (rounded off to 2 decimal places)?  And
> yet, in Python 2.6, 8 * 3.57 displays as 28.559?

Because the code for displaying floats was improved in python 3.  You
can follow the fascinating discussion on issue 7117:

   http://bugs.python.org/issue7117

I can't defend the rounding issues of floating point numbers in general
- it's just "one of those things" that you have to deal with.  But show
me a language where floats don't have this problem.

> And we wonder why kids don't want to learn to program.  

Yeah, obscure language warts, that must be the reason.

Note to self:  DNFTT...


  Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



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


Re: subprocess escaping POpen?!

2010-08-05 Thread Ryan Kelly
On Thu, 2010-08-05 at 12:58 +0100, Chris Withers wrote:
> Jean-Michel Pichavant wrote:
> > You did not redirect stdin, so it is expected you can still read input 
> > from the console. 
> 
> Okay, so if I definitely wanted no input, what should I pass as the 
> stdin parameter to the POpen constructor?

The cross-platform equivalent of /dev/null:

   Popen(...,stdin=open(os.devnull,"r")...)

> > And it looks like svn is writting the credentials 
> > prompt on stderr.
> 
> ...which, as you can see from the code I posted, is piped to STDOUT, 
> which is then PIPE'd through to the calling python so that 
> communicate()'s return value will contain the output.
> 
> As I explained, I can't reproduce this by replacing svn with a simple 
> python script that writes to stderr. So, what is svn doing?

Many programs prompt for auth credentials on the controlling tty instead
of standard input/output.  I believe SSH also does this, which suggests
that it's considered more secure.  No idea why, but I trust the authors
of SSH to know their stuff in this regard.


  Cheers,

 Ryan
-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details


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


Re: sending a file chunk by chunk instead as a whole to a web server

2010-08-02 Thread Ryan Kelly
On Tue, 2010-08-03 at 10:45 +0530, Kushal Kumaran wrote:
> On Mon, Aug 2, 2010 at 12:22 PM, Sanjeeb  wrote:
> > Hi,
> > I have a web client which send a file to a server as multipart form
> > data, the sending of data is from
> > http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/.
> >
> > I dont want to open the whole file to memory(at cliend end) and then
> > send, i just want to send part by part, say chunk of 1024 bytes to the
> > server and then assemble at the server end.
> >
> > Could some one suggest what would be the best way to do this?
> >
> 
> There's no reason why sending the whole file implies reading the whole
> file into memory at one time.  You can just read your desired chunk
> size and send it, then read the next chunk, and so on.  You might have
> to first find the total size to calculate what to set Content-Length
> to.

More concretely, you would restructure the encode_multipart_formdata()
function as a generator, yielding chunks of data to send one at a time.
Something like this:

def post_multipart(host,selector,fields,files):
...snip...
h.endheaders()
for chunk in encode_multipart_formdata_chunks(fields,files):
h.send(chunk)
errcode, errmsg, headers = h.getreply()
return h.file.read()


def encode_multipart_formdata(fields,files):
BOUNDARY = '--ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
for (key, value) in fields:
yield '--' + BOUNDARY
yield 'Content-Disposition: form-data; name="%s"' % key
yield ''
yield value
for (key, filename, value) in files:
yield '--' + BOUNDARY
yield 'Content-Disposition: form-data; name="%s"; filename="%s"' % 
(key, filename)
...etc...
...etc...

There are many improvements to make, but this should get you started.
For example, you'll need to calculate the total content-length rather
than just calling len(body) to obtain it.  That's left as an exercise to
the reader.


Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: A question about the posibility of raise-yield in Python

2010-06-30 Thread Ryan Kelly
On Wed, 2010-06-30 at 16:20 -0700, ru...@yahoo.com wrote:
> On Jun 30, 10:48 am, John Nagle  wrote:
> > On 6/30/2010 12:13 AM, Дамјан Георгиевски wrote:
> >
> > >> A 'raise-yield' expression would break the flow of a program just like
> > >> an exception, going up the call stack until it would be handled, but
> > >> also like yield it would be possible to continue the flow of the
> > >> program from where it was raise-yield-ed.
> >
> >  Bad idea.  Continuing after an exception is generally troublesome.
> > This was discussed during the design phase of Ada, and rejected.
> > Since then, it's been accepted that continuing after an exception
> > is a terrible idea.  The stack has already been unwound, for example.
> >
> >  What you want, in in the situation you describe, is an optional
> > callback, to be called in case of a fixable problem. Then the
> > caller gets control, but without stack unwinding.

I've tried my hand at implementing the "condition/handler/restart"
paradigm of common lisp, which is very similar to what you describe.
You might find it useful:

   http://pypi.python.org/pypi/withrestart/



  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details


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


Re: Lockless algorithms in python (Nothing to do with GIL)

2010-06-28 Thread Ryan Kelly
On Mon, 2010-06-28 at 19:45 -0700, sturlamolden wrote:
> > > Many lockless algorithms that I have looked at thusfar require a
> > > "Compare and Swap" operation. Does python have an equivalent to this?
> > > Is python high level enough that it has something better than this or
> > > it simply doesn't need it?
> 
> Python does have a GIL, and contrary to the title, this has a lot to
> do with the GIL. Specifically, any set of operations protected by the
> GIL are atomic in the CPython interpreter.
> 
> We can therefore get global synchronization 'for free', allowing 'lock
> free' data structures that avoid using threading.Lock, and replaces it
> with, well, nothing. :)
> 
> How to do it (it takes tiny amounts of C or Cython):
> 
> Take at look at page 14:
> 
>http://www.dabeaz.com/python/UnderstandingGIL.pdf
> 
> The critical part is the variable _Py_Ticker in Python's source file
> ceval.c, which is declared volatile int. As it is not declared static
> it is a global variable, and we can actually manipulate its value from
> a C extension:
> 
>extern volatile int _Py_Ticker; // evil!!!
> 
> Now imagine temporarily setting _Py_Ticker to some ridiculous high
> value like 0x7fff. That locks out all other threads, practically
> forever, until we restore _Py_Ticker back to it's original value.
> 
> What this gives us is global synchronization for free! The GIL is
> there anyway, so it adds no additional overhead.

Very interesting idea.  Will it work if accessed through ctypes?

   ticker = ctypes.c_int.in_dll(ctypes.pythonapi,"_Py_Ticker")
   ticker.value = 0x7fff

Or does ctypes muck with the GIL in a way that would break this idea?


  Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lockless algorithms in python (Nothing to do with GIL)

2010-06-28 Thread Ryan Kelly
On Mon, 2010-06-28 at 18:27 -0700, Zac Burns wrote:
>
>
> 
> I've managed to avoid locking in some cases by using
> dict.setdefault() as a kind of atomic test-and-set operation.
> It's not a full compare-and-swap but you could implement a
> simple locking scheme using it like this:
> 
> 
>  class PretendLock:
>  def __init__(self):
>  self.d = dict()
>  def acquire(self):
>  myid = threading.currentThread().ident
>  while self.d.setdefault("owner",myid) != myid:
>  pass
>  def release(self):
>  del self.d["owner"]
> 
> 
> This depends on some peculiarities of the CPython
> implementation that aren't guaranteed by the language spec -
> namely that thread switches can't happen while executing C
> code, that dict.setdefault is implemented in C, and that is
> can calculate the hash of a string key without calling back
> out to python code.
>
> 
> Thanks Ryan,
> 
> Agreed, I was timing the wrong thing - but largely because I wasn't
> sure what to time against. setdefault certainly seems to be a
> candidate for something to time. Even so, setdefault wins.
> 
> Though, I wouldn't want to use PretendLock in this case... it doesn't
> seem that having the spin loop would justify reducing reducing the
> lock allocation overhead in a no-contention scenario.


Oh totally - nobody reading this should even consider using that
PretendLock class for anything.  It's just an example of how to use
setdefault as a test-and-set kind of operator.


  Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Lockless algorithms in python (Nothing to do with GIL)

2010-06-28 Thread Ryan Kelly
On Mon, 2010-06-28 at 16:46 -0700, Zac Burns wrote:
> In my experience it is far more expensive to allocate a lock in python
> then it is the types that use them. Here are some examples:
> 
> >>> timeit.timeit('Lock()', 'from threading import Lock')
> 1.4449114807669048
> 
> >>> timeit.timeit('dict()')
> 0.2821554294221187
> 
> >>> timeit.timeit('list()')
> 0.17358153222312467
> 
> 
> Granted, I know these types do not allocate a lock - but a similarly
> defined user type would need to allocate a lock to guarantee
> thread-safety.

Sure, but I think you're timing the wrong thing here.  You would only
allocate the lock relatively rarely - it's the overhead of *acquiring*
the lock that's the real problem.

   r...@durian:~$ python -m timeit -s "from threading import Lock; l = Lock()" 
"l.acquire(); l.release()"
   100 loops, best of 3: 0.378 usec per loop

Compare to one of my favourite dict methods, setdefault:

   r...@durian:~$ python -m timeit -s "d = dict()" 
"d.setdefault('hello','world')"
   1000 loops, best of 3: 0.189 usec per loop


In the same ballpark really.

> I have not done a great deal of research into lockless algorithms
> thusfar, but would it be worthwhile to investigate implementing some
> of them in python to optimize performance critical sections of code?
> 
> Many lockless algorithms that I have looked at thusfar require a
> "Compare and Swap" operation. Does python have an equivalent to this?
> Is python high level enough that it has something better than this or
> it simply doesn't need it?

I've managed to avoid locking in some cases by using dict.setdefault()
as a kind of atomic test-and-set operation.  It's not a full
compare-and-swap but you could implement a simple locking scheme using
it like this:


  class PretendLock:
  def __init__(self):
  self.d = dict()
  def acquire(self):
  myid = threading.currentThread().ident
  while self.d.setdefault("owner",myid) != myid:
  pass
  def release(self):
  del self.d["owner"]


This depends on some peculiarities of the CPython implementation that
aren't guaranteed by the language spec - namely that thread switches
can't happen while executing C code, that dict.setdefault is implemented
in C, and that is can calculate the hash of a string key without calling
back out to python code.

Usually, it's not worth it.  The one time I use this regularly is for
lazy object initialisation, e.g. something like this:

  def get_my_object(key):
  try:
 return objects[key]
  except KeyError:
     return objects.setdefault(key,create_my_object(key))

If two threads happen to try initialising the object at the same time,
only one will wind up in the dict and being used; the other will be
discarded and garbage-collected.



  Cheers,

 Ryan




-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Possible to reach back in stack and grab calling function's locals()?

2010-06-17 Thread Ryan Kelly
On Thu, 2010-06-17 at 16:02 -0400, pyt...@bdurham.com wrote:
> Is there an elegant way to reach back in the stack and grab the
> calling function's copy of locals()?

You can do it using my favourite function, sys._getframe:

>>> import sys
>>> 
>>> def outer():
... a = 1
... inner()
... 
>>> 
>>> def inner():
... print sys._getframe(1).f_locals
... 
>>> 
>>> outer()
{'a': 1}
>>> 


The dict so obtained is of course read-only.  If you like I can show you
the black magic necessary to *write* to the local variables of the
calling function, but it ain't pretty :-)

> I'm working on a library that does lots of textmerge operations and am
> looking for a way to eliminate the need for many of the calls to our
> library to have to explictly pass locals() to our formatting
> functions.

I understand the desire, but that sounds like trouble to me.  Explicit
is better than implicit and all that.

You might get away with it for purely internal code (heck, even the
standard library uses sys._getframe on occasion!) but I would hesitate
to have a public-facing API that snaffles locals from any function that
happens to call it.


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: withhacks module (Re: Code redundancy)

2010-04-21 Thread Ryan Kelly
On Wed, 2010-04-21 at 19:43 -0400, pyt...@bdurham.com wrote:
> Ryan,
> 
> Your withhacks module looks very interesting.
> http://pypi.python.org/pypi/withhacks
> 
> What are your specific concerns about its use? Are there portability
> concerns?


It combines two things you just don't see in respectable python programs
- bytecode hacking and trace-function hacking.  And I'm sure its
performance is less than stellar, although much of that could be fixed
with some careful bytecode caching.

I'd be surprised if it runs under alternative python implementations,
and not surprised if it doesn't even work on Python 3 - although I
haven't tried it to confirm either way.

Having said that, it should work as advertised on Python 2.X  with
minimal fuss. So if you don't care about portability or about that dirty
feeling you get from messing with the Python internals, then have at
it :-)


  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details


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


Re: Code redundancy

2010-04-21 Thread Ryan Kelly
On Tue, 2010-04-20 at 14:43 +0100, Alan Harris-Reid wrote:
> Hi,
> 
> During my Python (3.1) programming I often find myself having to repeat 
> code such as...
> 
> class1.attr1 = 1
> class1.attr2 = 2
> class1.attr3 = 3
> class1.attr4 = 4
> etc.
> 
> Is there any way to achieve the same result without having to repeat the 
> class1 prefix?  Before Python my previous main language was Visual 
> Foxpro, which had the syntax...
> 
> with class1
>.attr1 = 1
>.attr2 = 2
>.attr3 = 3
>.attr4 = 4
>etc.
> endwith
> 
> Is there any equivalent to this in Python?


Please don't take this as in invitation to disregard the excellent
advice already received in this thread - I just want to point out that
python can usually be bent to your will.  Observe:

  
  from withhacks import namespace

  with namespace(class1):
  attr1 = 1
  attr2 = 2


This will do pretty much what you get from the "with" statement in
javascript (I assume it's similar to Visual Foxpro).


But don't use this in any real code.  Seriously, don't even think about
it.  You don't want to know the kind of abuses that go on under the
covers to make this kind of syntax hacking work...



  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details


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


Re: when should I explicitely close a file?

2010-04-13 Thread Ryan Kelly
On Tue, 2010-04-13 at 18:19 -0700, Chris Rebert wrote:
> On Tue, Apr 13, 2010 at 5:45 PM, Giampaolo Rodola'  wrote:
> > What about open('foo', 'w').close().
> > Does it have the same problems?
> 
> Well, no, but that's only because it's a pointless no-op that doesn't
> really do anything besides possibly throwing an exception (e.g. if the
> script didn't have write access to the current directory).

Actually, it will create the file if it doesn't exist, and truncate it
to zero length if it does.


  Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details


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


Re: sqlite savepoint problem [solved]

2010-03-15 Thread Ryan Kelly
On Fri, 2010-03-12 at 09:35 +0100, Laszlo Nagy wrote:
> > No it doesn't.  The problem is that using a connection as a context
> > manager doesn't do what you think. 
> >
> > It does *not* start a new transaction on __enter__ and commit it on
> > __exit__.  As far as I can tell it does nothing on __enter__ and calls
> > con.commit() or con.rollback() on exit.  With isolation_level=None,
> > these are no-ops.
> >   
> Thank you Ryan! You are abolutely right, and thank you for reading the 
> source.  Now everything works as I imagined.

No problemo - isolation_level has given me my fair share of headaches in
the past, so I couldn't resist the opportunity to understand it a little
better.

> The way the context manager and isolation_level works looks very very 
> strange to me. Here is a demonstration:
> 
> import sqlite3
> def getconn():
> conn = sqlite3.connect(':memory:')
> conn.isolation_level = None
> return conn
> def main():
> with getconn() as conn:
> conn.execute("create table a ( i integer ) ")
> try:
> conn.execute("insert into a values (1)")
> with conn:
> conn.execute("insert into a values (2)")
> raise Exception
> except:
> print "There was an error"
> for row in conn.execute("select * from a"):
> print row
> main()
> 
> 
> Output:
> 
> There was an error
> (1,)
> (2,)
>
> 
> Looks like the context manager did not roll back anything.

Yes, because there were no transactions created so there was nothing to
roll back.

>  If I remove 
> isolation_level=None then I get this:
> 
> There was an error
> 
> E.g. the context manager rolled back something that was executed outside 
> the context. 

Yes, because the transactions created by the default isolation level do
not nest, so the rollback happens at outermost scope.

> I cannot argue with the implementation - it is that way. 
> But this is not what I would expect. I believe I'm not alone with this.

That's at least two of us :-)

> Just for clarity, we should put a comment at the end of the 
> documentation here:
> 
> http://docs.python.org/library/sqlite3.html#sqlite3-controlling-transactions
> 
> I would add at least these things:
> 
> #1. By using isolation_level = None, connection objects (used as a 
> context manager) WON'T automatically commit or rollback transactions.
> #2. Using any isolation level, connection objects WON'T automatically 
> begin a transaction.
> #3. Possibly, include your connection manager class code, to show how to 
> do it "the expected" way.
> 
> Also one should clarify in the documentation, what isolation_level does. 
> Looks like setting isolation_level to None is not really an "auto commit 
> mode". It is not even part of sqlite itself. It is part of the python 
> extension.

I think of it as almost the opposite - you have to set
isolation_level=None to get the unadulterated behaviour of the
underlying sqlite library. 

I'm sure the devs would appreciate a documentation patch (submission
details at http://python.org/dev/patches/).  I'm also pretty confident
that I won't have time to do one up anytime soon :-)


 Good luck with your project!


 Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sqlite savepoint problem

2010-03-14 Thread Ryan Kelly
On Fri, 2010-03-12 at 08:32 +0100, Laszlo Nagy wrote:
> > From memory you can't issue a "CREATE TABLE" statement inside a
> > transaction, at least not at the default isolation level.  Such a
> > statement will automatically commit the current transaction.  Doesn't
> > help with your current problem but worth pointing out :-)
> >   
> Thank you. I'll keep in mind.
> > When debugging strange transaction behaviour, I find it easiest to
> > create the connection with isolation_level=None so that are no implicit
> > transactions being created behind your back.  Not sure why, but setting
> > this makes your example work for me.
> >   
> Yes, same for me. But setting it to None means auto commit mode! See here:
> 
> http://docs.python.org/library/sqlite3.html#sqlite3-controlling-transactions
> 
> 
> But it does not work that way. Look at this example
> 
> import sqlite3
> 
> conn = sqlite3.connect(':memory:')
> conn.isolation_level = None
> with conn:
> conn.execute("create table a ( i integer ) ")
> 
> with conn:
> conn.execute("insert into a values (1)")
> conn.execute("SAVEPOINT sp1")
> conn.execute("insert into a values (2)")
> conn.execute("SAVEPOINT sp2")
> conn.execute("insert into a values (3)")
> conn.execute("ROLLBACK TO sp2")
> conn.execute("insert into a values (4)")
> conn.execute("RELEASE sp1")
> 
> with conn:
> for row in conn.execute("select * from a"):
> print row
>
> 
> It prints:
> 
> (1,)
> (2,)
> (4,)
> 
> So everything is working. Nothing is auto commited. But if I change it 
> to "DEFERRED" or "IMMEDIATE" or "EXCLUSIVE" then it won't work. Why?

I have a theory, based on a quick perusal of the sqlite3 bindings
source.

The bindings think that "SAVEPOINT sp1" is a "non-DML, non-query"
statement. So when isolation_level is something other than None, this
statement implicitly commits the current transaction and throws away
your savepoints!

Annotating your example:

  # entering this context actually does nothing
  with conn:
 # a transaction is magically created before this statement
 conn.execute("insert into a values (1)")
 # and is implicitly committed before this statement
 conn.execute("SAVEPOINT sp1")
 # a new transaction is magically created
 conn.execute("insert into a values (2)")
 # and committed, discarding the first savepoint.
 conn.execute("SAVEPOINT sp2")
 # a new transaction is magically created
 conn.execute("insert into a values (3)")
 # and committed, discarding the very savepoint we are trying to use. 
     conn.execute("ROLLBACK TO sp2")
 conn.execute("insert into a values (4)")
 conn.execute("RELEASE sp1")


In your previous multi-threaded example, try adding a "SAVEPOINT sp1"
statement after deleting the rows in Thread2.  You'll see that the
delete is immediately committed and the rows cannot be read back by
Thread1.  (modified version attached for convenience).


  Cheers,

 Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



import os
import sqlite3
import threading
import time

FPATH = '/tmp/test.sqlite'
if os.path.isfile(FPATH):
os.unlink(FPATH)

class MyConn(sqlite3.Connection):
def __enter__(self):
self.execute("BEGIN")
return self
def __exit__(self,exc_type,exc_info,traceback):
if exc_type is None:
self.execute("COMMIT")
else:
self.execute("ROLLBACK")

def getconn():
global FPATH
conn = sqlite3.connect(FPATH)#,factory=MyConn)
conn.isolation_level = None
return conn

class Thr1(threading.Thread):
def run(self):
conn = getconn()
print "Thr1: Inserting 0,1,2,3,4,5"
with conn:
for i in range(6):
conn.execute("insert into a values (?)",[i])
print "Thr1: Commited"
with conn:
print "Thr1: Selecting all rows:"
for row in conn.execute("select * from a"):
print row
print "Thr1: Wait some..."
time.sleep(3)
print "Thr1: Selecting again, in the same transaction"
for row in conn.execute("select * from a"):
print row


class Thr2(threading.Thread):
def run(self):
conn = getconn()
with conn:
prin

Re: sqlite savepoint problem

2010-03-14 Thread Ryan Kelly
On Fri, 2010-03-12 at 08:48 +0100, Laszlo Nagy wrote:
> >
> > I'm now confused. Also, I could not find anything about these 
> > isolation levels on the sqlite website. The only think I could find is 
> > "PRAGMA read_uncommited". If that is the same as setting 
> > isolation_level to None, then I don't want it.
> Yes, it is. Here is a test:

No it isn't.  The "magic" behind isolation_level is a creation of the
python sqlite bindings.  You can probably tell that I'm not a fan of it.

> import os
> import sqlite3
> import threading
> import time
> 
> FPATH = '/tmp/test.sqlite'
> if os.path.isfile(FPATH):
> os.unlink(FPATH)
> 
> def getconn():
> global FPATH
> conn = sqlite3.connect(FPATH)
> conn.isolation_level = None
> return conn
> 
> class Thr1(threading.Thread):
> def run(self):
> conn = getconn()
> print "Thr1: Inserting 0,1,2,3,4,5"
> with conn:
> for i in range(6):
> conn.execute("insert into a values (?)",[i])
> print "Thr1: Commited"
> with conn:
> print "Thr1: Selecting all rows:"
> for row in conn.execute("select * from a"):
> print row
> print "Thr1: Wait some..."
> time.sleep(3)
> print "Thr1: Selecting again, in the same transaction"
> for row in conn.execute("select * from a"):
> print row
> 
> 
> class Thr2(threading.Thread):
> def run(self):
> conn = getconn()
> with conn:
> print "Thr2: deleting all rows from a"
> conn.execute("delete from a")
> print "Thr2: Now we wait some BEFORE commiting changes."
> time.sleep(3)
> print "Thr2: Will roll back!"
> raise Exception
> 
> 
> def main():
> with getconn() as conn:
> conn.execute("create table a ( i integer ) ")
> thr1 = Thr1()
> thr1.start()
> time.sleep(1)
> thr1 = Thr2()
> thr1.start()
> 
> main()
> 
> 
> And the test result:
> 
> Thr1: Inserting 0,1,2,3,4,5
> Thr1: Commited
> Thr1: Selecting all rows:
> (0,)
> (1,)
> (2,)
> (3,)
> (4,)
> (5,)
> Thr1: Wait some...
> Thr2: deleting all rows from a
> Thr2: Now we wait some BEFORE commiting changes.
> Thr1: Selecting again, in the same transaction
> Thr2: Will roll back!
> Exception in thread Thread-2:
> Traceback (most recent call last):
>   File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
> self.run()
>   File "test.py", line 44, in run
> raise Exception
> Exception
> 
> 
> It means that setting isolation_level to None will really allow 
> uncommited changes to be read by other transactions! This is sad, and of 
> course this is something that I do not want.


No it doesn't.  The problem is that using a connection as a context
manager doesn't do what you think. 

It does *not* start a new transaction on __enter__ and commit it on
__exit__.  As far as I can tell it does nothing on __enter__ and calls
con.commit() or con.rollback() on exit.  With isolation_level=None,
these are no-ops.

If you create your own connection wrapper that explicitly creates and
commits transactions, you example will work fine with
isolation_level=None.  Here's the relevant changes:


  class MyConn(sqlite3.Connection):
  def __enter__(self):
  self.execute("BEGIN")
  return self
  def __exit__(self,exc_type,exc_info,traceback):
  if exc_type is None:
  self.execute("COMMIT")
  else:
  self.execute("ROLLBACK")

  def getconn():
  global FPATH
  conn = sqlite3.connect(FPATH,factory=MyConn)
  conn.isolation_level = None
  return conn


  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sqlite savepoint problem (was: Re: sqlite3 is sqlite 2?)

2010-03-14 Thread Ryan Kelly
On Fri, 2010-03-12 at 07:46 +0100, Laszlo Nagy wrote:
> >
>  >>> import sqlite3
>  >>> conn = sqlite3.connect(':memory:')
>  >>> with conn:
> ... conn.execute("BEGIN")
> ... conn.execute("create table a ( i integer)")
> ... conn.execute("insert into a values (1)")
> ... conn.execute("savepoint sp1")
> ... conn.execute("insert into a values(2)")
> ... conn.execute("release sp1")
> ... conn.execute("COMMIT")
> ...
> 
> 
> 
> 
> 
> Traceback (most recent call last):
>   File "", line 7, in 
> sqlite3.OperationalError: no such savepoint: sp1
>  >>>
>
> The syntax is correct: http://www.sqlite.org/lang_savepoint.html
> The savepoint was really created.
> But I get this error, telling "no such savepoint". What is wrong here? 
> Maybe it has to do something with transaction isolation? :-s

From memory you can't issue a "CREATE TABLE" statement inside a
transaction, at least not at the default isolation level.  Such a
statement will automatically commit the current transaction.  Doesn't
help with your current problem but worth pointing out :-)

When debugging strange transaction behaviour, I find it easiest to
create the connection with isolation_level=None so that are no implicit
transactions being created behind your back.  Not sure why, but setting
this makes your example work for me.

  Ryan




-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sqlite3 is sqlite 2?

2010-03-14 Thread Ryan Kelly
On Fri, 2010-03-12 at 06:48 +0100, Laszlo Nagy wrote:
> gand...@ubuntu:~$ python
> Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
> [GCC 4.3.3] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> import sqlite3
>  >>> sqlite3.version
> '2.4.1'
> 
> Is it possible to install a real sqlite version 3 somehow? I really need 
> it because I have to use savepoint/rollback to. That is only supported 
> from sqlite 3.6.8. Is it enough if I upgrade to Ubuntu Karmic? I know 
> that is not a question about Python itself.

That's the sqlite *bindings* version:

  >>> sqlite3.version
  '2.4.1'
  >>> sqlite3.sqlite_version
  '3.6.16'
  >>>

So this is "pysqlite" version 2.4.1, which wraps sqlite version 3.6.16.

Cheers,

  Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Upgrading Py2exe App

2010-02-24 Thread Ryan Kelly
On Wed, 2010-02-24 at 15:05 -0800, Aahz wrote:
> In article ,
> Ryan Kelly   wrote:
> >
> >Yes.  The idea of having a "bootstrapping exe" is that actual
> >application code can be swapped out without having to overwrite the
> >executable file.  As long as you don't change python versions, this
> >allows updates to be safe against system crashes, even on platforms
> >without atomic file replacement.
> >
> >So the frozen app does this in a background thread:
> >
> >   Esky(sys.executable,"http://my.updates.com";).auto_update()
> >
> >And it hits the given url, grabs the latest zipfile, downloads and
> >unpacks and atomically places it into the application directory.  Et
> >viola, your app is at the latest version.
> 
> How does this work with a running app?  What if the app is a service?

The changes will only take effect the next time the app is started -
currently there's no support for "hot upgrading" a running app.

Would definitely be an interesting feature though...


   Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


ANN: esky v0.4.0 [was Re: Upgrading Py2exe App]

2010-02-22 Thread Ryan Kelly

Hi All,


  As promised I have made a new release of esky, my auto-update
framework for frozen python apps.  Details below for those who are
interested.

  Cheers,

 Ryan


---


  esky:  keep frozen apps fresh

Esky is an auto-update framework for frozen Python applications.  It
provides a simple API through which apps can find, fetch and install
updates, and a bootstrapping mechanism that keeps the app safe in the
face of failed or partial updates.

Esky is currently capable of freezing apps with bbfreeze, cxfreeze and
py2exe.  Support for py2app is in the works.

The latest version is v0.4.0, with the following major changes:

   * added support for freezing with cx_Freeze.
   * improved support for freezing with py2exe.
   * added ability to set the icon on each executable
 (if the chosen freezer module supports it)
   * made Esky.cleanup() catch and ignore common errors.
   * added support for Python 3 (via distribute's "use_2to3" flag)
   * added a brief tutorial and example application
   * some backwards-incompatible API changes (see ChangeLog for details)


Downloads:  http://pypi.python.org/pypi/esky/0.4.0/

Code, bugs, etc:  http://github.com/rfk/esky/

Tutorial:  http://github.com/rfk/esky/tree/master/tutorial/


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Overcoming python performance penalty for multicore CPU

2010-02-21 Thread Ryan Kelly
On Sun, 2010-02-21 at 23:05 +0100, Martin v. Loewis wrote: 
> > It's far from scientific, but I've seen behaviour that's close to a 100%
> > performance penalty on a dual-core linux system:
> > 
> >http://www.rfk.id.au/blog/entry/a-gil-adventure-threading2
> > 
> > Short story:  a particular test suite of mine used to run in around 25
> > seconds, but a bit of ctypes magic to set thread affinity dropped the
> > running time to under 13 seconds.
> 
> Indeed, it's not scientific - but with a few more details, you could
> improve it quite a lot: what specific Linux distribution (the posting
> doesn't even say it's Linux), what specific Python version had you been
> using? (less important) what CPUs? If you can: what specific test suite?

I'm on Ubuntu Karmic, Python 2.6.4, an AMD Athlon 7750 dual core.

Unfortunately the test suite is for a proprietary application.  I've
been able to reproduce similar behaviour with an open-source test suite,
using the current trunk of the "pyfilesystem" project:

  http://code.google.com/p/pyfilesystem/


In this project "OSFS" is an object-oriented interface to the local
filesystem.  The test case "TestOSFS.test_cases_in_separate_dirs" runs
three theads, each doing a bunch of IO in a different directory.

Running the tests normally:

r...@durian:/storage/software/fs$ nosetests 
fs/tests/test_fs.py:TestOSFS.test_cases_in_separate_dirs
.
--
Ran 1 test in 9.787s


That's the best result from five runs - I saw it go as high as 12
seconds.  Watching it in top, I see CPU usage at around 150%.

Now using threading2 to set the process cpu affinity at the start of the
test run:

r...@durian:/storage/software/fs$ nosetests 
fs/tests/test_fs.py:TestOSFS.test_cases_in_separate_dirs
.
--
Ran 1 test in 3.792s


Again, best of five.  The variability in times here is much lower - I
never saw it go above 4 seconds.  CPU usage is consistently 100%.



  Cheers,

 Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details




signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Overcoming python performance penalty for multicore CPU

2010-02-21 Thread Ryan Kelly
On Sun, 2010-02-21 at 22:22 +0100, Martin v. Loewis wrote:
> John Nagle wrote:
> >I know there's a performance penalty for running Python on a
> > multicore CPU, but how bad is it?  I've read the key paper
> > ("www.dabeaz.com/python/GIL.pdf"), of course.  It would be adequate
> > if the GIL just limited Python to running on one CPU at a time,
> > but it's worse than that; there's excessive overhead due to
> > a lame locking implementation.  Running CPU-bound multithreaded
> > code on a dual-core CPU runs HALF AS FAST as on a single-core
> > CPU, according to Beasley.
> 
> I couldn't reproduce these results on Linux. Not sure what "HALF AS
> FAST" is; I suppose it means "it runs TWICE AS LONG" - this is what I
> couldn't reproduce.
> 
> If I run Beazley's program on Linux 2.6.26, on a 4 processor Xeon (3GHz)
> machine, I get 30s for the sequential execution, 40s for the
> multi-threaded case, and 32s for the multi-threaded case when pinning
> the Python process to a single CPU (using taskset(1)).
> 
> So it's 6% overhead for threading, and 25% penalty for multicore CPUs -
> far from the 100% you seem to expect.

It's far from scientific, but I've seen behaviour that's close to a 100%
performance penalty on a dual-core linux system:

   http://www.rfk.id.au/blog/entry/a-gil-adventure-threading2

Short story:  a particular test suite of mine used to run in around 25
seconds, but a bit of ctypes magic to set thread affinity dropped the
running time to under 13 seconds.


  Cheers,

 Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is there a way to continue after an exception ?

2010-02-20 Thread Ryan Kelly
On Sun, 2010-02-21 at 13:17 +1100, Lie Ryan wrote:
> On 02/21/10 12:02, Stef Mientki wrote:
> > On 21-02-2010 01:21, Lie Ryan wrote:
> >>> On Sun, Feb 21, 2010 at 12:52 AM, Stef Mientki
>  wrote:
> >>>
> >>>> hello,
> >>>>
> >>>> I would like my program to continue on the next line after an uncaught
> >>>> exception,
> >>>> is that possible ?
> >>>>
> >>>> thanks
> >>>> Stef Mientki
> >>>>
> >>>>
> >> That reminds me of VB's "On Error Resume Next"
> >>
> > I think that's what I'm after ...
>
> A much better approach is to use callbacks, the callbacks determines
> whether to raise an exception or continue execution:
> 
> def handler(e):
> if datetime.datetime.now() >= datetime.datetime(2012, 12, 21):
> raise Exception('The world has ended')
> # else: ignore, it's fine
> 
> def add_ten_error_if_zero(args, handler):
> if args == 0:
> handler(args)
> return args + 10
> 
> print add_ten_error_if_zero(0, handler)
> print add_ten_error_if_zero(10, handler)
> print add_ten_error_if_zero(0, lambda e: None) # always succeeds


Or if you don't like having to explicitly manage callbacks, you can try
the "withrestart" module:

http://pypi.python.org/pypi/withrestart/

It tries to pinch some of the good ideas from Common Lisp's
error-handling system.

  from withrestart import *

  def add_ten_error_if_zero(n):
  #  This gives calling code the option to ignore
  #  the error, or raise a different one.
  with restarts(skip,raise_error):
  if n == 0:
  raise ValueError
  return n + 10

  # This will raise ValueError
  print add_ten_error_if_zero(0)

  # This will print 10
  with Handler(ValueError,"skip"):
  print add_ten_error_if_zero(0)

  # This will exit the python interpreter
  with Handler(ValueError,"raise_error",SystemExit):
  print add_ten_error_if_zero(0)



  Cheers,

  Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Upgrading Py2exe App

2010-02-19 Thread Ryan Kelly
On Fri, 2010-02-19 at 11:08 -0800, T wrote:
> On Feb 18, 7:19 pm, Ryan Kelly  wrote:
> > On Thu, 2010-02-18 at 07:46 -0800, T wrote:
> > > I have a Python app which I converted to an EXE (all files separate;
> > > single EXE didn't work properly) via py2exe - I plan on distributing
> > > this and would like the ability to remotely upgrade the program (for
> > > example, via HTTP/HTTPS).   Looks like it's not just the EXE that I
> > > will need need to replace (DLLs, the library.zip, etc.).  What would
> > > be the best way to go about doing this?
> >
> > I've been working on an auto-update framework for my own frozen apps,
> > you might find it useful:
> >
> >  http://pypi.python.org/pypi/esky
> >
> > Docs are a little scarce at the moment, the next release will hopefully
> > come with a short tutorial (as well as support for cx_freeze and maybe
> > py2app, depending on how adventurous I'm feeling).
> >
> Thanks Ryan..this looks like it could be what I'm looking for, but I'm
> still a bit unsure of how exactly how it works.  Do you happen to have
> an idea approx when the next release w/ tutorial will be out?


If I punt on the py2app support, I should be able to get it done in the
next 3-4 days.  I'll send a quick email to python-list when it's ready.

Here's a rough roadmap of where the project is heading:

  v0.4.0:  cx_freeze support and a tutorial [the next 3-4 days]
  v0.4.1:  py2app support [the next 2-3 weeks]
  v0.5.0:  differential updates using bsdiff [next few months]


  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Upgrading Py2exe App

2010-02-19 Thread Ryan Kelly
On Thu, 2010-02-18 at 20:32 -0800, CM wrote:
> On Feb 18, 7:19 pm, Ryan Kelly  wrote:
> > On Thu, 2010-02-18 at 07:46 -0800, T wrote:
> > > I have a Python app which I converted to an EXE (all files separate;
> > > single EXE didn't work properly) via py2exe - I plan on distributing
> > > this and would like the ability to remotely upgrade the program (for
> > > example, via HTTP/HTTPS).   Looks like it's not just the EXE that I
> > > will need need to replace (DLLs, the library.zip, etc.).  What would
> > > be the best way to go about doing this?
> >
> > I've been working on an auto-update framework for my own frozen apps,
> > you might find it useful:
> >
> >  http://pypi.python.org/pypi/esky
> >
>
> 
> This looks pretty interesting and useful.

Thanks :-)

> Just to help me understand it a bit more:  what is it that users will
> download from some web page in order to initially get the py2exe'd app
> on their system?  Is it "really" an "esky", with the app's .exe file
> inside it (but the esky is named the same as the app)?

Currently, it's just a zip file with the frozen app in it, which the
user unzips to wherever they want the app.  When unzipped it looks like
this:

   myapp.exe  <-- actually the esky bootstrap exe
   myapp-X.Y.Z.win32/
   myapp.exe  <-- the actual frozen app as produced by py2exe
   python26.dll
   ...etc...

This could easily be wrapped in an installer - the important thing is
just that the files end up on the user's machine in the expected
directory structure.

>   And then when
> they want to update, the app's code calls the esky class to do the
> work of swapping out the appropriate .exe file?  Something like this?

Yes.  The idea of having a "bootstrapping exe" is that actual
application code can be swapped out without having to overwrite the
executable file.  As long as you don't change python versions, this
allows updates to be safe against system crashes, even on platforms
without atomic file replacement.

So the frozen app does this in a background thread:

   Esky(sys.executable,"http://my.updates.com";).auto_update()

And it hits the given url, grabs the latest zipfile, downloads and
unpacks and atomically places it into the application directory.  Et
viola, your app is at the latest version.

From the packager's point of view, you run the "bdist_esky" distutils
command to generate the zipfile containing your latest version, then
simply upload it to your server.

> Would this also work if one used InnoSetup to install the exe on the
> user's system?

Yes, absolutely - in fact I plan to do this myself at some stage.  All
that's required is that the files end up in the expected directory
structure.


   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Upgrading Py2exe App

2010-02-18 Thread Ryan Kelly
On Thu, 2010-02-18 at 07:46 -0800, T wrote:
> I have a Python app which I converted to an EXE (all files separate;
> single EXE didn't work properly) via py2exe - I plan on distributing
> this and would like the ability to remotely upgrade the program (for
> example, via HTTP/HTTPS).   Looks like it's not just the EXE that I
> will need need to replace (DLLs, the library.zip, etc.).  What would
> be the best way to go about doing this?


I've been working on an auto-update framework for my own frozen apps,
you might find it useful:

  http://pypi.python.org/pypi/esky

Docs are a little scarce at the moment, the next release will hopefully
come with a short tutorial (as well as support for cx_freeze and maybe
py2app, depending on how adventurous I'm feeling).


  Cheers,

 Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Python's Reference And Internal Model Of Computing Languages

2010-02-02 Thread Ryan Kelly

> On Tue, 2010-02-02 at 17:28 -0800, Xah Lee wrote:

I know, I know, do not feed the trolls.  But this is just so *wrong*
that I can't help myself.

> In Python, there are 2 ways to clear a hash:

No, no there's not.  There's one way to clear a hash and there's one way
to assign a new object to a variable.

>  “myHash = {}” and
> “myHash.clear()”. What is the difference?
> The difference is that “myHash={}” simply creates a new empty hash and
> assigns to myHash, while “myHash.clear()” actually clear the hash the
> myHash is pointing to.
> 
> What does that mean?? Here's a code that illustrates:
> 
> # python
> # 2 ways to clear hash and their difference
> aa = {'a':3, 'b':4}
> bb = aa
> aa = {}
> print bb # prints {'a': 3, 'b': 4}
> 
> aa = {'a':3, 'b':4}
> bb = aa
> aa.clear()
> print bb # prints {}
> 
> This is like this because of the “reference” concept.

...snip inane babble...

> Languages that do not have any “reference” or “object”, or otherwise
> does not require the programer to have some internal model of source
> code, are: Mathematica, JavaScript, PHP. (others may include TCL,
> possibly assembly langs.)


Just so we're all clear exactly how much thought has gone into this
little rant, here's a transcript from a JavaScript session:

  var aa = {};
  var bb = aa;
  aa.hello = "world";
  alert(bb.hello)  -->  "world"
  delete bb.hello
  alert(aa.hello)  -->  "undefined"

OMFG, references!!

Come to think of it, the JavaScript and Python object models are really
very similar.  I'm genuinely curious now - what little sprinkle of magic
fairy dust has earned JavaScript objects the Xah Lee seal of approval
while Python objects miss out?


   Ryan




-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Why this error message

2010-01-31 Thread Ryan Kelly
On Sun, 2010-01-31 at 15:25 -0500, Ray Holt wrote:
> Why am I getting the error that test is not defined. Thanks, Ray
>  class SpecialFile:
> def __init__(self, fileName):
> self.__file = open(fileName, 'W')
> self.__file.write('* Start Special File *\n\n')
> def write(self, str):
> self.__file.write(str)
> def writelines(self, strList):
> self.__file.writelines(strList)
> 
> def __del__(self):   # Destructor method, __del__.
> print "entered __del__"
> self.close()
> 
> def close(self):  # Clean up method
> if self.__file:
> self.__file.write('\\n* End Special File *')
> self.__file.close()
> self.__file = None
> 
> def test():
> f = SpecialFile('testfile')
> f.write('11\n')
> f.close()
> test()
> Traceback (most recent call last):
>   File "C:\Python26\Classes_and_OOP_Programing.py", line 145, in
> 
> test()
> NameError: name 'test' is not defined


Based on the indentation, it looks like you've defined "test" as a
method on the SpecialFile class.  Try dedenting it to begin in the first
column.


  Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: shouldn't list comprehension be faster than for loops?

2009-12-18 Thread Ryan Kelly

> > Tenting the time spent by each approach (using time.clock()), with a
> > file with about 100,000 entries, I get 0.03s for the loop and 0.05s
> > for the listcomp.
>
> Anything else being equal, list comprehensions will be the faster
> becuase they incur fewer name and attribute lookups. It will be the
> same as the difference between a for loop and a call to map. A list
> comprehension is basically an enhancement of map.

Not so.  If you use the "dis" module to peek at the bytecode generated
for a list comprehension, you'll see it's very similar to that generated
for an explicit for-loop.  The byte-code for a call to map is very
different.

Basically:  both a for-loop and a list-comp do the looping in python
bytecode, while a call to map will do the actual looping in C.

>>> def comper():
... return [i*2 for i in xrange(10)]
... 
>>> 
>>> dis.dis(comper)
  2   0 BUILD_LIST   0
  3 DUP_TOP 
  4 STORE_FAST   0 (_[1])
  7 LOAD_GLOBAL  0 (xrange)
 10 LOAD_CONST   1 (10)
 13 CALL_FUNCTION1
 16 GET_ITER
>>   17 FOR_ITER17 (to 37)
 20 STORE_FAST   1 (i)
 23 LOAD_FAST0 (_[1])
 26 LOAD_FAST1 (i)
 29 LOAD_CONST   2 (2)
 32 BINARY_MULTIPLY 
 33 LIST_APPEND 
 34 JUMP_ABSOLUTE   17
>>   37 DELETE_FAST  0 (_[1])
 40 RETURN_VALUE
>>>
>>>
>>>
>>> def maper():
... return map(lambda i: i*2,xrange(10))
... 
>>> dis.dis(maper)
  2   0 LOAD_GLOBAL  0 (map)
  3 LOAD_CONST   1 (>> 



  Cheers,

Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: ANN: withrestart 0.2.1

2009-12-18 Thread Ryan Kelly
On Fri, 2009-12-18 at 07:12 -0500, Neal Becker wrote:
> I haven't tried it, but it sounds really cool.  I suppose I should expect a 
> lot more overhead compared to try/except, since it's not built-in to python?

It's a pretty thin layer on top of try/except so I'll be surprised if
there is *too* much overhead.  The only overhead is at establishment
and/or invocation time - calling some extra functions, walking a few
stack frames, etc.

I've attached a highly scientific benchmark I threw together this
morning.  Results:

  Establishing a restart/tryexcept but not using it:

test_tryexcept0:  1.23 usec
test_restarts0:  34.90 usec

  Establishing a restart/tryexcept, returning a new value:

test_tryexcept1:  3.56 usec
test_restarts1:  67.30 usec

  Establishing a restart/tryexcept, raising a new error: 

test_tryexcept2:  5.86 usec
test_restarts2:  90.20 usec

  Not having to pass status flags or callback functions through every
layer of your API to properly recover from errors:

tryexcept:impossible :-(
withrestart:  priceless  :-)


  Cheers,

  Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details


from withrestart import *


def test_tryexcept0():
def raiser():
return 7
def invoker():
return raiser()
def catcher():
try:
return invoker()
except ValueError:
return 7
assert catcher() == 7

def test_tryexcept1():
def raiser():
raise ValueError
def invoker():
return raiser()
def catcher():
try:
return invoker()
except ValueError:
return 7
assert catcher() == 7

def test_tryexcept2():
def raiser():
raise ValueError
def invoker():
raiser()
def catcher():
try:
invoker()
except ValueError:
raise TypeError
try:
catcher()
except TypeError:
pass
else:
raise AssertionError



def test_restarts0():
def raiser():
return 7
def invoker():
with restarts(use_value) as invoke:
return invoke(raiser)
def catcher():
with Handler(ValueError,"use_value",7):
return invoker()
assert catcher() == 7

def test_restarts1():
def raiser():
raise ValueError
def invoker():
with restarts(use_value) as invoke:
return invoke(raiser)
def catcher():
with Handler(ValueError,"use_value",7):
return invoker()
assert catcher() == 7

def test_restarts2():
def raiser():
raise ValueError
def invoker():
with restarts(raise_error) as invoke:
invoke(raiser)
def catcher():
with Handler(ValueError,"raise_error",TypeError):
invoker()
try:
catcher()
except TypeError:
pass
else:
raise AssertionError




signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


ANN: withrestart 0.2.1

2009-12-17 Thread Ryan Kelly

Hi All,


  Apologies if you receive multiple copies of this, my python-announce
posts don't seem to be making it through.

  I've just released a new python module called "withrestart".  It's an
attempted Pythonisation of the restart-based condition system of Common
Lisp.  Details are on PyPI:

http://pypi.python.org/pypi/withrestart/0.2.1


  For an introduction to conditions and restarts, see "Beyond Exception
Handling" by Peter Seibel:

   
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html


  For a quick demo of the module in action, keep reading...

  Cheers,

  Ryan



About withrestart:
--

Version:  0.2.1
Licence:  MIT
Source:   http://github.com/rfk/withrestart


withrestart is a Pythonisation (Lispers might rightly say "bastardisation") of
the restart-based condition system of Common Lisp.  It's designed to make error
recovery simpler and easier by removing the assumption that unhandled errors
must be fatal.

A "restart" represents a named strategy for resuming execution of a function
after the occurrence of an error.  At any point during its execution a
function can push a Restart object onto its call stack.  If an exception
occurs within the scope of that Restart, code higher-up in the call chain can
invoke it to recover from the error and let the function continue execution.
By providing several restarts, functions can offer several different strategies
for recovering from errors.

A "handler" represents a higher-level strategy for dealing with the occurrence
of an error.  It is conceptually similar to an "except" clause, in that one
establishes a suite of Handler objects to be invoked if an error occurs during
the execution of some code.  There is, however, a crucial difference: handlers
are executed without unwinding the call stack.  They thus have the opportunity
to take corrective action and then resume execution of whatever function
raised the error.

As an example, here's a function that doesn't like the number seven:

def anything_but_seven(v):
if v == 7:
raise ValueError("Argh!  A Seven!")
return v
 
And here's a function that can recover from the occurrence of a seven
using the pre-defined restarts "skip" and "use_value":

def sum_items(items):
total = 0
for i in items:
with restarts(skip,use_value) as invoke:
total += invoke(anything_but_seven,i)
return total

Naively calling this will raise a ValueError:

>>> sum_items(range(8))
Traceback (most recent call last):
...
ValueError: Argh! A Seven!
>>>

But if we handle ValueErrors by invoking the "skip" restart, we can
still get the sum of the remaining items:

>>> with Handler(ValueError,"skip"):
... sum_items(range(8))
... 
21
>>> 

Alternately, we can invoke the "use_value" restart to replace the sevens
with another value:

>>> with Handler(ValueError,"use_value",12):
... sum_items(range(8))
... 
33
>>> 

By splitting the responsibility for error recovery between Handlers and
Restarts, we can cleanly separate the low-level mechanics of recovering
from an error from the high-level decisions about what sort of recovery
to perform.



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details





signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: ANN: esky 0.2.1

2009-11-13 Thread Ryan Kelly

> >> Recently I was looking into distribution mechanisms, and I passed over
> >> bbfreeze because I saw no indication that Python 2.6 was supported.
> >
> >Not sure if it's officially supported, but I do most of my development
> >on Python 2.6 and bbfreeze hasn't given me any problems as yet.
> 
> Also, bbfreeze doesn't seem to have active development.

It's slow but certainly active.  Development was recently moved to
github with almost no fanfare (in fact I only discovered the github site
by accident):

   http://github.com/schmir/bbfreeze


Out of curiosity, what freezer package did you settle on in the end?
I'm curious it see if esky could easily switch between different
freezers (although it currently depends on some rather deep details of
the bbfreeze format).


  Cheers,

Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: ANN: esky 0.2.1

2009-11-12 Thread Ryan Kelly

> >Esky is an auto-update framework for frozen python apps, built on top of
> >bbfreeze.  It provides a simple API through which apps can find, fetch
> >and install updates, and a bootstrapping mechanism that keeps the app
> >safe in the face of failed or partial updates.
> 
> Recently I was looking into distribution mechanisms, and I passed over
> bbfreeze because I saw no indication that Python 2.6 was supported.

Not sure if it's officially supported, but I do most of my development
on Python 2.6 and bbfreeze hasn't given me any problems as yet.

  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


ANN: esky 0.2.1

2009-11-07 Thread Ryan Kelly

I'm pleased to announce the latest release of esky, a tool for keeping
your frozen apps fresh:

  Downloads:http://pypi.python.org/pypi/esky/
  Latest Version:   0.2.1
  License:  BSD

Esky is an auto-update framework for frozen python apps, built on top of
bbfreeze.  It provides a simple API through which apps can find, fetch
and install updates, and a bootstrapping mechanism that keeps the app
safe in the face of failed or partial updates.

A frozen app that wants to auto-update itself might run the following in
a background thread:

if hasattr(sys,"frozen"):
app = esky.Esky(sys.executable,"http://myapp.com/downloads/";)
new_version = app.find_update()
if new_version is not None:
app.install_update(new_version)

The new version of the application is linked into the app directory in
the safest possible manner:  using a carefully-ordered sequence of
atomic renames on POSIX, using MoveFileTransacted on Windows Vista or
later, and using the "rename-and-pray" method on older versions of
Windows.  Failed or partial updates are detected and cleaned up
automatically.


 Enjoy!


 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: comparing alternatives to py2exe

2009-11-03 Thread Ryan Kelly

> Recently I put together this incomplete comparison chart in an attempt
> to choose between the different alternatives to py2exe:
> 
> http://spreadsheets.google.com/pub?key=tZ42hjaRunvkObFq0bKxVdg&output=html
> 
> ...snip...
>
> Are there major things I'm missing or misunderstanding?

A quick note - although I haven't tried it out, the latest version of
bbfreeze claims to support OSX.


  Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: recommendation for webapp testing?

2009-09-22 Thread Ryan Kelly

> >I need to do some basic website testing (log into account, add item to
> >cart, fill out and submit forms, check out, etc.). What modules would
> >be good to use for webapp testing like this?
> 
> Windmill is an option, but I haven't tried it myself

I'll second Windmill as an option, have had good experiences with it.
The current version is a little on the slow side, but I believe there's
a big new release just around the corner that contains significant
performance improvements.

   Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Granularity of OSError

2009-09-18 Thread Ryan Kelly
> > You can access the exception object which gives you greater detail.
> >
> > try:
> > os.unlink(some_file)
> > except OSError, e:
> > print e.errno
> > print e.strerror
> >
> > if e.errno == 2:
> > pass
> > else:
> > raise
>
> I do this myself in a lot of places, almost exactly like this. It's
> slightly clearer to use 'if e.errno == errno.ENOENT' in my opinion,
> but, whatever.

In some cases it's also more correct.  While ENOENT is always 2, some
error codes differ between windows and posix.  In general it's better to
use the constants from the errno module.

   Ryan


-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


ANN: extprot 0.1.1

2009-08-05 Thread Ryan Kelly

Hi All,


Sorry if you get this twice, it seems to have gotten lost on its way
through python-announce.

I'm pleased to announce the first release of the "extprot" python
module.  Extprot implements a compact, efficient, extensible and
language-neutral object serialisation protocol.

License:  MIT
Downloads:http://pypi.python.org/pypi/extprot/
Source code:  http://github.com/rfk/extprot/tree/master


You can think of extprot as something akin to Google's protocol buffers,
with a few extra bytes of serialisation overhead and a Python binding
that doesn't have nearly as many rough edges.  For example:

  * It's a stand-alone python module, packaged and distributed in
the standard fashion.
  * It's friendly to dynamic package management tools like pip.
  * It works exclusively with standard Python objects. Declared a
list field? It's a native list object.
  * You don't need to compile your protocol definitions.


More on the extprot format itself is here:

   http://eigenclass.org/R2/writings/extprot-extensible-protocols-intro

More on my motivations for this package here, if you're interested:

http://www.rfk.id.au/blog/entry/new-python-module-extprot


Enjoy!


Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: [ANN] regobj - Pythonic object-based access to the Windows Registry

2009-05-04 Thread Ryan Kelly

> >   I've just released the results of a nice Sunday's coding, inspired by
> > one too many turns at futzing around with the _winreg module.  The
> > "regobj" module brings a convenient and clean object-based API for
> > accessing the Windows Registry.
>
> Sounds very interesting, Ryan.  Just a couple questions about the 
> dictionary interface.

Thanks for you interest and suggestions, a couple of quick points below.

> I could see how you could map  numbers to DWORD, 2.x str/3.x bytes to 
> binary, and 2.x unicode/3.x str to REG_SZ.  But you don't document such 
> a translation, so it is unclear exactly what you actually do.  This 
> would be somewhat weird in 2.x, though, where str commonly would want to 
> map to String rather than Binary.
> 
> It seems almost necessary to add an explanation of whatever mapping is 
> presently done, to have complete documentation.

I guess I just ran out of steam on the documentation front :-)

Currently it maps integers to DWORD and anything else to REG_SZ.  The
idea of having a distinct Value class is to allow a more nuanced mapping
to be developed, but I haven't got down to the details of that yet - my
current application only requires REG_SZ.

> Thinking more, I wonder if it is possible to create objects of type 
> Value to put in the dictionary to allow specification of multistring and 
> expandablestring Registry types, but then the dictionary name would have 
> to be redundant with the name attribute in the Value object.  Maybe a 
> nameless value type could be invented, with just type and data attributes?

It certainly is, using syntax like:

  HKCU.foo.bar["key"] = Value("%SYSTEMROOT%/mydir",type=REG_EXPAND_SZ)}

Putting a nameless Value() instance in the initialisation dictionary
should also work (but as you note, there's no documentation or tests for
this yet...)


  Cheers,

 Ryan



-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why doesn't this work ? For loop variable scoping ?

2009-03-19 Thread Ryan Kelly
> newCylinderTempertature = newCylinderTemperature + deltaTemp

Take a careful look at the variable name here: "Tempertature".  Python's
dynamic nature provides a lot of wonderful benefits, but you've just hit
one of the drawbacks - you don't get any protection from typos in
variable names.


   Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
--
http://mail.python.org/mailman/listinfo/python-list


Re: Why is lambda allowed as a key in a dict?

2009-03-09 Thread Ryan Kelly
>Python 2.5.1 (r251:54863, Oct 30 2007, 13:45:26)
> [GCC 4.1.2 20070925 (Red Hat 4.1.2-33)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>> x = { }
> >>> x[lambda arg: arg] = 5
> >>> x[lambda arg: arg]
> Traceback (most recent call last):
>   File "", line 1, in 
> KeyError:  at 0x2abaab18>

I think the point is that function objects compare by object identity,
so the two lambdas you use above are not equal even though they have the
same code.  Consider:

>>> a = lambda arg: arg
>>> x = {}
>>> x[a] = 5
>>> x[a]
5
>>> x[lambda arg:arg]
Traceback (most recent call last):
  File "", line 1, in 
KeyError:  at 0xa06602c>
>>> 


  Cheers,

 Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
r...@rfk.id.au|  http://www.rfk.id.au/ramblings/gpg/ for details



signature.asc
Description: This is a digitally signed message part
--
http://mail.python.org/mailman/listinfo/python-list