7

Just started to use Mercurial. Wow, nice application. I moved my database file out of the code directory, but I was wondering about the .pyc files. I didn't include them on the initial commit. The documentation about the .hgignore file includes an example to exclude *.pyc, so I think I'm on the right track.

I am wondering about what happens when I decide to roll back to an older fileset. Will I need to delete all the .pyc files then? I saw some questions on Stack Overflow about the issue, including one gentleman that found old .pyc files were being used. What is the standard way around this?

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
kd4ttc
  • 1,075
  • 1
  • 10
  • 28
  • Do you use Mercurial under Linux? And do you use command line `hg` app or some kind of GUI app? – Kirill Jun 06 '12 at 19:05
  • 1
    I prefer setting PYTHONDONTWRITEBYTECODE during development to avoid pyc headaches altogether. – georg Jun 06 '12 at 20:29
  • ->Kirill: I am using Mercurial under MacOS X for Django web development for my medical practice. It is fun watching files come and go in the GUI when the command line hg app works its magic. ->thg435: Thanks for pointing out the PYTHONDONTWRITEBYTECODE option. – kd4ttc Jun 06 '12 at 21:52

4 Answers4

14

As mentioned in ms4py's answer, *.pyc are compiled files that will be regenerated on the fly. You wouldn't want to include these when distributing a project.

However, if it happens you have modules that existed before when you roll back changes and *.pyc files are left lying around, strange bugs can appear as pyc files can be execute even if the original python file doesn't exist anymore. This has bitten me a few times in Django when adding and removing apps in a project and switching branches with git.

To clean things up, you can delete every compiled files in your project's directory by running the following shell command in you project's directory:

find . -name '*.pyc' -exec rm {} \;
JeromeParadis
  • 1,046
  • 7
  • 5
  • 9
    Most `find`s also support `-delete` instead of `-exec rm {} \;`. – Danica Jun 06 '12 at 20:51
  • 1
    If your code base is bug free this problem does not occur within the default mercurial workflow (because you never import from a *.pyc which has no corresponding *.py). – schlamar Jun 06 '12 at 21:20
  • 1
    OK, so it looks like the right thing to do is do `hg commit` at intervals. If rolling back, run `find . -name '*.pyc' -delete` after the rollback as an option. It is good to exclude *.pyc files in general from Mercurial. – kd4ttc Jun 06 '12 at 22:04
  • @ms4py It can also happen if you move a file from one package to another. – Danica Jun 07 '12 at 01:42
5

Usually you are safe, because *.pyc are regenerated if the corresponding *.py changes its content.

It is problematic if you delete a *.py file and you are still importing from it in another file. In this case you are importing from the *.pyc file if it is existing. But this will be a bug in your code and is not really related to your mercurial workflow.

Conclusion: Every famous Python library is ignoring their *.pyc files, just do it ;)

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
schlamar
  • 9,238
  • 3
  • 38
  • 76
  • 1
    I agree. For the most part, things "just work". If you get strange behavior from your project (code being run that you *know* is no longer there, for example), then delete your *.pyc files. Otherwise, don't worry about it. – Chris Pratt Jun 06 '12 at 21:13
  • If you're deleting modules but still importing them, expecting an ImportError instead of loading an old .pyc file, that's probably a sign you're doing something odd... – Wooble Jun 06 '12 at 21:35
3

For a more general solution, then ask Mercurial itself about which files it ignores:

$ hg status --ignored

You can make the output safe for xargs consumption:

$ hg status --ignored --no-status -0 | xargs -0 -delete

(The -0 is important to handle files with spaces in the name.) You can install this as a post-update hook:

[hooks]
post-update = hg status --ignored --no-status -0 | xargs -0 -delete

Finally, Mercurial comes with a purge extension that does something similar:

$ hg purge --all

will delete both untracked and ignored files. If you're okay with losing untracked files, then that command is probably the easiest for you, in particular because it also works on Windows where xargs may be hard to come by.

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
0

Sure if you have a .pyc file from an older version of the same module python will use that. Many times I have wondered why my program wasn't reflecting the changes I made, and realized it was because I had old pyc files.

If this means that .pyc are not reflecting your current version then yes you will have to delete all .pyc files.

If you are on linux you can find . -name *.pyc -delete

dm03514
  • 54,664
  • 18
  • 108
  • 145