My package, available at https://github.com/jab/bidict, is currently laid out 
like this:

bidict/
├── __init__.py
├── _bidict.py
├── _common.py
├── _frozen.py
├── _loose.py
├── _named.py
├── _ordered.py
├── compat.py
├── util.py


I'd like to get some more feedback on a question about this layout that I 
originally asked here: 
<https://github.com/jab/bidict/pull/33#issuecomment-193877248>:

What do you think of the code layout, specifically the use of the _foo modules? 
It seems well-factored to me, but I haven't seen things laid out this way very 
often in other projects, and I'd like to do this as nicely as possible.

It does kind of bug me that you see the _foo modules in the output when you do 
things like this:

>>> import bidict
>>> bidict.bidict
<class 'bidict._bidict.bidict'>
>>> bidict.KeyExistsError
<class 'bidict._common.KeyExistsError'>


In https://github.com/jab/bidict/pull/33#issuecomment-205381351 a reviewer 
agrees:

"""
Me too, and it confuses people as to where you should be importing things from 
if you want to catch it, inviting code like

```
import bidict._common

try:
    ...
except bidict._common.KeyExistsError:
    ...
```
ie. becoming dependent on the package internal structure.

I would be tempted to monkey-patch .__module__ = __name__ on each imported 
class to get around this. Maybe there are downsides to doing magic of that 
kind, but dependencies on the internals of packages are such a problem for me 
in our very large codebase, that I'd probably do it anyway in order to really 
explicit about what the public API is.
"""

Curious what folks on this list recommend, or if there are best practices about 
this published somewhere.

Thanks,
Josh
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to