Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fake unresolved import error in PyDev

PyDev is reporting import errors which don't exist. The initial symptom was a fake "unresolved import" error, which was fixed by some combination of:

  • Cleaning the Project
  • Re-indexing the project (remove interpreter, add again)
  • Restarting Eclipse
  • Burning incense to the Python deities

Now the error is "unverified variable from import"--it can't seem to find pymssql.connect.

This IS NOT a PYHTONPATH problem. I can access the module just fine, the code in the file with the (alleged) error runs fine---it has unit tests and production code calling it.

The error is somewhere in PyDev: I added a new module to my PyDev project, and the error only occurs in the new module. I've tried all of the above.


So, I was planning on posting this code somewhere else to solicit some comments about the design, and I was asked in the comments to post code. (Inspired by: Database connection wrapper and Clint Miller's answer to this question: How do I correctly clean up a Python object?). The import error happens at line 69 (self.connection = pymssql.connect...). Not sure what good this does in answering the question, but...

import pymssql
from util.require_type import require_type

class Connections(object):
    @require_type('host', str)
    @require_type('user', str)
    @require_type('password', str)
    @require_type('database', str)
    @require_type('as_dict', bool)
    def __init__(self, host, user, password, database, as_dict=True):
        self.host = host
        self.user = user
        self.password = password
        self.db = database
        self.as_dict = as_dict

    @staticmethod
    def server1(db):
        return Connections('','','','')

    @staticmethod
    def server2(db):
        pass

    @staticmethod
    def server3(db):
        pass


class DBConnectionSource(object):
    # Usage:
    #        with DBConnectionSource(ConnectionParameters.server1(db = 'MyDB)) as dbConn:
    #            results = dbConn.execute(sqlStatement)

    @require_type('connection_parameters', Connections)
    def __init__(self, connection_parameters=Connections.server1('MyDB')):
        self.host = connection_parameters.host
        self.user = connection_parameters.user
        self.password = connection_parameters.password
        self.db = connection_parameters.db
        self.as_dict = connection_parameters.as_dict
        self.connection = None

    def __enter__(self):

        parent = self

        class DBConnection(object):
            def connect(self):
                self.connection = pymssql.connect(host=parent.host,
                                                  user=parent.user,
                                                  password=parent.password,
                                                  database=parent.db,
                                                  as_dict=parent.as_dict)

            def execute(self, sqlString, arguments={}):
                if self.connection is None:
                    raise Exception('DB Connection not defined')
                crsr = self.connection.cursor()
                crsr.execute(sqlString, arguments)
                return list(crsr)

            def cleanup(self):
                if self.connection:
                    self.connection.close()

        self.connection = DBConnection()
        self.connection.connect()
        return self.connection

    def __exit__(self, typ, value, traceback):
        self.connection.cleanup()
like image 585
BenDundee Avatar asked Nov 03 '22 06:11

BenDundee


2 Answers

Try ctrl+1 at the line where the error and add a comment saying that you are expecting that import. This should resolve the PyDev error, as it does static code analysis and not runtime analysis.

like image 179
Woot4Moo Avatar answered Nov 11 '22 03:11

Woot4Moo


TL;DR version: read the fifth grey box.

Your problem (and mine) appears to be due to multiple levels of imports that should be, but is not, handled correctly. Somewhere along the line, linkage is lost.

Assume for a moment that you have a file

foo/bar.py

and that within that file, you have a symbol named

wazoo=15

If you then try:

from foo import bar
from bar import wazoo <-- false error here

Or if you try to use:

from foo import bar
...
i = bar.wazoo <-- false error here

You may get the false unresolved error on wazoo. Being a bug, this is obviously inconsistent.

If however, you do the following:

from foo.bar import wazoo

The problems do seem to go away.

As an aside, I've noted that this sometime seems to happen for newly-defined symbols within an imported file. Furthermore, the earlier false errors for some symbols within that file will magically disappear, with the only the new error remaining. This implies that there might be some sort of state file that isn't being cleaned, EVEN WHEN you "buildall", etc.

Note also that this problem seems to occur the most for me when I use the Python enum hack...perhaps this will provide a clue to the PyDev-elopers (is PyDev even being maintained anymore?):

bar.py:

def enum(**enums):
  return type('Enum', (), enums)

SOMETHING = enum(A=1, B=2)

someotherfile.py:

from foo import bar
from bar import SOMETHING
...
x = SOMETHING.A
like image 35
Mark Gerolimatos Avatar answered Nov 11 '22 04:11

Mark Gerolimatos