Skip to content

Absolute/relative import not working? #43535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mitchchapman mannequin opened this issue Jun 21, 2006 · 11 comments
Closed

Absolute/relative import not working? #43535

mitchchapman mannequin opened this issue Jun 21, 2006 · 11 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@mitchchapman
Copy link
Mannequin

mitchchapman mannequin commented Jun 21, 2006

BPO 1510172
Nosy @Yhg1s, @ncoghlan
Files
  • package.tgz: Re-creation of PEP 328 example package structure
  • main_relative_imports.diff: Allow relative imports from main when -m is used
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/ncoghlan'
    closed_at = <Date 2007-12-03.13:03:08.768>
    created_at = <Date 2006-06-21.19:35:52.000>
    labels = ['interpreter-core', 'type-bug']
    title = 'Absolute/relative import not working?'
    updated_at = <Date 2007-12-03.13:03:08.767>
    user = 'https://bugs.python.org/mitchchapman'

    bugs.python.org fields:

    activity = <Date 2007-12-03.13:03:08.767>
    actor = 'ncoghlan'
    assignee = 'ncoghlan'
    closed = True
    closed_date = <Date 2007-12-03.13:03:08.768>
    closer = 'ncoghlan'
    components = ['Interpreter Core']
    creation = <Date 2006-06-21.19:35:52.000>
    creator = 'mitchchapman'
    dependencies = []
    files = ['2035', '2036']
    hgrepos = []
    issue_num = 1510172
    keywords = []
    message_count = 11.0
    messages = ['28851', '28852', '28853', '28854', '28855', '28856', '28857', '28858', '28859', '28860', '58121']
    nosy_count = 6.0
    nosy_names = ['twouters', 'nnorwitz', 'mitchchapman', 'ncoghlan', 'zseil', 'mnot']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue1510172'
    versions = ['Python 2.6']

    @mitchchapman
    Copy link
    Mannequin Author

    mitchchapman mannequin commented Jun 21, 2006

    Trying to import from a module using dotted import syntax produces
    this exception:

    ValueError: Relative importpath too deep

    This behavior has been confirmed on Mac OS X 10.4 using the Python
    2.5b1 disk image; and on CentOS 4 using the Python 2.5b1 source
    tarball.

    The exception is raised regardless of whether the PYTHONPATH
    environment variable can see the toplevel directory of the package
    being tested; regardless of whether the import is performed from an
    interactive Python session or from a script invoked from the command
    line; and regardless of whether the main script starts with

    from __future__ import absolute_import

    To test, I tried to re-create the package structure used as an example
    in PEP-328. (See attachments.)

    Most of the files were empty, except moduleX.py and moduleY.py:

    #moduleX.py:
    from __future__ import absolute_import
    
    from .moduleY import spam
    
    #moduleY.py:
    spam = "spam"

    According to the PEP, if should be possible to import moduleX without
    error. But I get the above exception whenever I try to import moduleX
    or to run it from the command line.

    $ python2.5 moduleX.py 
    Traceback (most recent call last):
      File "moduleX.py", line 3, in <module>
        from .moduleY import spam
    ValueError: Relative importpath too deep

    Is this a usage/documentation error?

    @mitchchapman mitchchapman mannequin assigned ncoghlan Jun 21, 2006
    @mitchchapman mitchchapman mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Jun 21, 2006
    @mitchchapman mitchchapman mannequin assigned ncoghlan Jun 21, 2006
    @mitchchapman mitchchapman mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Jun 21, 2006
    @mnot
    Copy link
    Mannequin

    mnot mannequin commented Jun 21, 2006

    Logged In: YES
    user_id=21868

    Seeing the same behaviour; OSX with the installer.

    @zseil
    Copy link
    Mannequin

    zseil mannequin commented Jun 21, 2006

    Logged In: YES
    user_id=1326842

    I think this is a usage error. The problem is that
    you run moduleX as a script. This puts the module's
    directory as the first entry in sys.path (see
    http://docs.python.org/dev/lib/module-sys.html#l2h-5058
    for detais).
    As a consequence, moduleX is recognised as a top
    level module, not as part of a package.

    If you want to test relative import, try opening an
    interactive shell in the directory where package
    resides, and type:

    >>> from package.subpackage1 import moduleX
    >>> moduleX.spam
    'spam'

    @mitchchapman
    Copy link
    Mannequin Author

    mitchchapman mannequin commented Jun 21, 2006

    Logged In: YES
    user_id=348188

    Hm... but the same error occurs if one tries to import moduleX from an
    interactive Python session, or from a sibling module.

    In other words, in 2.5b1 any module which uses relative imports can be used
    only as a fully-qualified member of a package. It cannot be imported directly
    by a sibling module, and it cannot be used as a main module at all:

    $ python2.5 -m package.subpackage1.moduleX
    ...
        from .moduleY import spam
    ValueError: Relative importpath too deep

    Given other efforts (PEP-299; PEP-338) to make it easier to use modules both
    as mainlines and as imports, I still think this is a bug.

    @Yhg1s
    Copy link
    Member

    Yhg1s commented Jun 23, 2006

    Logged In: YES
    user_id=34209

    See the discussion started at:
    http://mail.python.org/pipermail/python-dev/2006-June/066161.html

    It's not a bug in 328 or 338 (the PEP that adds the -m
    switch for packages), but in the interaction between the
    two. I don't think this will be fixed for 2.5, since there
    is no obvious fix. If it hurts when you press there, don't
    press there. Either don't use -m for packaged modules, or
    have the packaged module only use absolute imports. (But
    don't be surprised if the script-module is imported twice,
    once as __main__ and once as the module itself. That's a
    whole other bug/feature.)

    @nnorwitz
    Copy link
    Mannequin

    nnorwitz mannequin commented Jun 27, 2006

    Logged In: YES
    user_id=33168

    http://mail.python.org/pipermail/python-dev/2006-June/066197.html

    Nick you made mention of changing the docs, but I'm not sure
    if you did or not. Could you address this bug? Thanks.

    @ncoghlan
    Copy link
    Contributor

    Logged In: YES
    user_id=1038590

    The issue isn't actually unique to the -m switch - the
    problem is that relative imports are based on __name__, and
    in the main module, __name__ always has the value
    '__main__'. Hence, relative imports currently can't work
    properly from the main module of an application, because the
    main module doesn't know where it really fits in the Python
    module namespace (this is at least fixable in theory for the
    main modules executed through the -m switch, but directly
    executed files and the interactive interpreter are
    completely out of luck).

    With the old implicit relative imports this behaviour is
    masked by the fact that executing a module puts that
    module's directory on sys.path. When you execute a module in
    a package directly, it actually imports its sibling modules
    as top-level modules. The fact that the -m switch doesn't
    allow this to occur is a deliberate design decision (putting
    package directories on the system level path is a bad idea
    because you can get multiple copies of the same module under
    different names).

    You should be able get something similar to the old implicit
    relative import behaviour by sticking the following at the
    top of your module (before doing any relative imports):

    if __name__ = '__main__':
       from os.path import dirname
       __path__ = [dirname(__file__)]
       del dirname

    This makes the relative import machinery treat your main
    module as a package. The problem with this workaround is
    that, just like the old situation with implicit relative
    imports from the main module, you may end up with two
    different copies of the sibling modules in sys.modules. One
    copy will be '__main__.foo' while the other will be
    'package.foo' (with implicit relative imports, the first
    copy would have been a top level module called 'foo').

    When I went to document this, I got stuck on the fact that
    section 6 of the tutorial hasn't been updated for PEP-328 at
    *all*. And the language ref palms the details off on to
    Guido's packages essay. So describing the limitation in the
    real documentation entails documenting PEP-328 properly in
    the first place (which I'm *not* volunteering to do :).

    However, I'll add a section to PEP-328 about '__main__' and
    relative imports (including the workaround to get something
    similar to the old behaviour back).

    @ncoghlan
    Copy link
    Contributor

    Logged In: YES
    user_id=1038590

    All that said, PEP-328 currently says that "from ...sys
    import path" should be legal from moduleX in the example.

    I tried it, and it currently fails - the ValueError gets
    raised as soon as the number of dots in the relative path
    exceeds the number of dots in __name__, instead of treating
    a single excess dot as requesting an absolute import
    instead. (All of the other examples in the PEP work as
    specified when moduleX and subpackage1 are imported rather
    than executed directly)

    I believe fixing this would also fix Mitch's problem - an
    explicit relative import from __main__ would be treated as a
    top level import.

    I also have an idea regarding the -m switch that I will
    raise on python-dev.

    @ncoghlan
    Copy link
    Contributor

    Logged In: YES
    user_id=1038590

    Patch attached that allows relative imports from a main
    module to work so long as:
    a. the top level package is either in the current
    directory or somewhere else on sys.path; and
    b. the module is executed using -m so Python knows where
    it fits in the package hierarchy

    So to get the PEP-328 example to work, you'd have to run it as:

    $python2.5 -m package.subpackage1.moduleX

    The patch relies on a feature added to runpy in rev 47142
    (post beta 1). I've added a question to PEP-356 as to how
    this should be handled, since we're technically in feature
    freeze.

    Patch attached directly to the bug report because it's
    stupidly early in the morning and I don't feel like dealing
    with SF and then copying the patch tracker number here :)

    @ncoghlan
    Copy link
    Contributor

    Logged In: YES
    user_id=1038590

    Punting on this until 2.6. See updated PEP-338 for the gory
    details.

    @ncoghlan
    Copy link
    Contributor

    ncoghlan commented Dec 3, 2007

    PEP-366 has been implemented for 2.6, which fixes this bug. The fix
    turned out to be quite invasive (hence the PEP), so it won't be
    backported to 2.5.

    @ncoghlan ncoghlan closed this as completed Dec 3, 2007
    @ncoghlan ncoghlan added the type-bug An unexpected behavior, bug, or error label Dec 3, 2007
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants