6464
6565coding_re = re .compile ("coding[:=]\s*([-\w_.]+)" )
6666
67- class EncodingMessage (SimpleDialog ):
68- "Inform user that an encoding declaration is needed."
69- def __init__ (self , master , enc ):
70- self .should_edit = False
71-
72- self .root = top = Toplevel (master )
73- top .bind ("<Return>" , self .return_event )
74- top .bind ("<Escape>" , self .do_ok )
75- top .protocol ("WM_DELETE_WINDOW" , self .wm_delete_window )
76- top .wm_title ("I/O Warning" )
77- top .wm_iconname ("I/O Warning" )
78- self .top = top
79-
80- l1 = Label (top ,
81- text = "Non-ASCII found, yet no encoding declared. Add a line like" )
82- l1 .pack (side = TOP , anchor = W )
83- l2 = Entry (top , font = "courier" )
84- l2 .insert (0 , "# -*- coding: %s -*-" % enc )
85- # For some reason, the text is not selectable anymore if the
86- # widget is disabled.
87- # l2['state'] = DISABLED
88- l2 .pack (side = TOP , anchor = W , fill = X )
89- l3 = Label (top , text = "to your file\n "
90- "Choose OK to save this file as %s\n "
91- "Edit your general options to silence this warning" % enc )
92- l3 .pack (side = TOP , anchor = W )
93-
94- buttons = Frame (top )
95- buttons .pack (side = TOP , fill = X )
96- # Both return and cancel mean the same thing: do nothing
97- self .default = self .cancel = 0
98- b1 = Button (buttons , text = "Ok" , default = "active" ,
99- command = self .do_ok )
100- b1 .pack (side = LEFT , fill = BOTH , expand = 1 )
101- b2 = Button (buttons , text = "Edit my file" ,
102- command = self .do_edit )
103- b2 .pack (side = LEFT , fill = BOTH , expand = 1 )
104-
105- self ._set_transient (master )
106-
107- def do_ok (self ):
108- self .done (0 )
109-
110- def do_edit (self ):
111- self .done (1 )
112-
11367def coding_spec (data ):
11468 """Return the encoding declaration according to PEP 263.
11569
@@ -409,6 +363,9 @@ def encode(self, chars):
409363 # This is either plain ASCII, or Tk was returning mixed-encoding
410364 # text to us. Don't try to guess further.
411365 return chars
366+ # Preserve a BOM that might have been present on opening
367+ if self .fileencoding == 'BOM' :
368+ return BOM_UTF8 + chars .encode ("utf-8" )
412369 # See whether there is anything non-ASCII in it.
413370 # If not, no need to figure out the encoding.
414371 try :
@@ -423,61 +380,22 @@ def encode(self, chars):
423380 except LookupError as msg :
424381 failed = msg
425382 enc = None
383+ else :
384+ if not enc :
385+ # PEP 3120: default source encoding is UTF-8
386+ enc = 'utf-8'
426387 if enc :
427388 try :
428389 return chars .encode (enc )
429390 except UnicodeError :
430391 failed = "Invalid encoding '%s'" % enc
431- if failed :
432- tkMessageBox .showerror (
433- "I/O Error" ,
434- "%s.\n Saving as UTF-8" % failed ,
435- master = self .text )
436- # If there was a UTF-8 signature, use that. This should not fail
437- if self .fileencoding == 'BOM' or failed :
438- return BOM_UTF8 + chars .encode ("utf-8" )
439- # Try the original file encoding next, if any
440- if self .fileencoding :
441- try :
442- return chars .encode (self .fileencoding )
443- except UnicodeError :
444- tkMessageBox .showerror (
445- "I/O Error" ,
446- "Cannot save this as '%s' anymore. Saving as UTF-8" \
447- % self .fileencoding ,
448- master = self .text )
449- return BOM_UTF8 + chars .encode ("utf-8" )
450- # Nothing was declared, and we had not determined an encoding
451- # on loading. Recommend an encoding line.
452- config_encoding = idleConf .GetOption ("main" ,"EditorWindow" ,
453- "encoding" )
454- if config_encoding == 'utf-8' :
455- # User has requested that we save files as UTF-8
456- return BOM_UTF8 + chars .encode ("utf-8" )
457- ask_user = True
458- try :
459- chars = chars .encode (encoding )
460- enc = encoding
461- if config_encoding == 'locale' :
462- ask_user = False
463- except UnicodeError :
464- chars = BOM_UTF8 + chars .encode ("utf-8" )
465- enc = "utf-8"
466- if not ask_user :
467- return chars
468- dialog = EncodingMessage (self .editwin .top , enc )
469- dialog .go ()
470- if dialog .num == 1 :
471- # User asked us to edit the file
472- encline = "# -*- coding: %s -*-\n " % enc
473- firstline = self .text .get ("1.0" , "2.0" )
474- if firstline .startswith ("#!" ):
475- # Insert encoding after #! line
476- self .text .insert ("2.0" , encline )
477- else :
478- self .text .insert ("1.0" , encline )
479- return self .encode (self .text .get ("1.0" , "end-1c" ))
480- return chars
392+ tkMessageBox .showerror (
393+ "I/O Error" ,
394+ "%s.\n Saving as UTF-8" % failed ,
395+ master = self .text )
396+ # Fallback: save as UTF-8, with BOM - ignoring the incorrect
397+ # declared encoding
398+ return BOM_UTF8 + chars .encode ("utf-8" )
481399
482400 def fixlastline (self ):
483401 c = self .text .get ("end-2c" )
0 commit comments