diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index 4f140ca23b70..4942774a6ac3 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -122,6 +122,8 @@ public class PyNames { public static final String PY_TEST = "pytest"; public static final String AT_TEST = "attest"; + public static final String PYCACHE = "__pycache__"; + /** * Contains all known predefined names of "__foo__" form. diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 9535bded79a4..d9bb3e0ee2ef 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -18,6 +18,7 @@ import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -52,6 +53,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.util.*; import java.util.List; @@ -572,6 +574,34 @@ public class PyUtil { return ScopeUtil.getScopeOwner(element) instanceof PsiFile; } + public static void deletePycFiles(String pyFilePath) { + if (pyFilePath.endsWith(".py")) { + List filesToDelete = new ArrayList(); + File pyc = new File(pyFilePath + "c"); + if (pyc.exists()) { + filesToDelete.add(pyc); + } + File pyo = new File(pyFilePath + "o"); + if (pyo.exists()) { + filesToDelete.add(pyo); + } + final File file = new File(pyFilePath); + File pycache = new File(file.getParentFile(), PyNames.PYCACHE); + if (pycache.isDirectory()) { + final String shortName = FileUtil.getNameWithoutExtension(file); + Collections.addAll(filesToDelete, pycache.listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + if (!FileUtil.getExtension(pathname.getName()).equals("pyc")) return false; + String nameWithMagic = FileUtil.getNameWithoutExtension(pathname); + return FileUtil.getNameWithoutExtension(nameWithMagic).equals(shortName); + } + })); + } + FileUtil.asyncDelete(filesToDelete); + } + } + public static class KnownDecoratorProviderHolder { public static PyKnownDecoratorProvider[] KNOWN_DECORATOR_PROVIDERS = Extensions.getExtensions(PyKnownDecoratorProvider.EP_NAME); diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java index 4c4e275ca078..a67bfb33aebd 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java @@ -4,6 +4,7 @@ import com.intellij.extapi.psi.PsiFileBase; import com.intellij.lang.Language; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; @@ -11,6 +12,7 @@ import com.intellij.psi.stubs.StubElement; import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.reference.SoftReference; +import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.indexing.IndexingDataKeys; @@ -700,6 +702,13 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { } } + @Override + public void delete() throws IncorrectOperationException { + String path = getVirtualFile().getPath(); + super.delete(); + PyUtil.deletePycFiles(path); + } + private static class ArrayListThreadLocal extends ThreadLocal> { @Override protected List initialValue() {