简体   繁体   中英

ImportError when using import as

I have the following layout for my project:

chemcoord/
    __init__.py
    cartesian_coordinates/
        xyz_functions.py
        cartesian_class_main.py
        ...
    ...
docs/
    sources/
        conf.py
        cartesian_coordinates.rst
        src_xyz_function1/
            chemcoord.cartesian_coordinates.xyz_functions.view.rst
            ...
        ...
    ...

My package has a setup.py script, was installed via pip install -e and is available in the PYTHONPATH . Nevertheless I also put: sys.path.insert(0, os.path.abspath(u'../../')) into the Sphinx conf.py file.

In the __init__.py I import:

from chemcoord.cartesian_coordinates.cartesian_class_main import Cartesian
from chemcoord.cartesian_coordinates import xyz_functions
# the import of pew is just for testing purposes
from chemcoord.cartesian_coordinates import xyz_functions as pew

One function in xyz_functions.py is called eg view . And if I do this in my Ipython console all functions are defined:

 import chemcoord as cc
 cc.cartesian_coordinates.xyz_functions.view
 cc.xyz_functions.view
 cc.pew.view

The following sphinx code in the cartesian_coordinates.rst file should document the Cartesian and the xyz_functions

Cartesian coordinates
===================================



.. currentmodule:: chemcoord


The ``Cartesian`` class which is used to represent
a molecule in cartesian coordinates.

.. autosummary::
    :toctree: src_Cartesian

    ~Cartesian



A collection of functions operating on instances of ``Cartesian``.

.. currentmodule:: chemcoord.cartesian_coordinates.xyz_functions

.. autosummary::
    :toctree: src_xyz_functions1

    ~isclose
    ~read
    ~write
    ~view


A collection of functions operating on instances of ``Cartesian``.

.. currentmodule:: chemcoord

.. autosummary::
    :toctree: src_xyz_functions2

    ~xyz_functions.isclose
    ~xyz_functions.read
    ~xyz_functions.write
    ~xyz_functions.view


A collection of functions operating on instances of ``Cartesian``.

.. currentmodule:: chemcoord

.. autosummary::
    :toctree: src_xyz_functions3

    ~pew.isclose
    ~pew.read
    ~pew.write
    ~pew.view

I generate the stub rst files via sphinx-autogen and they look like:

chemcoord.cartesian_coordinates.xyz_functions.view
==================================================

.. currentmodule:: chemcoord.cartesian_coordinates.xyz_functions

.. autofunction:: view

Now the really strange thing is, that the parts with: chemcoord.cartesian_coordinates.xyz_functions and chemcoord.Cartesian are documented, but I get an ImportError for the documentation parts with: chemcoord.xyz_functions and chemcoord.pew and they are not documented. The stub rst files were created by sphinx-autogen in all cases. Does anyone have an Idea how to tackle this problem?

The intended usage for the end user is:

 import chemcoord as cc
 cc.xyz_functions.view(...)

For this reason I want to document it with xyz_functions in the namespace of chemcoord .

Edit 1 (Clarifying because of answer of @LaurentLaport):

Also if I write in the cartesian_coordinates.rst file the following, it still does not work:

Cartesian coordinates
===================================



.. currentmodule:: chemcoord


The ``Cartesian`` class which is used to represent
a molecule in cartesian coordinates.

.. autosummary::
    :toctree: src_Cartesian

    ~Cartesian



A collection of functions operating on instances of ``Cartesian``.

.. currentmodule:: chemcoord

.. autosummary::
    :toctree: src_xyz_functions2

    ~xyz_functions.isclose
    ~xyz_functions.read
    ~xyz_functions.write
    ~xyz_functions.view

The packages chemcoord.xyz_functions and chemcoord.pew are only references (or aliases) to the package chemcoord.cartesian_coordinates.xyz_functions which is already documented.

This is why it doesn't work.

I created an Issue on the sphinx webpage where they gave me a working solution. I am still not sure, if it is a clean solution though.

The trick was to fake the module system with the following lines in the __init__.py file:

import sys
sys.modules['chemcoord.xyz_functions'] = xyz_functions

The explanation is straightforward :

import Y in module X makes Y an attribute of X module. It does not mean converting Y to XY module. On the other hand, import XY tries to load XY module, not Y attribute of X module. As a result, it failed to import.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM