Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

print in pythonw raises silent exception when no console available #38179

Closed
amiseler mannequin opened this issue Mar 19, 2003 · 22 comments
Closed

print in pythonw raises silent exception when no console available #38179

amiseler mannequin opened this issue Mar 19, 2003 · 22 comments
Assignees
Labels
OS-windows topic-IO type-bug An unexpected behavior, bug, or error

Comments

@amiseler
Copy link
Mannequin

amiseler mannequin commented Mar 19, 2003

BPO 706263
Nosy @tim-one, @mhammond, @birkenfeld, @jcea, @amauryfa, @tiran, @alanjds

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = 'https://github.com/mhammond'
closed_at = <Date 2013-10-13.18:13:18.421>
created_at = <Date 2003-03-19.13:05:43.000>
labels = ['type-bug', 'expert-IO', 'OS-windows']
title = 'print in pythonw raises silent exception when no console available'
updated_at = <Date 2013-10-13.18:13:18.420>
user = 'https://bugs.python.org/amiseler'

bugs.python.org fields:

activity = <Date 2013-10-13.18:13:18.420>
actor = 'georg.brandl'
assignee = 'mhammond'
closed = True
closed_date = <Date 2013-10-13.18:13:18.421>
closer = 'georg.brandl'
components = ['Windows', 'IO']
creation = <Date 2003-03-19.13:05:43.000>
creator = 'amiseler'
dependencies = []
files = []
hgrepos = []
issue_num = 706263
keywords = []
message_count = 22.0
messages = ['15196', '15197', '15198', '15199', '15200', '15201', '15202', '15203', '75973', '97442', '114222', '114224', '114232', '114335', '114359', '130660', '136238', '136240', '190035', '191901', '191902', '199743']
nosy_count = 13.0
nosy_names = ['tim.peters', 'mhammond', 'georg.brandl', 'jcea', 'pysquared', 'amaury.forgeotdarc', 'amiseler', 'tim_evans', 'techtonik', 'christian.heimes', 'alanjds', 'santoso.wijaya', 'BreamoreBoy']
pr_nums = []
priority = 'normal'
resolution = 'wont fix'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue706263'
versions = ['Python 2.6', 'Python 2.7']

@amiseler
Copy link
Mannequin Author

amiseler mannequin commented Mar 19, 2003

platform: win2k
testet with: 2.2.2 2.3a1 2.3a2

the test case works fine when the script is run with
python.exe. with pythonw.exe an exception is raised
after printing 4096 bytes. the exception is rather
obscure but the bytecount suggests a buffer overflow.

print (or to be more exact sys.stdout.write) should be
a noop when there is no console.

test case:
import traceback
counter = 0
try:
for counter in range(100000):
print 'a',
success_file = open('success.txt', 'w')
success_file.write('Bytes printed: %d\n' % (counter*2))
success_file.close()
except:
error_file = open('error.txt', 'w')
error_file.write('Bytes printed before exception was
raised: %d\n' % (counter*2))
traceback.print_exc(100, error_file)
error_file.close()

output:
Bytes printed before exception was raised: 4096
Traceback (most recent call last):
  File "test_case.py", line 5, in ?
    print 'a',
IOError: [Errno 9] Bad file descriptor

@amiseler amiseler mannequin assigned mhammond Mar 19, 2003
@amiseler amiseler mannequin added the OS-windows label Mar 19, 2003
@amiseler amiseler mannequin assigned mhammond Mar 19, 2003
@amiseler amiseler mannequin added the OS-windows label Mar 19, 2003
@tim-one
Copy link
Member

tim-one commented Mar 19, 2003

Logged In: YES
user_id=31435

Mark, give a rip <wink>?

@mhammond
Copy link
Contributor

Logged In: YES
user_id=14198

I struck this years ago, but was in a quandry. On one hand,
sys.stdout *is* invalid, and I see no reason why Python
should mask these errors. There may be real applications
where this failure *must* be reported to the program rather
than simply consumed.

However, I see the point that print is so basic that is
should never fail. To my mind, the first point outweighs
the first, and the problem is fairly simply solved (see if
sys.stdout is invalid, and if so, open a file and set it to
that).

So I am afraid that, no, I don't give a rats <wink>. Unless
conivenced otherwise (ie, by Tim or Guido) I will close this
as "not a bug" in a week or so.

@tim-one
Copy link
Member

tim-one commented Mar 20, 2003

Logged In: YES
user_id=31435

I can swing either way on this, or even a third: open text
files stdout.txt and stderr.txt in the current directory then.
That's really aiming at a different irritation, though, that
tracebacks end up in the bit bucket by default under
pythonw.

BTW, making stdout and stderr /dev/null workalikes is
least attractive to me (nobody would write to stdout or
stderr *intending* the output be lost). I'm (barely) OK with
letting it stay as it is, because that just reflects Windows
reality.

@amiseler
Copy link
Mannequin Author

amiseler mannequin commented Mar 20, 2003

Logged In: YES
user_id=693638

then please throw a meaningful exception at first byte
written, not an obscure exception after 4096 bytes written.

@amiseler
Copy link
Mannequin Author

amiseler mannequin commented Mar 20, 2003

Logged In: YES
user_id=693638

and to say something FOR noop:
tim_one: "(nobody would write to stdout or stderr
*intending* the output be lost)"

yes, but someone would use print in an application and still
intend this application to run on any platform supported by
python.
its not really intuitive for someone programming under linux
that the print statement may limit the portability.

btw: the microsoft implementations (visual studio) of printf
and cout seem to be noops for non-console applications.
no idea how other windows compilers (mingw?) handle this.

i would consider it best, to make sys.stdout.write a noop
but to provide some other means to inquire the availability
of text output.

@pysquared
Copy link
Mannequin

pysquared mannequin commented Mar 26, 2003

Logged In: YES
user_id=543663

I just submitted a bug report ([ 710041 ] sys.stdout IOError
under Windows) with this same problem, so I closed it and will
add some of my comments here, in the hopes they will be
useful:

Python 2.1.2 (#31, Jan 15 2002, 17:28:11) [MSC 32 bit
(Intel)] on win32.
Under Windoze 98, in a non-console application.

Calls to the write() methods seem to discard the data, which
is what I want (when running a cross-platform GUI program
with debug print statements).

BUT, when the write() method is called with more than
about 4KB, it raises "IOError: [Errno 9] Bad file descriptor",
the same as if you had manually called the flush() method.

This IOError happens when write()ing even one character
if "pythonw.exe -u" was used to start the GUI.

I work around it by defining my own bit-bucket for
sys.std[out|err].
(NOTE: This bug was hard to track down!)

@timevans
Copy link
Mannequin

timevans mannequin commented Apr 11, 2003

Logged In: YES
user_id=561705

Yet another alternative: when soneone writes to stdout or
stderr, open a console window and write into that. I have
seen this used by the win32 vesion of Glade (the GTK gui
builder), so it may be a part of the win32 version of GTK or
Glib.

Personally, I would prefer just discarding the output. This
is not inconsistant. My gui apps on Linux are started from
the gnome panel (or an equivalent), not an xterm, so
anything they print gets discarded too.

Note that it is still posible to capture the stdout and
stderr of pythonw (at least on NT/2K/XP) by redirecting them
at the command prompt, like this: pythonw spam.pyw >
stdout.log 2> stderr.log

@amauryfa
Copy link
Member

Python 3.0 already discards the output in this case (see bpo-1415):
it sets sys.stdout=None and silently ignores prints to the None file.

I think this is the correct behavior, but I'm not sure this can be
backported to 2.7, because of compatibility issues.

@alanjds
Copy link
Mannequin

alanjds mannequin commented Jan 8, 2010

FWIW: I don't know if it changes anything, but when deploying Django projects on some clients who uses Windows as server, I'm using this piece of code to workarround this issue:

## Fixes "IOError: [Errno 9] Bad file descriptor" when in pythonw.exe of Windows

if sys.platform.find('win') != -1 and sys.executable.find('pythonw') != -1:

    blackhole = file(os.devnull, 'w')

    sys.stdout = sys.stderr = blackhole

Is not my intention to remove print statments neither to send they to a file. For this I'm using logging module.

I really expect they to be silently ignored, bothering not my user.

@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented Aug 18, 2010

Works fine with pythonw on 2.6 and 2.7.

@BreamoreBoy BreamoreBoy mannequin closed this as completed Aug 18, 2010
@BreamoreBoy BreamoreBoy mannequin closed this as completed Aug 18, 2010
@amauryfa
Copy link
Member

No, nothing changed in this aspect since python 2.2.
With 2.7, I get the same error.txt file containing the "Bad file descriptor" message.

@amauryfa amauryfa reopened this Aug 18, 2010
@amauryfa amauryfa reopened this Aug 18, 2010
@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented Aug 18, 2010

@Amaury I tested with Windows Vista and the latest 2.6 and 2.7 maintainance releases, what did you use?

@amauryfa
Copy link
Member

I use Windows XP.
Note that nothing is displayed on screen. there is just a error.txt file in the current directory.

@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented Aug 19, 2010

Ah I was misreading things, I too can confirm that it is still a problem.

@santosowijaya santosowijaya mannequin added topic-IO labels Mar 11, 2011
@santosowijaya
Copy link
Mannequin

santosowijaya mannequin commented Mar 12, 2011

This is indeed reproducible in Python 2.7. The following unittest will expose it. However, patching sys.std* to None will break print statements to raise AttributeError in pythonw.exe programs, though it won't mysteriously break only after printing 4 kbytes...

diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
old mode 100644
new mode 100755
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -58,6 +58,19 @@
         new = sys.getrefcount(path)
         self.assertEqual(old, new)
 
+    @unittest.skipUnless(sys.platform == 'win32',
+                         'test specific to Windows console')
+    def test_print_no_stdout(self):
+        # Issue python/cpython#38179: pythonw.exe will raise an IOError after
+        # attempting to print more than 4096 bytes (it silently
+        # succeeds for the first 4096 bytes and fails with an
+        # IOError: "[Errno 9] Bad file descriptor" on the 4097th byte.
+        DETACHED_PROCESS = 0x00000008
+        command = [sys.executable, '-c',
+                   'for _ in xrange(100000): print "a", ']
+        retcode = subprocess.call(command, creationflags=DETACHED_PROCESS)
+        self.assertEqual(retcode, 0)
+
 
 class TemporaryFileTests(unittest.TestCase):
     def setUp(self):

@jcea
Copy link
Member

jcea commented May 18, 2011

Does this affects Python 3?

@amauryfa
Copy link
Member

Python 3 is not affected: pythonw.exe sets sys.stderr to None, and print() silently discards the output in this case.

@BreamoreBoy
Copy link
Mannequin

BreamoreBoy mannequin commented May 25, 2013

Is it really worth leaving this open? There's no consensus after ten years and it only impacts on Python 2.7. Mark Hammond made his view plain in msg15198, which is supported by the fact that a type has yet to be allocated.

@techtonik
Copy link
Mannequin

techtonik mannequin commented Jun 26, 2013

This is still an issue for Python 2 users. Most important that pythonw.exe has a magic ability to fail silently leaving users with no means to create valid bug reports (the reason why StackOverflow questions are downvoted and erased).

http://bugs.ascend4.org/print_bug_page.php?bug_id=471
stream https://code.google.com/p/spyderlib/issues/detail?id=1260

The argument in msg15198 is somewhat misleading. If pythonw.exe fails because of print statement or because other issue, there is no way to report that.

Anyway, this reminds me very much of mod_wsgi, with only problem that Python developers don't receive as much feedback as Graham to make the change: http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html

@techtonik techtonik mannequin changed the title print raises exception when no console available print in pythonw raises silent exception when no console available Jun 26, 2013
@techtonik techtonik mannequin changed the title print raises exception when no console available print in pythonw raises silent exception when no console available Jun 26, 2013
@tiran
Copy link
Member

tiran commented Jun 26, 2013

I recommend against changing the code so late in the Python 2.7 release cycle. A change in behavior is too confusing.
And it's not a bug but a design decision, too. Over five years ago I implement parts of the IO interaction with the operating system for Python 3.0. I deliberately did NOT port modifications to 2.6.

If you want to get Python 3.x style print() behavior in Python 2.7 you can have it already:

from __future__ import print_function
import sys
if sys.executable.endswith("pythonw.exe"):
    sys.stdout = sys.stdout = None

print("can handle sys.stdout = None just fine.")

@tiran tiran added type-bug An unexpected behavior, bug, or error labels Jun 26, 2013
@birkenfeld
Copy link
Member

I agree with Christian; closing as suggested.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS-windows topic-IO type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

6 participants