[sugar] Re: Python Style Guide

Johan Dahlin jdahlin
Fri Nov 17 14:15:59 EST 2006


Ian Bicking wrote:
> Johan Dahlin wrote:
>>>>  >__init__.py files should generally contain no substantive code.
>>>> Instead they should import from >other modules. Importing from other
>>>> modules is done so that a package can provide a front-facing >set of
>>>> objects and functions it exports, without exposing each of the
>>>> internal modules in the >package. Note however that this causes the
>>>> submodules to be eagerly imported; if this is likely to >cause
>>>> unnecessary overhead then the import in __init__.py should be
>>>> reconsidered.
>>>>
>>>> Can you give an example of this? I think it would be useful to have it
>>>> on the guide too. Is it part of PEP-8 in any way?
>>> This was my addition.  __init__.py can be a little tricky, because it
>>> will swallow ImportErrors and maybe some other errors.  (This way if you
>>> __init__.py is broken, the entire package won't become unusable.)  For
>>> this reason I prefer not to put too much into those files.  Also I must
>>> admit an Emacs bias, where I like it when files tend to have more unique
>>> names than __init__; but I that's not a real justification ;)
>>
>> As an fellow Emacs user I used to share your opinion about unique
>> filenames
>> until I found that default emacs configuration is utterly broken.
>> Add this to your .emacs and you'll be happy:
>>
>> (setq uniquify-buffer-name-style 'post-forward-angle-brackets)
> 
> Huh; reading this page that does indeed sound like a better style
> http://www.delorie.com/gnu/docs/emacs/emacs_180.html -- but it isn't
> making any effect in my Emacs, and C-H v doesn't give any documentation
> for it :(

Oops, I forgot to mention that you also need this module loaded:

(require 'uniquify)

Checked using GNU Emacs 21.4 and 22.0.50.

>> After all, you're only going to write the code once, but lots of
>> people are
>> going to read and try to understand the code.

> And of course if it means not breaking backward compatibility you
> definitely should use this style -- e.g., if you moved from a module to
> a package, and factored your objects into different modules.

You can also use placeholder modules to provide backwards compatibility,
That's one of the few cases where I'd actually put code in __init__.py
files. It needs a little (tiny) bit of infrastructure to be done on demand,
but that's also desirable even if you use aliasing, you don't want
all sub-modules to be imported when you import a package, especially in
the large packages (10-15 modules or so)

> Also, I think there's reason to think of a packages "public" API, and
> that does not consist of every module in the package.  Some people are
> very conscientious about naming all their internal modules with leading
> _'s (CherryPy, for example)... which is actually reasonable, but
> something I've never done.  I tend to use documentation to indicate
> publicness.
> 
> Using imports in __init__ make that publicness more clear.  But I
> wouldn't argue strongly for it, unless you were maintaining a public
> interface in which case I'd argue strongly for it.

I agree, indicating publicness through documentation seems to be the sanest
approach. Anything undocumented is likely to lack proper design.

> Also, while the import makes it harder to track a name back from the
> source, in tracebacks it's always correct regardless of how many imports
> were involved in attaining the object.

Or just using a tool such as ctags/etags helps too, then you don't need to
worry where it's defined.

I'm only arguing that aliasing adds another layer of indirection for no
/obvious/ good reason.

>>>> *> Is _() always defined?
>>>>
>>>> Nope, I think you need to import it from gettext.
>>> OK; are we just using plain gettext for everything?  I've been
>>> encountering places where people use fancier _'s, but I think that's
>>> because in server-side apps you might be supporting multiple language
>>> simultaneously, which isn't an issue for OLPC.
>>>
>>> In some of these cases people often put _ in __builtins__.  Which seems
>>> convenient, except you end up doing this for portability:
>>
>> Putting it in __builtins__ break source code analyzers such as pyflakes,
>> pychecker.
>>
>> Modifying __builtins__ is always a bad idea, as it surprises people
>> not very familiar with the code.
> 
> I wouldn't really argue for that, but it has been a pattern I've seen
> for _ in particular.  I think part of the reason is that there are
> multiple _ implementations, and which one is used is often
> deployment-specific.  So importing from any particular module isn't
> really right, unless you expect that module to be monkeypatched based on
> the deployment.
> 
> My vague impression is that _ needs a better implementation than
> gettext's, with more consideration of threadlocal languages,
> registration of providers, and whatever else people are adding into
> their _ implementations.  But without much experience in the subject
> it's only something I'm detecting by smell ;)

Don't forget unicode handling; gettext doesn't quite work properly with
unicode, it always returns a string, regardless of the type of the input.
It might not matter in all applications, but in ours which happened to
use SQLObject and UnicodeCol it did.



More information about the Sugar-devel mailing list