How to remove git repository, in python, on windows - python

As the title describes, I need to remove a git repository by using python.
I've seen other questions about this very same topic, but none of the solutions seem to work for me.
My work:
I need to download a repository, using gitpython, followed by checking some irrelevant things. After the process is finished, I need to delete the repository to save space for whoever is using my script.
The problem:
When cloning a git repository, a .git file will be created. This file is hidden in windows, and the modules I've been using do not have permission to delete any of the files within the .git folder.
What I've tried:
import shutil
shutil.rmtree('./cloned_repo')
PermissionError: [WinError 5] Access is denied:
Any help regarding this issue would be deeply appreciated.

Git has some readonly files. You need to change the permissions first:
import subprocess
import shutil
import os
import stat
from os import path
for root, dirs, files in os.walk("./cloned_repo"):
for dir in dirs:
os.chmod(path.join(root, dir), stat.S_IRWXU)
for file in files:
os.chmod(path.join(root, file), stat.S_IRWXU)
shutil.rmtree('./cloned_repo')

As noted above, this is because many of Git's files are read-only, which Python does not delete gracefully on Windows. The GitPython module has a utility function for just this purpose: git.util.rmtree
Calling the function like so should resolve your problem:
from git import rmtree
rmtree('./cloned_repo')
You can also see their source here--it's similar to the answer above, as of Dec 2020.

I've tried all the suggestions above, but none of them worked.
I'm using the GitPython module to handle my git repo's and I'm not convinced that I'm handling any open connections correctly. Saying that I have found a way to kill all git sessions which "fixed" my issue. (Albeit it a dirty fix)
import os
folder = "path/to/root"
git_repo = git.Repo(folder)
# do something with gitrepo
os.system(f'taskkill /IM "git.exe" /F')
This is not a good solution as you might have other git session open that you don't want to close. One way will be to make sure you close the git session, by closing it.
git_repo = git.Repo(folder)
#do something with gitrepo
git_repo.close()
Although the better way will be to use a context manager like 'with'
import git
with git.Repo(folder) as git_repo:
# do something with gitrepo
The context manager makes it easier to manage the git repo, and less likely have open repo's in session, thus less likely to have read only access errors.

If you use tempfile.TemporaryDirectory in Python 3.8+, this will just work. The specific issue with Git and Windows was considered a bug in Python and addressed in 3.8.
For <=3.7, you'll need to refer to one of the other answers, or to some workarounds linked in the Python issue.

Related

Download Repository to local folder and overwrite existing files by using Python

I have the problem that I want to update/overwrite my local folder with a Repository, but I cant find information about how I can do that with Python. When I am cloning it I have to have a empty folder which is not the case for me.
Thank in advanced!
If I understand your problem correctly, os module is all you need! The steps are below:
To clone the repository:
import os
github_repository_url = 'https://github.com/<user_name>/<repository_name>.git'
os.system(f'git clone {github_repository_url}')
Move to the directory:
os.system(f'cd <repository_name>')
Take a pull i.e., update the repository:
os.system('git pull')
Replace the placeholders <...> where necessary.
If you want to recreate a folder or update it can use with mkdir() function.
Otherwise, if you want to delete it you can use shutil.rmtree() function to delete a folder with all content of in it.
more ditailes here

Python scratch files in Pycharm - modules not being found?

I'm new to Python and using PyCharm professional as my IDE. I have a small section of code that I want to work with from a longer file, so I created a "scratch file" with Python set as the interpreter. However, even just with importing modules I'm getting errors that the modules can't be found (even with standard modules). The file is set as a "Python" scratch file, so I'm not sure what else I need to do. The code I'm trying to run is:
from zipfile import ZipFile
import urllib
testfile = urllib.request.urlretrieve("https://ihmecovid19storage.blob.core.windows.net/latest/ihme-covid19.zip", "ihme-covid19.zip")
print("File saved at: " + (str(os.getcwd())))
with ZipFile('ihme-covid19.zip', 'r') as zipobj:
print(zipobj.printdir())
zipobj.extractall()
Everything is showing up with an error - no module urllib, no module zipfile, etc.
This may come across like a non-answer, but I do think this is a bug in Pycharm.
I even downloaded an update, restarted pycharm, and rebuilt my indexes. Same thing, here -- core Python modules are not registering as being importable (i.e. import sys or import inspect both failing type-checking).
We should probably move this to Pycharm's bug tracker. For example:
Here is a similar issue around a specific import NamedTuple
Here's an issue around the default interpreter in scratch files
There may be a better existing bug ticket, so please do look and report back here -- I'll update this comment if someone finds or creates a better bug ticket on youtrack.jetbrains.com and shares the link.

Py2app: A main script could not be located in the Resources folder

I am building a GUI tkinter python3 application and attempting to compile it with py2app. For some reason when I try to launch the .app bundle in the dist folder it gives me this error:
A main script could not be located in the Resources folder
I was wondering why it is doing this, as it is rather frustrating, and I can not find anything about it anywhere. I copied my .py file into the resources folder (Networking.py). Previous to this error I also found an error in the Info.plist. In the key where it states the runtime executable, I found it was trying to get python2.7, which I have updated and am no longer using. I changed it to my current version, which the path for looks like this:
/Library/Frameworks/Python.framework/Versions/3.6/Python
It may be worth noting that it had a strange path previously, which did not look like a proper path to me. It was #executable_path/../Frameworks/Python.framework/Versions/2.7/PythonI removed this completely... Was this wrong? I have no idea about anything about XML, which is what it seemed to be...
Also when compiling this happened:
error: [Errno 1] Operation not permitted: '/Users/Ember/dist/Networking.app/Contents/MacOS/Networking'
Any help would be highly appreciated! Thanks!
EDIT
I actually figured out: a bit of a stupid mistake, but since I'm using python 3.x I have to type in python3 before doing it.
In your "setup.py" file that you used to create the application, did you remember to list all the modules used in your code. For example, if you used the OS and Glob modules, then you would add this to your setup.py next to "OPTIONS":
OPTIONS = {'argv_emulation': True, 'includes':['glob', 'os']}
Basically, anything that you import into your module, you should include in the setup.py. Let me know if that works.
I actually figured out: a bit of a stupid mistake, but since I'm using python 3.x I have to type in python3 before doing it.
I had the same problem.
python setup.py py2app
I tried
python3 setup.py py2app
and it worked just fine. Hope this helps.

Including a Python Library (suds) in a portable way

I'm using suds (brilliant library, btw), and I'd like to make it portable (so that everyone who uses the code that relies on it, can just checkout the files and run it).
I have tracked down 'suds-0.4-py2.6.egg' (in python/lib/site-packages), and put it in with my files, and I've tried:
import path.to.egg.file.suds
from path.to.egg.file.suds import *
import path.to.egg.file.suds-0.4-py2.6
The first two complain that suds doesn't exist, and the last one has invalid syntax.
In the __init__.py file, I have:
__all__ = [ "FileOne" ,
"FileTwo",
"suds-0.4-py2.6"]
and have previously tried
__all__ = [ "FileOne" ,
"FileTwo",
"suds"]
but neither work.
Is this the right way of going about it? If so, how can I get my imports to work. If not, how else can I achieve the same result?
Thanks
You must add your egg file to sys.path, like this:
import sys
# insert at 0 instead of appending to end to take precedence
# over system-installed suds (if there is one).
sys.path.insert(0, "suds-0.4-py2.6.egg")
import suds
.egg files are zipped archives; hence you cannot directly import them as you have discovered.
The easy way is to simply unzip the archive, and then copy the suds directory to your application's source code directory. Since Python will stop at the first module it discovers; your local copy of suds will be used even if it is not installed globally for Python.
One step up from that, is to add the egg to your path by appending it to sys.path.
However, the proper way would be to package your application for distribution; or provide a requirements file that lets other people know what external packages your program depends on.
Usually I distribute my program with a requirements.txt file that contain all dependencies and their version.
The users can then install these libraries with:
pip install -r requirements.txt
I don't think including eggs with your code is a good idea, what if the user use python2.7 instead of python2.6
More info about requirement file: http://www.pip-installer.org/en/latest/requirements.html

run as administrator problem with py2exe

I am having this problem that we compiled our python project into an exe with py2exe and the resulting exe does not work unless it is executed as an administrator.
I wanted to ask that is this supposed to happen ?? As in there are so many applications that we can run as not an administrator so is there any way I can convert my python code to such an application ...
Thanks a lot..
It sounds like your application is attempting to write to a directory for which the basic user doesn't have access; most likely the "Program Files" directory. I believe in Vista/Win7 this is not allowed, and the standard convention is to write to the user's appdata folder, for any user data you might wish to store.
You can reliably obtain the location of this directory using the ctypes module, here's an example:
import ctypes
from ctypes import wintypes
def get_appdata_directory():
CSIDL_APPDATA = 0x001a
dll = ctypes.windll.shell32
app_data_directory = ctypes.create_unicode_buffer(wintypes.MAX_PATH)
found = dll.SHGetFolderPathW(0, CSIDL_APPDATA, 0, 0, app_data_directory)
# FYI: if `found` is False, then it failed to locate the appdata directory
# and app_data_directory.value is empty. So you might want to add some
# code here to verify that a valid path is going to be returned.
# This would probably only happen on older versions of windows,
# but, this is just a guess as I don't have any older OSs available
# for testing. (see my note below)
return app_data_directory.value
appdata = get_appdata_directory()
print(appdata)
# outputs something such as: 'C:\Users\bob\AppData'
Note: I believe the appdata folder was introduced with WinXP/Win2k. Not sure about WinME and prior, however, I don't believe you have to worry about the administrator restrictions on these earlier OSs. If you really care to support them, you could use python's builtin platform module along with some conditionals, then simply write user data to the "Program Files" directory for the archaic versions of Windows.
I've had serious problems with getting py2exe to work. Luckily I found the excellent PyInstaller which not only works, but also creates smaller executables. I haven't ran into the problem you mention with PyInstaller so I recommend trying it.
http://www.pyinstaller.org/

Categories