38
votes

I'm getting this error :

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__
return self.func(*args)
File "C:/Users/Marc/Documents/Programmation/Python/Llamachat/Llamachat/Llamachat.py", line 32, in download
with open(place_to_save, 'wb') as file:
PermissionError: [Errno 13] Permission denied: '/goodbye.txt'

When running this :

def download():
    # get selected line index
    index = films_list.curselection()[0]
    # get the line's text
    selected_text = films_list.get(index)
    directory = filedialog.askdirectory(parent=root, 
                                        title="Choose where to save your movie")
    place_to_save = directory + '/' + selected_text
    print(directory, selected_text, place_to_save)
    with open(place_to_save, 'wb') as file:
        connect.retrbinary('RETR ' + selected_text, file.write)
    tk.messagebox.showwarning('File downloaded', 
                              'Your movie has been successfully downloaded!' 
                              '\nAnd saved where you asked us to save it!!')

Can someone tell me what I am doing wrong?

Specs : Python 3.4.4 x86 Windows 10 x64

14
shouldn't place_to_save be simply goodbye.txt? I'm not sure how Windows would behave, but on Linux you'll be writing to root dir (/), and that's always a bad idea. Instead of manual string manipulation you should use os.path.join(directory, selected_text). - Łukasz Rogalski
try open(place_to_save, 'w+') instead of open(place_to_save, 'wb'). I remember seeing some other SO posts about the same issue, - DevLounge
An MCVE stackoverflow.com/help/mcve should be one line: open('/goodbye.txt', 'wb'). If this also raises, then tkinter is irrelevant and should be removed as a tag. This should be tagged with the OS, as that is relevant. - Terry Jan Reedy
What is the output of print(directory, selected_text, place_to_save)? My guess is that directory is an empty string for some reason. I would try adding initialdir=r'c:/' to filedialog.askdirectory call. - J.J. Hakala
@Mixone I think this is because the code is not minimal. The only relevant line is ` with open(place_to_save, 'wb') as file:`, and maybe the path itself. Also the stack trace is not full. - Gulzar

14 Answers

37
votes

This happens if you are trying to open a file, but your path is a folder.

This can happen easily by mistake.

To defend against that, use:

import os

path = r"my/path/to/file.txt"
assert os.path.isfile(path)
with open(path, "r") as f:
    pass

The assertion will fail if the path is actually of a folder.

33
votes

EDIT

I am seeing a bit of activity on my answer so I decided to improve it a bit for those with this issue still

There are basically three main methods of achieving administrator execution privileges on Windows.

  1. Running as admin from cmd.exe
  2. Creating a shortcut to execute the file with elevated privileges
  3. Changing the permissions on the python executable (Not recommended)

1) Running cmd.exe as and admin

Since in Windows there is no sudo command you have to run the terminal (cmd.exe) as an administrator to achieve to level of permissions equivalent to sudo. You can do this two ways:

  1. Manually

    • Find cmd.exe in C:\Windows\system32
    • Right-click on it
    • Select Run as Administrator
    • It will then open the command prompt in the directory C:\Windows\system32
    • Travel to your project directory
    • Run your program
  2. Via key shortcuts

    • Press the windows key (between alt and ctrl usually) + X.
    • A small pop-up list containing various administrator tasks will appear.
    • Select Command Prompt (Admin)
    • Travel to your project directory
    • Run your program

By doing that you are running as Admin so this problem should not persist

2) Creating shortcut with elevated privileges

  1. Create a shortcut for python.exe
  2. Righ-click the shortcut and select Properties
  3. Change the shortcut target into something like "C:\path_to\python.exe" C:\path_to\your_script.py"
  4. Click "advanced" in the property panel of the shortcut, and click the option "run as administrator"

Answer contributed by delphifirst in this question

3) Changing the permissions on the python executable (Not recommended)

This is a possibility but I highly discourage you from doing so.

It just involves finding the python executable and setting it to run as administrator every time. Can and probably will cause problems with things like file creation (they will be admin only) or possibly modules that require NOT being an admin to run.

10
votes

Make sure the file you are trying to write is closed first.

8
votes

Change the permissions of the directory you want to save to so that all users have read and write permissions.

3
votes

You can run CMD as Administrator and change the permission of the directory using cacls.exe. For example:

cacls.exe c: /t /e /g everyone:F # means everyone can totally control the C: disc
2
votes

The problem could be in the path of the file you want to open. Try and print the path and see if it is fine I had a similar problem

def scrap(soup,filenm):
htm=(soup.prettify().replace("https://","")).replace("http://","")
if ".php" in filenm or ".aspx" in filenm or ".jsp" in filenm:
    filenm=filenm.split("?")[0]
    filenm=("{}.html").format(filenm)
    print("Converted a  file into html that was not compatible")

if ".aspx" in htm:
    htm=htm.replace(".aspx",".aspx.html")
    print("[process]...conversion fron aspx")
if ".jsp" in htm:
    htm=htm.replace(".jsp",".jsp.html")
    print("[process]..conversion from jsp")
if ".php" in htm:
    htm=htm.replace(".php",".php.html")
    print("[process]..conversion from php")

output=open("data/"+filenm,"w",encoding="utf-8")
output.write(htm)
output.close()
print("{} bits of data written".format(len(htm)))

but after adding this code:

nofilenametxt=filenm.split('/')
nofilenametxt=nofilenametxt[len(nofilenametxt)-1]
if (len(nofilenametxt)==0):
    filenm=("{}index.html").format(filenm)
1
votes

I had a similar problem. I thought it might be with the system. But, using shutil.copytree() from the shutil module solved the problem for me!

1
votes

In my case the problem was that I hid the file (The file had hidden atribute):
How to deal with the problem in python:

import os

# This is how to hide the file
os.system(f"attrib +h {filePath}")
file_ = open(filePath, "wb")
>>> PermissionError <<<


# and this is how to show it again making the file writable again:
os.system(f"attrib -h {filePath}")
file_ = open(filePath, "wb")
# This works

# and just to let you know there is also this way
# so you don't need to import os
import subprocess
subprocess.check_call(["attrib", "-H", _path])


0
votes

I faced a similar problem. I am using Anaconda on windows and I resolved it as follows: 1) search for "Anaconda prompt" from the start menu 2) Right click and select "Run as administrator" 3) The follow the installation steps...

This takes care of the permission issues

0
votes

in my case. i just make the .idlerc directory hidden. so, all i had do is to that directory and make recent-files.lst unhidden after that, the problem was solved

0
votes

Here is how I encountered the error:

import os

path = input("Input file path: ")

name, ext = os.path.basename(path).rsplit('.', 1)
dire = os.path.dirname(path)

with open(f"{dire}\\{name} temp.{ext}", 'wb') as file:
    pass

It works great if the user inputs a file path with more than one element, like

C:\\Users\\Name\\Desktop\\Folder

But I thought that it would work with an input like

file.txt

as long as file.txt is in the same directory of the python file. But nope, it gave me that error, and I realized that the correct input should've been

.\\file.txt
0
votes

Another option that helped me is using pathlib:

from pathlib import Path
p = Path('.') ## if you want to write to current directory
with open(p / 'test.txt', 'w') as f:
    f.write('test message')

and it works

0
votes

As @gulzar said, I had the problem to write a file 'abc.txt' in my python script which was located in Z:\project\test.py:

with open('abc.txt', 'w') as file:
    file.write("TEST123")

Every time I ran a script in fact it wanted to create a file in my C drive instead Z! So I only specified full path with filename in:

with open('Z:\\project\\abc.txt', 'w') as file: ...

and it worked fine. I didn't have to add any permission nor change anything in windows.

-1
votes

This error actually also comes when using keras.preprocessing.image so for example:

img = keras.preprocessing.image.load_img(folder_path, target_size=image_size)

will throw the permission error. Strangely enough though, the problem is solved if you first import the library: from keras.preprocessing import image and only then use it. Like so:

img = image.load_img(img_path, target_size=(180,180))