Setuptools, __init__ and __main__

Dave Angel davea at davea.name
Fri Feb 6 16:44:26 EST 2015


On 02/06/2015 04:35 PM, Ben Finney wrote:
> Rob Gaddi <rgaddi at technologyhighland.invalid> writes:
>
>> So I'm trying to wrap my head around packaging issues
>
> Congratulations on tackling this. You will likely find the Python
> Packaging User Guide <URL:https://packaging.python.org/> helpful.
>
> Also know that Python packaging was in a terrible state for a long
> stretch of years, but now the Python Packaging Authority exists
> <URL:https://www.pypa.io/> which has tended to steadily improve the
> ecosystem in recent years.
>
>> I'm developing applications of various size for internal deployment.
>> When I'm actually getting the whole thing written, I've got my
>> initialization stub in __main__.py, because it's an application rather
>> than a library. But then when I migrated over to setuptools I had to
>> switch it to __init__.py and change around all my import statements to
>> compensate. Then I can reference it as an entry point.
>
> Yes, it's one of the enduring bad parts of Python that it makes the
> command-line invocation of an application overly awkward.
>
> What do you mean by “initialization stub”? That could mean a lot of
> different things, and I don't want to guess what you mean.
>
> As for the difference between library versus application: You should be
> writing all your code as discretely-testable units anyway, and unit
> tests should be importing those in order to test them. So the whole lot
> needs to be in a package hierarchy of some form in order to do that.
>
> That said, I haven't made use of the “execute a directory as a program”
> Python feature, so I might be misunderstanding what the problem is.
>
>> This feels silly. I'm sure I could go stumbling around until I come up
>> with an elegant solution, but does anyone already have one?
>
> It seems to me the problem is avoidable by ensuring from the start that
> all your code is importable by your unit tests; that way, it's ready for
> a Setuptools entry point declaration without changes.
>

To this I'd like to add the caveat that both __init__.py and __main__.py 
are reserved names, and putting arbitrary code in either one is quite risky.

I suspect you're putting library code in your application code file, and 
naming it __main__ because that way you can cheat around the recursive 
import restrictions.  Please don't do that.

Organize your code so that there are no loops in the import library 
hierarchy.  If that means your application file is only six lines, so be it.

And don't name any source code __main__.py,

Finally, the mere presence of __init__.py has a special meaning, and 
code in it should probably be limited to doing namespace munging that a 
package may require to keep its public interface simpler.


-- 
DaveA



More information about the Python-list mailing list