jorgenschaefer / elpy

Emacs Python Development Environment
GNU General Public License v3.0
1.9k stars 261 forks source link

Error in jedi completion #819

Closed Kurvivor19 closed 8 years ago

Kurvivor19 commented 8 years ago

Elpy Error

The backend encountered an unexpected error. This indicates a bug in Elpy. Please open a bug report with the data below in the Elpy bug tracker:

https://github.com/jorgenschaefer/elpy/issues/new

Error Message

'Class' object has no attribute 'is_generator'

Configuration

Virtualenv........: None
RPC Python........: 2.7.10 (/usr/bin/python)
Interactive Python: python (/usr/bin/python)
Emacs.............: 24.5.1
Elpy..............: 1.11.0
Jedi..............: 0.9.0
Rope..............: Not found (0.10.3 available)
Importmagic.......: Not found (0.1.3 available)
Autopep8..........: Not found (1.2.2 available)
Yapf..............: Not found (0.6.2 available)
Syntax checker....: pyflakes (/usr/bin/pyflakes)

Traceback

Traceback (most recent call last):
  File "/home/Kurvivor/.emacs.d/elpa/elpy-20160131.118/elpy/jedibackend.py", line 341, in run_with_debug
    return getattr(script, name)()
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/api/__init__.py", line 188, in completions
    completion_names = get_completions(user_stmt, b)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/api/__init__.py", line 174, in get_completions
    completion_names += self._simple_complete(path, dot, like)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/api/__init__.py", line 250, in _simple_complete
    scopes = list(self._prepare_goto(path, True))
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/api/__init__.py", line 294, in _prepare_goto
    scopes = self._evaluator.eval_element(eval_stmt)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/cache.py", line 41, in wrapper
    rv = function(obj, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 187, in eval_element
    types = self.eval_trailer(types, trailer)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 257, in eval_trailer
    new_types += self.find_types(typ, node)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 120, in find_types
    return f.find(scopes, search_global)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/debug.py", line 52, in wrapper
    result = func(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/finder.py", line 87, in find
    types = self._names_to_types(names, search_global)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/finder.py", line 233, in _names_to_types
    new_types = _name_to_types(self._evaluator, name, self.scope)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/cache.py", line 41, in wrapper
    rv = function(obj, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/finder.py", line 278, in _name_to_types
    types += _remove_statements(evaluator, typ, name)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/finder.py", line 323, in _remove_statements
    types += evaluator.eval_statement(stmt, seek_name=name)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/cache.py", line 41, in wrapper
    rv = function(obj, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/recursion.py", line 23, in run
    result = func(evaluator, stmt, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/debug.py", line 52, in wrapper
    result = func(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 135, in eval_statement
    types = self.eval_element(stmt.get_rhs())
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/cache.py", line 41, in wrapper
    rv = function(obj, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 187, in eval_element
    types = self.eval_trailer(types, trailer)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 259, in eval_trailer
    new_types += self.execute(typ, node, trailer)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/debug.py", line 52, in wrapper
    result = func(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/__init__.py", line 299, in execute
    types = func(self, arguments)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/representation.py", line 364, in py__call__
    return Function.py__call__(self, evaluator, params)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/_compatibility.py", line 122, in <lambda>
    return lambda *args, **kwargs: self.func(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/jedi-0.9.0-py2.7.egg/jedi/evaluate/representation.py", line 557, in py__call__
    if self.base.is_generator():
AttributeError: 'Class' object has no attribute 'is_generator'

Jedi Debug Information

[N] dbg: Parsed /cygdrive/c/Users/Kurvivor/Development/hq_git/builder/games/wh40k/renegades/hq.py, with 0 parsers in 29 splits.
[W] warning: No statement under the cursor.
[N] dbg: start: u'self.wep2' in <Function: check_rules@165-170>
[N] dbg: eval_element Node(power, [<Name: self@169,18>, Node(trailer, [<Operator: .>, <Name: wep2@169,23>])])@(169, 18)
[N] dbg: finder.filter_name "<Name: self@169,18>" in (<eFunction of <Function: check_rules@165-170>>): u'[<Name: self@165,20>]'@(169, 18)
[N] dbg: finder._names_to_types: [<Name: self@165,20>] -> [<eInstance of <eClass of <Class: RenegadeCommand@43-170>>(<Arguments: ()>)>]
[N] dbg: eval_trailer: Node(trailer, [<Operator: .>, <Name: wep2@169,23>]) in scope <eInstance of <eClass of <Class: RenegadeCommand@43-170>>(<Arguments: ()>)>
[N] dbg: eval_element <Name: Unit@43,22>@(43, 22)
[N] dbg: finder.filter_name "<Name: Unit@43,22>" in (<eClass of <Class: RenegadeCommand@43-170>>): u'[<Name: Unit@4,39>]'@(43, 22)
[N] dbg: search_module 'builder' in u'/cygdrive/c/Users/Kurvivor/Development/hq_git/builder/games/wh40k/renegades/hq.py'
[N] dbg: search_module 'builder.games' in paths ['/cygdrive/c/Users/Kurvivor/Development/hq_git/builder']
[N] dbg: search_module 'builder.games.wh40k' in paths ['/cygdrive/c/Users/Kurvivor/Development/hq_git/builder/games']
[N] dbg: search_module 'builder.games.wh40k.roster' in paths ['/cygdrive/c/Users/Kurvivor/Development/hq_git/builder/games/wh40k']
[N]  dbg: finder.filter_name "u'Unit'" in (<ModuleWrapper: <fast.FastModule: roster@1-376>>): u'[<Name: Unit@2,34>]'@None
[N]  dbg: search_module 'builder.core2' in paths ['/cygdrive/c/Users/Kurvivor/Development/hq_git/builder']
[N]   dbg: finder.filter_name "u'Unit'" in (<ModuleWrapper: <fast.FastModule: core2@1-8>>): u'[<Name: Unit@2,17>]'@None
[N]   dbg: search_module 'unit' in '/cygdrive/c/Users/Kurvivor/Development/hq_git/builder/core2/__init__.py'
[N]    dbg: finder.filter_name "u'Unit'" in (<ModuleWrapper: <fast.FastModule: unit@1-242>>): u'[<Name: Unit@10,6>]'@None
[N]    dbg: finder._names_to_types: [<FakeName: Unit@10,6>] -> [<eClass of <Class: Unit@10-170>>]
[N]   dbg: after import: [<eClass of <Class: Unit@10-170>>]
[N]   dbg: finder._names_to_types: [<Name: Unit@2,17>] -> [<eClass of <Class: Unit@10-170>>]
[N]  dbg: after import: [<eClass of <Class: Unit@10-170>>]
[N]  dbg: finder._names_to_types: [<Name: Unit@2,34>] -> [<eClass of <Class: Unit@10-170>>]
[N] dbg: after import: [<eClass of <Class: Unit@10-170>>]
[N] dbg: finder._names_to_types: [<Name: Unit@4,39>] -> [<eClass of <Class: Unit@10-170>>]
[N] dbg: eval_element <Name: Node@10,11>@(10, 11)
[N] dbg: finder.filter_name "<Name: Node@10,11>" in (<eClass of <Class: Unit@10-170>>): u'[<Name: Node@4,17>]'@(10, 11)
[N] dbg: search_module 'node' in '/cygdrive/c/Users/Kurvivor/Development/hq_git/builder/core2/unit.py'
[N]  dbg: finder.filter_name "u'Node'" in (<ModuleWrapper: <fast.FastModule: node@1-159>>): u'[<Name: Node@68,6>]'@None
[N]  dbg: finder._names_to_types: [<FakeName: Node@68,6>] -> [<eClass of <Class: Node@68-158>>]
[N] dbg: after import: [<eClass of <Class: Node@68-158>>]
[N] dbg: finder._names_to_types: [<Name: Node@4,17>] -> [<eClass of <Class: Node@68-158>>]
[N] dbg: eval_element <Name: object@68,11>@(68, 11)
[N] dbg: finder.filter_name "<Name: object@68,11>" in (<eClass of <Class: Node@68-158>>): u'[<CompiledName: (__builtin__).object>]'@(68, 11)
[N] dbg: finder._names_to_types: [<CompiledName: (__builtin__).object>] -> [<CompiledObject: <type 'object'>>]
[N] dbg: execute: <eClass of <Class: Unit@10-170>> <Arguments: ()>
[N]  dbg: execute: <InstanceElement of <eFunction of <Function: __init__@14-30>>> <Arguments: ()>
[N]  dbg: execute result: [] in <InstanceElement of <eFunction of <Function: __init__@14-30>>>
[N] dbg: execute result: [<eInstance of <eClass of <Class: Unit@10-170>>(<Arguments: ()>)>] in <eClass of <Class: Unit@10-170>>
[N] dbg: execute: <eClass of <Class: Node@68-158>> <Arguments: ()>
[N]  dbg: execute: <InstanceElement of <eFunction of <Function: __init__@69-77>>> <Arguments: ()>
[N]  dbg: execute result: [] in <InstanceElement of <eFunction of <Function: __init__@69-77>>>
[N] dbg: execute result: [<eInstance of <eClass of <Class: Node@68-158>>(<Arguments: ()>)>] in <eClass of <Class: Node@68-158>>
[N] dbg: finder.filter_name "<Name: wep2@169,23>" in (<eInstance of <eClass of <Class: RenegadeCommand@43-170>>(<Arguments: ()>)>): u'[<InstanceName: wep2@160,13>]'@None
[N]  dbg: eval_statement <InstanceElement of <ExprStmt:         self.wep2 = self.Weapon(self, "Voxbearer's weapon")@160,8>> (<InstanceName: wep2@160,13>)
[N]  dbg: eval_element <InstanceElement of Node(power, [<Name: self@160,20>, Node(trailer, [<Operator: .>, <Name: Weapon@160,25>]), Node(trailer, [<Operator: (>, Node(arglist, [<Name: self@160,32>, <Operator: ,>, <String: "Voxbearer's weapon">]), <Operator: )>])])>@(160, 20)
[N]   dbg: finder.filter_name "<InstanceName: self@160,20>" in (<InstanceElement of <eFunction of <Function: __init__@154-165>>>): u'[<Name: self@154,17>]'@(160, 8)
[N]   dbg: finder._names_to_types: [<Name: self@154,17>] -> [<eInstance of <eClass of <Class: RenegadeCommand@43-170>>(<Arguments: ()>)>]
[N]  dbg: eval_trailer: <InstanceElement of Node(trailer, [<Operator: .>, <Name: Weapon@160,25>])> in scope <eInstance of <eClass of <Class: RenegadeCommand@43-170>>(<Arguments: ()>)>
[N]   dbg: finder.filter_name "<InstanceName: Weapon@160,25>" in (<eInstance of <eClass of <Class: RenegadeCommand@43-170>>(<Arguments: ()>)>): u'[<InstanceName: Weapon@147,10>]'@None
[N]   dbg: finder._names_to_types: [<InstanceName: Weapon@147,10>] -> [<InstanceElement of <eClass of <Class: Weapon@147-154>>>]
[N]  dbg: eval_trailer: <InstanceElement of Node(trailer, [<Operator: (>, Node(arglist, [<Name: self@160,32>, <Operator: ,>, <String: "Voxbearer's weapon">]), <Operator: )>])> in scope <InstanceElement of <eClass of <Class: Weapon@147-154>>>
[N]   dbg: execute: <InstanceElement of <eClass of <Class: Weapon@147-154>>> <Arguments: <InstanceElement of Node(arglist, [<Name: self@160,32>, <Operator: ,>, <String: "Voxbearer's weapon">])>>

Reproduction:

import jedi

source = '''\
__author__ = 'Ivan Truskov'

from builder.games.wh40k.roster import Unit
from builder.core2 import OptionsList, OneOf, Gear, SubUnit,\
    Count, OptionalSubUnit
from transport import Chimera

class Devotions(OptionsList):
    def __init__(self, parent):
        super(Devotions, self).__init__(parent, 'Devotions')
        self.witch = self.variant('Primaris-rogue Witch', 35)
        self.ml2 = self.variant('Mastery level 2', 25)
        self.mutant = self.variant('Mutant Overlord', 15)
        self.horde = self.variant('Master of the Horde', 20)
        self.che = self.variant('Arch-heretic Revolutionary', 25)
        self.magus = self.variant('Heretek Magus', 30)
        self.reaver = self.variant('Bloody-handed Reaver', 20)

    def check_rules(self):
        super(Devotions, self).check_rules()
        OptionsList.process_limit([self.witch, self.mutant, self.horde,
                                   self.che, self.magus, self.reaver], 1)
        self.ml2.value = self.ml2.value and self.witch.value
        self.ml2.active = self.witch.value

class Covenant(OneOf):
    def __init__(self, parent, cost):
        super(Covenant, self).__init__(parent, 'Chaos Covenant')
        self.none = self.variant('No Chaos Covenant')
        self.kh = self.variant('Covenant of Khorne', cost)
        self.ng = self.variant('Covenant of Nurgle', cost)
        self.sl = self.variant('Covenant of Slaanesh', cost)
        self.tz = self.variant('Covenant of Tzeentch', cost)

    def set_cost(self, newcost):
        for opt in [self.kh, self.ng, self.tz, self.sl]:
            opt.points = newcost

class RenegadeCommand(Unit):
    type_name = 'Renegade Command Squad'
    type_id = 'r_command_v1'

    class Demagogue(Unit):
        class Weapon(OneOf):
            def __init__(self, parent, ccw=False):
                super(RenegadeCommand.Demagogue.Weapon, self).__init__(parent, '' if ccw else 'Weapon')
                if ccw:
                    self.variand('Close combat weapon')
                else:
                    self.variant('Autopistol')
                self.hotshot = [
                    self.variant('Hot-shot laspistol', 5),
                    self.variant('Hot-shot lasgun', 5)
                ]
                self.variant('Autogun')
                self.variant('Lasgun')
                self.variant('Shotgun')
                self.variant('Bolt pistol', 2)
                self.variant('Plasma pistol', 15)
                self.variant('Power weapon', 10)
                self.variant('Power fist', 15)

        class Options(OptionsList):
            def __init__(self, parent):
                super(RenegadeCommand.Demagogue.Options, self).__init__(parent, 'Options')
                self.variant('Caparace armour', 5)
                self.variant('Melta bombs', 5)
                self.field = self.variant('Refractor field', 15)

        def __init__(self, parent):
            super(RenegadeCommand.Demagogue, self).__init__(parent, 'Arch-demagogue',
                                                            gear=[Gear('Frag grenades')])
            self.wep1 = self.Weapon(self)
            self.wep2 = self.Weapon(self, True)
            self.devotion = Devotion(self)
            self.covenant = Covenant(self)
            self.opt = self.Options(self)

        def check_rules(self):
            super(RenegadeCommand.Demagogue, self).check_rules()
            self.covenant.set_cost(0 if self.devotion.che.value else 10)
            for wep in [self.wep1, self.wep2]:
                for shot in wep.hotchot:
                    shot.active = self.devotion.reaver.value
            self.opt.field.active = not self.devotion.reaver.value

        def build_description(self):
            res = super(RenegadeCommand.Demagogue, self).build_description()
            if self.devotion.reaver.value:
                res.add([Gear('Refractor field'), Gear('Krak grenades')])
            else:
                if self.parent.parent.opt.krak.value:
                    res.add(Gear('Krak grenades'))
            return res

    class DiscipleUpgrades(OptionsList):
        def __init__(self, parent):
            super(RenegadeCommand.DiscipleUpgrades, self).__init__(parent, 'Disciple wargear')
            self.banners = [
                self.variant('Banner of the Apostate', 10),
                self.variant('Banner of Hate', 25)
            ]
            self.vox = self.variant('Command net vox', 5)
            self.special = [
                self.variant('Flamer', 5),
                self.variant('Grenade launcher', 5),
                self.variant('Meltagun', 10),
                self.variant('Plasma gun', 15)
            ]

    class HeavyWeapon(OptionsList):
        def __init__(self, parent):
            super(RenegadeCommand.HeavyWeapon, self).__init__(parent, 'Heavy weapon')
            self.weapons = [
                self.variant('Heavy stubber', 5),
                self.variant('Mortar', 5),
                self.variant('Heavy bolter', 10),
                self.variant('Autocannon', 10)
            ]
            self.ml = self.variant('Missile launcher', 15)
            self.flak = self.variant('Flak missiles', 10)
            self.weapons += [
                self.ml, self.variant('Lascannon', 20)
            ]

        def check_rules(self):
            super(RenegadeCommand.HeavyWeapon, self).check_rules()
            OptionsList.process_limit(self.weapons, 1)
            self.flak.active = self.flak.used = self.ml.value

    class SquadOptions(OptionsList):
        def __init__(self, parent):
            super(RenegadeCommand.SquadOptions, self).__init__(parent, 'Squad upgrades')
            self.krak = self.variant('Krak grenades', 5)
            self.cap = self.variant('Caparace armour', 20)
            self.fnp = self.variant('Feel no Pain (6+)', 10)

    class Transport(OptionalSubUnit):
        def __init__(self, parent):
            super(RenegadeCommand.Transport, self).__init__(parent, 'Transport')
            SubUnit(self, Chimera(parent=None))

    class Weapon(OneOf):
        def __init__(self, parent, text='Weapon'):
            super(RenegadeCommand.Weapon, self).__init__(parent, name=text)
            self.variant('Autogun')
            self.variant('Lasgun')
            self.variant('Shotgun')

    def __init__(self, parent):
        super(RenegadeCommand, self).__init__(parent, points=45)
        self.boss = SubUnit(self, self.Demagogue(parent=None))
        self.extra = Count(self, 'Additional Disciples', 0, 10, 10)
        self.up = self.DiscipleUpgrades(self)
        self.wep1 = self.Weapon(self, "Banner bearer's weapon")
        self.wep2 = self.Weapon(self, "Voxbearer's weapon")
        self.heavy = self.HeavyWeapon(self)
        self.opt = self.SquadOptions(self)
        self.transport = self.Transport(self)

    def check_rules(self):
        super(RenegadeCommand, self).check_rules()
        self.opt.fnp.used = self.opt.fnp.visible = self.boss.unit.devotion.magus.value
        self.wep1.visible = any(opt.value for opt in self.up.banners)
        self.wep2.
'''

script = jedi.Script(column=18, source=source, line=169, encoding='utf-8', path=u'/cygdrive/c/Users/Kurvivor/Development/hq_git/builder/games/wh40k/renegades/hq.py')
script.completions()
jorgenschaefer commented 8 years ago

Hello, and thanks for the report! This is a bug in Jedi which we reported in October, but it has not been fixed yet. The problem is already mentioned in #698, so I will close this report to keep the discussion in one place, but please do not hesitate to open new issues if you have any further problems!

Kurvivor19 commented 8 years ago

No problem. I was just following the suggestions from Jedi when submitting the report

jorgenschaefer commented 8 years ago

It's always good to open issue! :-)