Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why was an old .pyc file breaking Django?

Tags:

python

django

I pulled the latest code using git today and I got the following error:

ImportError at /
cannot import name Like

This might have something to do with circular imports. I examined the traceback:

Traceback:
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/handlers/base.py" in get_response
  101.                             request.path_info)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/urlresolvers.py" in resolve
  298.             for pattern in self.url_patterns:
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/urlresolvers.py" in url_patterns
  328.         patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/core/urlresolvers.py" in urlconf_module
  323.             self._urlconf_module = import_module(self.urlconf_name)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/utils/importlib.py" in import_module
  35.     __import__(name)
File "/Users/Desktop/python/mystuff/Project/Project/urls.py" in <module>
  7. admin.autodiscover()
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/contrib/admin/__init__.py" in autodiscover
  29.             import_module('%s.admin' % app)
File "/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/utils/importlib.py" in import_module
  35.     __import__(name)

The only code in there it looked that could be causing the problem was urls.py. That had the following code:

from django.contrib import admin
admin.autodiscover()

So around this time I notice that the admin.py file that we previously had written was deleted in the latest merge but that the admin.pyc still existed. Deleting the .pyc file proceeded to fix the circular import error and now things seem to work fine.

My question is: what exactly was happening here? Git is configured to ignore all pyc files so after the merge the .pyc stuck around even though the .py was removed. But shouldn't python be smart enough not to try to call any compiled code in the .pyc if the .py itself was deleted?

like image 282
Chris Avatar asked Sep 08 '12 22:09

Chris


People also ask

Should I check .PYC files?

These files are compiled versions of the code already in the repo, so that Python can execute the code faster. Since they are a direct computational result of the actual source code there's no benefit to checking them in - they'd just need to be updated every time the source code was updated.

Why do .PYC files get created?

pyc files are created automatically by the GraalVM Python runtime when no or an invalid . pyc file is found matching the desired . py file. When a Python source file (module) is imported during an execution for the first time, the appropriate .

What is the difference between .py and .PYC files?

. py files contain the source code of a program. Whereas, . pyc file contains the bytecode of your program.

How do I recompile a PYC file?

Method 1: using py_compile module Import py_compile in your python code. There is a function called compile() . Pass the Python file name that you want to compile as an argument. It will convert Python script into the bytecode (file with the file extension pyc ).


2 Answers

No, in fact, Python will use the .pyc file preferably and only access the .py file if it a) exists and b) is newer than the .pyc file.

This allows you to distribute a Python app in compiled form without the source code (although it's not much of a code "obfuscation" technique).

like image 187
Tim Pietzcker Avatar answered Oct 02 '22 07:10

Tim Pietzcker


Nope, Python is (intentionally, see below) dumb about this! You can run

find . -name '*.pyc' -delete

from your project directory to get rid of old .pyc files.

If you're using git, you can set up a hook to do this automatically on checkout. Here's a similar solution for Mercurial.

like image 25
ecmendenhall Avatar answered Oct 02 '22 07:10

ecmendenhall