Reputation: 1867
I am working on a python package chemcoord
with several subpackages, some of whom should be exposed to the root namespace.
The repository is here,
the relevant __init__.py
file is here.
For example there is a chemcoord.cartesian_coordinates.xyz_functions
that should be accessible as chemcoord.xyz_functions
Accessible, in particular, means that the user should be able to write:
from chemcoord.xyz_functions import allclose
If I write in my __init__.py
import chemcoord.cartesian_coordinates.xyz_functions as xyz_functions
then I can use chemcoord.xyz_functions
in the code, but I cannot do
from chemcoord.xyz_functions import allclose
If I do the additional ugly/hacky (?) trick of modifying sys.modules
in the __init__.py
as in
import sys
sys.modules["chemcoord.xyz_functions"] = xyz_functions
then I can write
from chemcoord.xyz_functions import allclose
But it feels ugly and hacky.
Recently I got warnings from PyLance
about
Import "chemcoord.xyz_functions" could not be resolved
Which leads to my two questions:
PyLance
, is there a bug in PyLance
?Upvotes: 1
Views: 62
Reputation: 20550
nit: # -*- coding: utf-8 -*-
hasn't been needed
in python source files for a very very long time,
given that it is default starting with interpreter 3.0.
And 3.8 went
EOL
last year,
so really you only need to worry about 3.9 and later.
And these seem odd:
... import Cartesian as Cartesian
,
... import Zmat as Zmat
I completely agree with you that the
sys.modules["chemcoord.xyz_functions"]
assignment is not appropriate.
And I agree that apps consuming the Public API
should be able to use a short
from chemcoord.xyz_functions import allclose, dot
.
Organizing everything under
src/
is very nice and I thank you for that.
The entire cartesian_coordinates/
folder
keeps things tidy for the package developer and makes good sense.
However, you might possibly wish to "hide" a code module
by renaming it to _xyz_functions.py
, with leading _
underscore.
(I don't know what promises you've made to app developers
in v2.1.2 and previous, which might require you to still expose
some or all of that.)
Focusing on the OP question, you complain that an app author currently cannot do
from chemcoord.xyz_functions import allclose
Honestly, it's very simple.
You're just a little hung up on that
src/chemcoord/cartesian_coordinates/xyz_functions.py
filename.
You're thinking that is the "right" location,
but it's just a private implementation detail,
separate from the Public API you choose to expose,
which plays into why we might want to hide it.
I claim that what you want to do, to answer the original question,
is instead of editing an __init__.py
module,
you want to create a new
src/chemcoord/xyz_functions.py
module.
It can pull in allclose(), dot(), etc., and
make them visible with conveniently short names for app authors.
$ pyright .
.)Upvotes: 2