Original file line numberDiff line numberDiff line change@@ -1,5 +1,6 @@
11importcollections.abc
22importfunctools
3+importos
34importgc
45importplatform
56importsys
@@ -860,6 +861,26 @@ def test_iterable_protocol(self):
860861861862classTkTest(AbstractTkTest, unittest.TestCase):
862863864+deftest_readprofile(self):
865+# gh-153333: profile scripts are decoded with their own coding cookie,
866+# not the locale encoding. Two cookies so no locale can mask the bug.
867+profiles= {
868+'.RpClass.py': ('latin-1', "self._rp_latin1 = 'caf\xe9'"),
869+'.rpbase.py': ('utf-8', "self._rp_utf8 = 'caf\xe9'"),
870+ }
871+self.addCleanup(self.root.__dict__.pop, '_rp_latin1', None)
872+self.addCleanup(self.root.__dict__.pop, '_rp_utf8', None)
873+with (os_helper.temp_dir() ashome,
874+os_helper.EnvironmentVarGuard() asenv):
875+env['HOME'] =home
876+forfilename, (encoding, body) inprofiles.items():
877+script='# -*- coding: %s -*-\n%s\n'% (encoding, body)
878+withopen(os.path.join(home, filename), 'wb') asf:
879+f.write(script.encode(encoding))
880+self.root.readprofile('rpbase', 'RpClass')
881+self.assertEqual(self.root._rp_latin1, 'caf\xe9')
882+self.assertEqual(self.root._rp_utf8, 'caf\xe9')
883+863884deftest_className(self):
864885# The className argument sets the class of the root window. Tk
865886# title-cases it: the first letter is upper-cased, the rest lower-cased.
Original file line numberDiff line numberDiff line change@@ -2750,11 +2750,13 @@ def readprofile(self, baseName, className):
27502750ifos.path.isfile(class_tcl):
27512751self.tk.call('source', class_tcl)
27522752ifos.path.isfile(class_py):
2753-exec(open(class_py).read(), dir)
2753+withopen(class_py, 'rb') asf:
2754+exec(f.read(), dir)
27542755ifos.path.isfile(base_tcl):
27552756self.tk.call('source', base_tcl)
27562757ifos.path.isfile(base_py):
2757-exec(open(base_py).read(), dir)
2758+withopen(base_py, 'rb') asf:
2759+exec(f.read(), dir)
2758276027592761defreport_callback_exception(self, exc, val, tb):
27602762"""Report callback exception on sys.stderr.
Original file line numberDiff line numberDiff line change@@ -0,0 +1,3 @@
1+The ``readprofile`` method of :class:`tkinter.Tk` now reads the user's
2+profile scripts using the encoding declared in the file, instead of the
3+locale encoding.