Skip to content
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

relative import broken #52150

Closed
gangesmaster mannequin opened this issue Feb 10, 2010 · 11 comments
Closed

relative import broken #52150

gangesmaster mannequin opened this issue Feb 10, 2010 · 11 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker

Comments

@gangesmaster
Copy link
Mannequin

gangesmaster mannequin commented Feb 10, 2010

BPO 7902
Nosy @loewis, @warsaw, @brettcannon, @florentx, @meadori
Files
  • bar.py
  • issue-7902.patch: patch against 2.7 trunk
  • 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/brettcannon'
    closed_at = <Date 2010-08-16.19:11:12.103>
    created_at = <Date 2010-02-10.19:09:21.579>
    labels = ['interpreter-core', 'release-blocker']
    title = 'relative import broken'
    updated_at = <Date 2010-08-16.22:44:22.198>
    user = 'https://bugs.python.org/gangesmaster'

    bugs.python.org fields:

    activity = <Date 2010-08-16.22:44:22.198>
    actor = 'flox'
    assignee = 'brett.cannon'
    closed = True
    closed_date = <Date 2010-08-16.19:11:12.103>
    closer = 'barry'
    components = ['Interpreter Core']
    creation = <Date 2010-02-10.19:09:21.579>
    creator = 'gangesmaster'
    dependencies = []
    files = ['16201', '16350']
    hgrepos = []
    issue_num = 7902
    keywords = ['patch', 'needs review']
    message_count = 11.0
    messages = ['99176', '99177', '99179', '100006', '106065', '106179', '113926', '114048', '114065', '114067', '114082']
    nosy_count = 7.0
    nosy_names = ['loewis', 'barry', 'brett.cannon', 'gangesmaster', 'flox', 'meador.inge', 'Oren_Held']
    pr_nums = []
    priority = 'release blocker'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue7902'
    versions = ['Python 2.6']

    @gangesmaster
    Copy link
    Mannequin Author

    gangesmaster mannequin commented Feb 10, 2010

    the relative-import mechanism is broken... at least on python2.6 but i'd guess on later versions as well.

    consider this package layout:
    /tmp/foo/
    /tmp/foo/init.py
    /tmp/foo/bar.py

    where bar.py is:
    # note this is a relative import and should fail!
    from .os import walk
    print walk
    # and this should also fail
    from . import os
    print os

    running it yields a bug:

    $ PYTHONPATH="/tmp" python
    Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15) 
    [GCC 4.4.1] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import foo.bar
    <function walk at 0xb7d2aa04>  # <<<< ?!?!
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/tmp/foo/bar.py", line 4, in <module>
        from . import os
    ImportError: cannot import name os

    "from . import os" fails as expected, but "from .os import walk" works -- although it should obviously fail too.

    -tomer

    @gangesmaster gangesmaster mannequin added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Feb 10, 2010
    @gangesmaster
    Copy link
    Mannequin Author

    gangesmaster mannequin commented Feb 10, 2010

    i believe brett is in charge of this, adding him to the noisy. sorry if it's not you :)

    @brettcannon
    Copy link
    Member

    So doing the import manually through __import__('os', globals(), locals(), ['walk'], 1) does not work. My guess is it has something to do with the IMPORT_FROM opcode (or something related), but I don't have time right now to dig deeper.

    @meadori
    Copy link
    Member

    meadori commented Feb 24, 2010

    So doing the import manually through __import__('os', globals(),
    locals(), ['walk'], 1) does not work.

    I get the same behavior for this reproduction case regardless of whether I use:
    import .os import walk
    or:
    __import__('os', globals(), locals(), ['walk'], 1)
    The bug is reproducible in the trunk.

    I think the problem has to do with 'import_module_level' incorrectly doing an absolute lookup for 'os' when the relative lookup in 'foo' fails. I have attached a patch with the relevant fix and test case.

    @meadori
    Copy link
    Member

    meadori commented May 19, 2010

    Does this patch seem reasonable?

    @brettcannon brettcannon self-assigned this May 19, 2010
    @brettcannon
    Copy link
    Member

    Thanks for the patch, Meador. All I did was tweak the test slightly. Committed in:

    + 2.7: r81380
    + 2.6: r81381

    @loewis
    Copy link
    Mannequin

    loewis mannequin commented Aug 14, 2010

    Backporting this change to 2.6 has created an incompatibility in that branch, see for example bpo-9600. Apparently, it will only break code that is "conceptually wrong", but still "worked" on 2.6.

    I'll suggest that this is a release-critical issue for 2.6.6. It should be considered whether the incompatibility is accepted, or fixed, or reverted.

    @loewis loewis mannequin reopened this Aug 14, 2010
    @loewis loewis mannequin added the release-blocker label Aug 14, 2010
    @florentx
    Copy link
    Mannequin

    florentx mannequin commented Aug 16, 2010

    Btw, the comment and failure message in r81380/r81381 look wrong.

    -    # If absolute import syntax is used, then do not try to perform
    -    # a relative import in the face of failure.
    +    # If explicit relative import syntax is used, then do not try
    +    # to perform an absolute import in the face of failure.
         self.fail("explicit relative import triggered "
    -              "an implicit relative import")
    +              "an implicit absolute import")

    In addition the TestCase.assertRaises method could be used:

        def test_absolute_import_without_future(self):
            # If explicit relative import syntax is used, then do not try
            # to perform a relative import in the face of failure.
            # Issue python/cpython#52150.
            with self.assertRaises(ImportError):
                from .os import sep
                self.fail("explicit relative import triggered an "
                          "implicit absolute import")

    @florentx
    Copy link
    Mannequin

    florentx mannequin commented Aug 16, 2010

    Comment changed in r84097, 3.2 branch, with minor fixes.

    @warsaw
    Copy link
    Member

    warsaw commented Aug 16, 2010

    Guido has spoken: http://mail.python.org/pipermail/python-dev/2010-August/103104.html

    We'll keep the change for 2.6.6rc2.

    @warsaw warsaw closed this as completed Aug 16, 2010
    @florentx
    Copy link
    Mannequin

    florentx mannequin commented Aug 16, 2010

    Merged in 3.1 with r84115.

    @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) release-blocker
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants