3

I've encountered a very odd error.

I have this code as part of many of my functions in my python script:

url=['http://API_URL/query/query.aspx?name=', name, '&md=user']
url=''.join(url)
file = open("QueryESO.xml", "w")
filehandle = urllib.urlopen(url)
for lines in filehandle.readlines():
    file.write(lines)
file.close()

When I run in IDLE, everything works great.

If I run it with Python (Command Line) then it gives me this error:

[Errno 22] invalid mode('w') or filename: 'QueryESO.xml'

Here's where it starts to get weird: Weird #1: I have the exact same code in different functions in my script, but the error only occurs for one of them.

Weird #2: If I change the code to this, it works fine:

url=['http://API_URL/query/query.aspx?name=', name, '&md=user']
print url
url=''.join(url)
file = open("QueryESO.xml", "w")
filehandle = urllib.urlopen(url)
for lines in filehandle.readlines():
    file.write(lines)
file.close()

I also tried moving the print url to after I joined the list, which didn't work, and I just tried print "", which also got the previously mentioned error.

So I guess I've found a solution... but can anyone explain this behavior? Am I doing something wrong? (And do you need me to post the entire script so you can mess with it?)

EDIT: Here is the entire code:

import urllib
from Tkinter import *
import tkFont
master = Tk()

QUERY_ESO = "QueryESO.xml"

def QueryXML(xml, attribute):
    x = ["<", attribute, ">"]
    x=''.join(x)
    z = xml.split(x, 1)
    x = ["</", attribute, ">"]
    x=''.join(x)
    z=z[1]
    z=z.split(x, 1)
    return z[0]

def AddFriend():
    nfentry = nfe2
    name=nfentry.get()
    url=['http://agecommunity.com/query/query.aspx?name=', name, '&md=user']
    url=''.join(url)
    file = open("QueryESO.xml", "w")
    filehandle = urllib.urlopen(url)
    for lines in filehandle.readlines():
        file.write(lines)
    file.close()
    f = open(QUERY_ESO, "r")
    xml = f.readlines()
    f.close()
    xml=''.join(xml)
    f = open("Friends.txt", "r")
    filestring = f.read()
    f.close()
    fs = filestring.split('\n')
    if name in fs:
        print "Friend Already Added"
    elif xml == "<?xml version='1.0' encoding='utf-8'?><error>Failed to find user</error>":
        print "User does not exist"
    else:
        fs.append(name)
        fs = '\n'.join(fs)
        f = open("Friends.txt", "w")
        f.write(fs)
        f.close()
    nfe2.set("")
    nfentry = nfe2

def DeleteFriend():
    ofentry = ofe2
    name=ofentry.get()
    f = open("Friends.txt", "r")
    filestring = f.read()
    f.close()
    fs = filestring.split('\n')
    if name in fs:
        fs.remove(name)
        fs = '\n'.join(fs)
        f = open("Friends.txt", "w")
        f.write(fs)
    ofe2.set("")
    ofentry = ofe2
    
def IsOnline(name):
    url=['http://API_URL/query/query.aspx?name=', name, '&md=user']
    print url
    url=''.join(url)
    file = open("QueryESO.xml", "w")
    filehandle = urllib.urlopen(url)
    for lines in filehandle.readlines():
        file.write(lines)
    file.close()
    f = open(QUERY_ESO, "r")
    xml = f.readlines()
    f.close()
    xml=''.join(xml)
    if xml == "<?xml version='1.0' encoding='utf-8'?><error>Failed to find user</error>":
        print "User does not exist"
    else: 
        datetime = QueryXML(xml, "LastUpdated")
        datetime = datetime.split('T', 1)
        time = datetime[1].split('Z', 1)
        date = datetime[0]
        print "User", name, "is", QueryXML(xml, "presence"), "as of", date, "at", time[0]
        return QueryXML(xml, "presence")

def FriendCheck():
    f = open("Friends.txt", "r")
    filestring = f.read()
    f.close()
    fs = filestring.split('\n')
    Laonline = Label(lowerframe, text="")
    Laonline.grid(column=0, row=0)
    Laonline.grid_forget()
    x=0
    while x <= (len(fs)-1):
        if IsOnline(fs[x]) == "online":
            Laonline = Label(lowerframe, text=fs[x])
            Laonline.grid(column=0, row=x)
        x=x+1

def RunTwo(Function1, Function2):
    Function1()
    Function2()

def DeleteAllFriends():
    fs = "<?xml version='1.0' encoding='utf-8'?>\n<friends>\n</friends>"
    f = open("Friends.txt", "w")
    f.write(fs)
    f.close()
    FriendCheck()

def DAFPop():
    DAFpopup = Toplevel()
    DAFframe = Frame(DAFpopup)
    DAFframe.grid(columnspan=4, column=0, row=0)
    F1 = DeleteAllFriends
    F2 = DAFpopup.destroy
    Q1 = lambda: RunTwo(F1, F2)
    DAFL1 = Label(DAFframe, text="This delete all of your friends. Are you sure you wish to continue?")
    DAFL1.grid()
    DAFOK = Button(DAFpopup, width=10, text="Yes", command=Q1)
    DAFOK.grid(column=1, row=1)
    DAFNO = Button(DAFpopup, width=10, text="No", command=DAFpopup.destroy)
    DAFNO.grid(column=2, row=1)

frame = Frame(master, bd=5)
frame.grid()

friendlist = Frame(frame, bd=5, width=150, height=400)
friendlist.grid(column=0, row=0, rowspan=15)

lon = Frame(friendlist, bd=2, width=150, height=10)
lon.grid()

Lonline = Label(lon, text="Friends Online")
Lonline.grid(column=0, row=1)
underlined = tkFont.Font(Lonline, Lonline.cget("font"))
underlined.configure(underline=True)
Lonline.configure(font=underlined)

lowerframe = Frame(friendlist, bd=2, width=150, height=390)
lowerframe.grid()

lowerframe.grid_propagate(0)

newfriendframe = Frame(frame, bd=2)
newfriendframe.grid(column=1, row=0)

nfe2 = StringVar()
nfentry = Entry(newfriendframe, width=12, textvariable=nfe2)
nfentry.grid()
nfe2.set("")
nfentry = nfe2.get()

newfriend = Button(newfriendframe, text="Add Friend", width=10, command=AddFriend)
newfriend.grid(column=0, row=1)

oldfriendframe = Frame(frame, bd=2)
oldfriendframe.grid(column=1, row=1)

ofe2 = StringVar()
ofentry = Entry(oldfriendframe, width=12,textvariable=ofe2)
ofentry.grid()
ofe2.set("")
ofentry = ofe2.get()

oldfriend = Button(oldfriendframe, text="Delete Friend", width=10, command=DeleteFriend)
oldfriend.grid(column=0, row=1)

rof = Button(frame, text="Reset List", width=10, command=DAFPop)
rof.grid(column=1, row=2)

update = Button(frame, text="Refresh", width=10, command=FriendCheck)
update.grid(column=1, row=3)

close = Button(frame, text="Exit", width=10, command=master.destroy)
close.grid(column=1, row=4)

master.mainloop()

And the function that isn't working is IsOnline(), although I have left print url in there for the code I posted, which seems to keep it running without error 90% of the time, whereas without it it gets the error 100% of the time.

It also has a dependency text file, Friends.txt:

friend1
friend2
friend3

It seems to create QueryESO.xml just fine for me even if it isn't there (when it doesn't get the error, of course). If this isn't the case for you, a blank file called QueryESO.xml will work fine, as it gets its content from a webpage.

The 'Refresh' button is the one that has the error in it.

  • 4
    `file` is the name of the built-in file type in Python; it's considered bad practise to override it. – Katriel Feb 24 '11 at 22:01
  • The code actually specifies "QueryESO.xml" by itself, correct? (No path/directories in front?) – user470379 Feb 24 '11 at 22:16
  • The code I posted is exactly what is in my script... so there are not any paths or directories in front. This works because the file is in the same directory (right?). and @katrielalex: I'll be sure to change it from overriding the built-in file name. –  Feb 24 '11 at 22:52
  • just fyi, couldn't duplicate with 2.6.6 and code given – thenoviceoof Feb 25 '11 at 05:41
  • I'll post my entire code for you. Also, I'm using 2.7.1. –  Feb 25 '11 at 14:07
  • 1
    I doubt it's relevant, but you're missing an `f.close()` in `DeleteFriend()` (in the `if name in fs` section.) – Matt Gibson Feb 25 '11 at 15:01
  • When I ran into this problem using Ipython on windows I just escaped all the backslashes in the path ("C:\Foo\bar" becoming "C:\\Foo\\Bar") and that fixed it for me. – justin cress Feb 06 '14 at 15:47

2 Answers2

3

Some observations:

(1) If the problem was invalid characters in the actual file name, it would be obvious from the error message; see below:

>>> open('fu\x01bar', 'w')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 22] invalid mode ('w') or filename: 'fu\x01bar'

(2) You say that you are using a global constant for the file name, but there are TWO occurrences of the literal text (in functions AddFriend and IsOnline) -- it helps if you make sure that the code that you post is actually what you have been running.

(3) One cause of this "works 90% of the time" behaviour is an extension (e.g. tkinter) not processing an exception, which then pops up later when something else does check for an error. Note that for errorno 22, Windows just reports "something evil has happened" and Python has to issue the "oh, in that case the mode must be wrong, or the filepath must be wrong" error message.

(4) I'm not one to walk away from a puzzle, but: in two places you get the results from the web, write them to this file, and read them back -- WHY?? Why don't you just use the web result in memory?

John Machin
  • 81,303
  • 11
  • 141
  • 189
  • 1
    ...I'm really not sure why I was doing that. I don't really have a legitimate reason. I was just sort of making it work. Sometimes I just don't think of these things; this is really only the 3rd or so legit program I've written, so I'm a bit of a newbie. I'll just try reading the result from memory. –  Feb 26 '11 at 15:20
  • I am doing the same and the reason is that I upload a file resize it and then upload it to s3 amazon. I am getting the same error. http://stackoverflow.com/questions/17467967/invalid-filename-or-mode-wb – Sohaib Jul 04 '13 at 11:07
  • I'm experiencing the same issue, and also "works 90% of the time". I'm logging the output of the command line to a file. I have created several files to log the output of different command. I guess that might be the reason why the issue happens. – Wei Yang Feb 13 '14 at 21:54
0

Since 'w' is a valid mode, the problem is with the filename. Maybe you aren't using the same system encoding in one context. If it's only in one function, you may have some hidden characters in this instance of the filename. Your first step fixing this would be to make the filename a module-level constant.

Tobu
  • 24,771
  • 4
  • 91
  • 98
  • I changed the filename to a constant, but it persists as not working in just the one module, while it still works in the others. It just perplexes me why simply printing list, url, fixes the problem. –  Feb 24 '11 at 23:05
  • @user Well, it's either because it introduces a delay, or because it's causing some kind of I/O buffer flush, or something similar, I'd guess. What happens if you do a `sleep(1)` instead of the print? (`import time` first...) – Matt Gibson Feb 25 '11 at 15:05
  • @Matt Well... I've now tried using sleep, and when I put sleep(1) in, it gives me the error, NameError: global name 'sleep' is not defined, and I also tried time.sleep(1), which told me: UnboundLocalError: local variable 'time' referenced before assignment. I did import time... When used import time and time.sleep(1) in another file, it worked fine... I'm not sure what I'm doing wrong? –  Feb 25 '11 at 16:10