classification
Title: OS X print >> f, "Hello" produces no error on read-only f: normal?
Type: behavior Stage: resolved
Components: Interpreter Core, macOS Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: ajaksu2, christian.heimes, georg.brandl, lebigot, loewis, ned.deily, ronaldoussoren
Priority: normal Keywords:

Created on 2007-02-06 16:23 by lebigot, last changed 2012-12-31 00:05 by ned.deily. This issue is now closed.

Messages (14)
msg31191 - (view) Author: Eric O. LEBIGOT (lebigot) Date: 2007-02-06 16:23
When using
  print >> f, "Hello"
on a file f opened for reading, no exception is raised.  Is this normal?

This situation has to be contrasted with
  f.write("Hello")
which raises an exception.

Details with Python 2.5 (r25:51908, Sep 24 206) on OS X 10.4.8 / darwin 8.8.0:

In [1]: f=open("start.01")
In [2]: f.write("Hello")
<type 'exceptions.IOError'>: [Errno 9] Bad file descriptor
In [3]: print >> f, "Hello"
In [4]: f.close()

NB: file f is not modified, despite the "print" statement yielding no error, above.
msg31192 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2007-02-06 17:31
If this happens, it's a bug. Though it doesn't seem to occur under Linux here.
msg31193 - (view) Author: Eric O. LEBIGOT (lebigot) Date: 2007-02-06 17:45
Interesting point, about Linux.   The incorrect behavior is even seen in the  default python 2.3 that ships with Mac OS X!
msg31194 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2007-02-06 18:49
I verified this behavior on my Mac with /usr/bin/python, Python 2.5 and
Python 2.6a0, both built from SVN.

Skip
msg31195 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2007-02-09 23:14
There seem to be multiple problems here. AFAICT,

print >>f, 3

fails on both Linux and OSX. This is because this uses fprintf to put out the number, which, in turn, returns -1. This result is ignored; instead Python expects ferror() to be set. However, ferror doesn't get set.

For printing strings, fwrite is used. On both Linux and OSX, fwrite will return 0. On Linux, in addition, ferror gets set; on OSX, it doesn't.

Reading C99, I can't figure out which of these systems is behaving correctly in what cases. The definition of ferror is that it returns the "error indicator" of the stream, and only fseek, fputc (+putc), and fflush are explicitly documented to set the error indicator. However, the error indicator is also documented to be set that it "records whether a  read/write error  has  occurred", and write is documented to return a number smaller than the requested only if an error occurred. Likewise, fprintf is document to return an negative value "if an  output  or  encoding error occurred."

Putting these all together, ISTM that both Linux and OSX implement fprintf incorrectly. To work around, Python could check the result of fprintf and fwrite in all places; this might become a large change.
msg31196 - (view) Author: Eric O. LEBIGOT (lebigot) Date: 2007-02-10 11:49
Just for reference: with Fink Python 2.5 (r25:51908, Sep 24 2006) on OS X 10.4.8 / darwin 8.8.0 for Intel Macs, "print >>f, 3" is also silently (and incorrectly) accepted when f is only opened for reading.
msg59792 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008-01-12 05:10
On Linux both 2.5 and 2.6 are raising an exception:

>>> f = open("/etc/passwd")
>>> print >>f, "Hello"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor
msg84647 - (view) Author: Daniel Diniz (ajaksu2) (Python triager) Date: 2009-03-30 21:03
Can anyone confirm this for Mac?
msg84668 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2009-03-30 21:53
This issue is still present on OSX:

Python 2.6.1+ (release26-maint:70603, Mar 26 2009, 08:38:03) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open("/dev/null")
>>> print >>f, "hello"
>>> f = open("/etc/hosts")
>>> print >>f, "world"
>>> 


This is a 2.6.x build from earlier this week.
msg95686 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2009-11-24 16:55
<http://www.opengroup.org/onlinepubs/9699919799/functions/printf.html> 
claims fprintf should return a negative value when there is an output 
error (the same claims is in the manpage of fprintf on OSX 10.6).

Neither document refers to the error indicator. I'm afraid Martin is right 
that that the return value of all calls to fprintf (and fwrite) need to be  
explicitly checked, which is a very large patch.
msg116602 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-09-16 20:19
I've assumed this is still a problem on OS X.
msg116612 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2010-09-16 21:14
At least for the original test case, the Python 3 equivalent does fail on OS X:

$ python3.1
Python 3.1.2 (r312:79360M, Mar 24 2010, 01:33:18) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('/dev/null')
>>> print('Hello',file=f)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: not writable
>>> 

Perhaps this can be closed as "wont fix" for Python 2 and, if necessary, open a separate issue for checking fprintf and fwrite return values?
msg116645 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2010-09-17 06:15
This is not an issue for 3.x because the io library doesn't use stdio.

I'd say this is unlikely to get fixed in 2.7 as every call to stdio functions needs to be checked and updated.
msg178630 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2012-12-31 00:05
An update: the problem with OS X behavior appears to have been fixed between OS X 10.6 and 10.7.  As of 10.7, print to a read-only file also fails as on linux:

>>> print >> f, "Hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 9] Bad file descriptor

Also, f.write() as of 2.7.3 produces a more meaningful message.

>>> f.write("bha")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: File not open for writing

Since the original example now produces an exception, plus, as noted, this is not an issue for 3.x and it's not likely that further work will be done  on 2.x in this area, I'm closing this as out-of-date.
History
Date User Action Args
2012-12-31 00:05:44ned.deilysetstatus: open -> closed

nosy: - BreamoreBoy
messages: + msg178630

resolution: out of date
stage: test needed -> resolved
2010-09-17 06:54:15lebigotsettitle: OS X print >> f, "Hello" produces no error: normal? -> OS X print >> f, "Hello" produces no error on read-only f: normal?
2010-09-17 06:15:31ronaldoussorensetmessages: + msg116645
versions: - Python 3.1, Python 3.2
2010-09-16 21:14:51ned.deilysetnosy: + ned.deily
messages: + msg116612
2010-09-16 20:19:13BreamoreBoysetnosy: + BreamoreBoy
title: print >> f, "Hello" produces no error: normal? -> OS X print >> f, "Hello" produces no error: normal?
messages: + msg116602

versions: + Python 3.1, Python 2.7, Python 3.2, - Python 2.6
2009-11-24 16:55:11ronaldoussorensetmessages: + msg95686
2009-03-31 16:22:16skip.montanarosetnosy: - skip.montanaro
2009-03-30 21:53:56ronaldoussorensetnosy: + ronaldoussoren
messages: + msg84668
2009-03-30 21:03:00ajaksu2setversions: - Python 2.5
nosy: + ajaksu2

messages: + msg84647

components: + macOS
stage: test needed
2008-01-12 05:10:05christian.heimessetnosy: + christian.heimes
messages: + msg59792
2008-01-12 05:08:42christian.heimessettype: behavior
versions: + Python 2.6
2007-02-06 16:23:53lebigotcreate