2012-11-30 5 views
5

私はstraceを通してそれを実行すると、次のPython 3のコードは、(少なくとも、私には)いくつかの奇妙な挙動を示す:.close()が失敗したときに、Python 3でファイル記述子はどうなりますか?

import os 
import sys 

if len(sys.argv) != 2: 
    print('Usage: ecpy <filename>') 
sys.exit(1) 
try: 
    print('my PID: %d' % os.getpid()) 
    with open(sys.argv[1], 'w') as fp: 
     try: 
      fp.write('Hello Stack Overflow!') 
     except IOError as e: 
      print('### before close') 
      print(str(e)) 
      sys.stdout.flush() 
except IOError as e: 
    print('### after close') 
    print(str(e)) 
    sys.stdout.flush() 

print('### after exception block') 
sys.stdout.flush() 

I/Oがバッファリングされているので、あなたが/dev/fullでこのコードを実行した場合、それはdoesnのブロックwithの最後でfpが終了するまで失敗します。それは驚きではありません。 (私のシステム上の)Pythonの2.7.3rc2では、コードが実際にfpに対応するファイルディスクリプタを閉じた後に例外ハンドラを実行します:

write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device) 
close(3)        = 0 
munmap(0x7f9de3f78000, 4096)   = 0 
write(1, "### after close\n", 16)  = 16 
write(1, "[Errno 28] No space left on devi"..., 35) = 35 
write(1, "### after exception block\n", 26) = 26 

しかし、Pythonの3.2.3(私のシステム上)、ファイルディスクリプタに

write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device) 
write(1, "### after close\n", 16)  = 16 
write(1, "[Errno 28] No space left on devi"..., 35) = 35 
write(1, "### after exception block\n", 26) = 26 
... 
write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device) 
write(3, "Hello Stack Overflow!", 21) = -1 ENOSPC (No space left on device) 
close(3)        = 0 

インタープリタがファイルに何度か書き込もうとしましたが、サイレントモードで失敗します。 Pythonはいつ実際にclose()を呼び出しますか?それを呼び出すのは何ですか?この動作は、ファイル記述子をリークするようです。

答えて

2

私はbugs.python.orgに問題を提出する自由をとりました。待っていて、それがパンされているかどうかを確認しましょう。

http://bugs.python.org/issue16597

編集:それはバグ、大漁だように見えます!

+0

提出いただきありがとうございます。 –

関連する問題