r4fek / django-cassandra-engine

Django Cassandra Engine - the Cassandra backend for Django
BSD 2-Clause "Simplified" License
365 stars 84 forks source link

Exception on sync_cassandra in python 3.6.3 #102

Open Krolken opened 7 years ago

Krolken commented 7 years ago

Hi

I had my Cassandra API hooked up to docker image python3.6 (stupid me) And when they updated the docker image my API image got updated and I couln't run migrations to Cassandra anymore. I looked for a long while until I realised that they have changed the import exception in importlib for 3.6.3.

importlib Import now raises the new exception ModuleNotFoundError (subclass of ImportError) when it cannot find a module. Code that current checks for ImportError (in try-except) will still work. (Contributed by Eric Snow in bpo-15767.)

In the code for sync_cassandra is this:

for app_name in settings.INSTALLED_APPS:
            try:
                import_module('.management', app_name)
            except SystemError:
                # We get SystemError if INSTALLED_APPS contains the
                # name of a class rather than a module
                pass
            except ImportError as exc:
                # This is slightly hackish. We want to ignore ImportErrors
                # if the "management" module itself is missing -- but we don't
                # want to ignore the exception if the management module exists
                # but raises an ImportError for some reason. The only way we
                # can do this is to check the text of the exception. Note that
                # we're a bit broad in how we check the text, because different
                # Python implementations may not use the same text.
                # CPython uses the text "No module named management"
                # PyPy uses "No module named myproject.myapp.management"
                msg = exc.args[0]
                if not msg.startswith('No module named') \
                        or 'management' not in msg:
                    raise

I'm not really sure about the correct way to solve it to keep it backwards compatible. Since I got a problem when defining my apps like myapp.apps.MyappConfig. I should have gotten a Systemerror and nothing would have been done, but now we get a ModuleNotFoundError and everything broke. But shouldn't that been caught with the Import Error since it is derived from that?

If I get some input on how to solve the best I'll make a pull request of the change

It works on python 3.6.1. I also tried 3.5 where it failed.

r4fek commented 7 years ago

Hey,

Thanks for the report. I'll try to address this error soon I hope.

r4fek commented 6 years ago

Hey @Krolken,

Could you try to verify if it works in version 1.4?

lexnjugz commented 6 years ago

Hey @r4fek, The Issue is still present

lexnjugz commented 6 years ago

Hey @r4fek, Got a hackish way round the problem, have a look at this

from importlib import import_module
        for app_name in settings.INSTALLED_APPS:
            try:
                import_module('.management', app_name)
            except SystemError:
                # We get SystemError if INSTALLED_APPS contains the
                # name of a class rather than a module
                pass
            except ImportError:
                # This is slightly hackish. We want to ignore ImportErrors
                # if the "management" module itself is missing -- but we don't
                # want to ignore the exception if the management module exists
                # but raises an ImportError for some reason. The only way we
                # can do this is to check the text of the exception. Note that
                # we're a bit broad in how we check the text, because different
                # Python implementations may not use the same text.
                # CPython uses the text "No module named management"
                # PyPy uses "No module named myproject.myapp.management"
                try:
                    import_module('..management', app_name)
                except ImportError as exc:
                    msg = exc.args[0]
                    if not msg.startswith('No module named') \
                            or 'management' not in msg:
                        raise
ba-la commented 5 years ago

Still issue is present , any updates here

r4fek commented 3 years ago

What about now? Should be fixed some time ago.

Krolken commented 3 years ago

The project we used to run Cassandra on is no longer active so I can't check.