[Python-Dev] Package Style Guide

Gordon McMillan gmcm@hypernet.com
Thu, 8 Jun 2000 10:48:01 -0400


Andy wrote:

> 1. use of __init__ to save users work
[package structure]
> reportlab
>     pdfgen
>         canvas.py  defines class Canvas
>         textobject.py defines class TextObject
>         pathobject.py defines class PathObject
>     platypus
>         (the same problem, but 3x worse)
>     lib
>         (loads of modules, all independent)

> ---reportlab/pdfgen/__init__.py--------
> from canvas import Canvas
> from textobject.py import TextObject
> from pathobject.py impory PathObject

I would suggest that these not use relative names. 

from reportlab.pdfgen.canvas import Canvas

will ensure that Canvas is only found in one way (no matter 
where the script is, or rather, what sys.path[0] evaluates to at 
import time).

Your other choice is to disallow any scripts within reportlab/ 
and deliver 220 V shocks to any user who starts Python 
anyplace within reportlab/ (or otherwise lets any part of 
sys.path evaluate to anything within reportlab/).
 
> Then users can just do:
> from reportlab.pdfgen import Canvas, PathObject, TextObject
> 
> It seems that this (a) makes life easier for users, and
> (b) gives us freedom to refactor code as it grows, without
> changing the user interface.  

Since you're doing this for "convenience", another option is to 
provide convenience methods:

def newCanvas():
  return reportlab.pdfgen.canvas.Canvas()

> 2. Ambiguities running scripts within package
> ---------------------------------------------

> Should test scripts all be moved out of the package?  
> Indeed, is Python behaving the way it ought to?

If you use relative imports, yes. But even so, you incur a risk 
in using relative imports (see above). And you only do it from 
laziness. So I say don't use relative imports.

> 3. Preferred subpackage import technique
> ----------------------------------------
> I have two scripts 'spam.py' and 'eggs.py' in
> subpackage 'A.B'.  spam imports eggs.
> Should it say...
>    import eggs
> or...
>    import A.B.eggs?

You know what I'm going to say...

- Gordon