mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-91827: Add method info_pathlevel() in tkinter (GH-91829)
This commit is contained in:
		
							parent
							
								
									d707d073be
								
							
						
					
					
						commit
						15dbe8570f
					
				
					 8 changed files with 75 additions and 23 deletions
				
			
		|  | @ -744,6 +744,14 @@ For major changes, see :ref:`new-feat-related-type-hints-311`. | |||
|   (Contributed by Serhiy Storchaka in :issue:`43923`.) | ||||
| 
 | ||||
| 
 | ||||
| tkinter | ||||
| ------- | ||||
| 
 | ||||
| * Added method ``info_patchlevel()`` which returns the exact version of | ||||
|   the Tcl library as a named tuple similar to :data:`sys.version_info`. | ||||
|   (Contributed by Serhiy Storchaka in :issue:`91827`.) | ||||
| 
 | ||||
| 
 | ||||
| unicodedata | ||||
| ----------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,8 +76,8 @@ def create_widgets(self): | |||
|                        bg=self.bg, font=('courier', 24, 'bold')) | ||||
|         header.grid(row=0, column=0, sticky=E, padx=10, pady=10) | ||||
| 
 | ||||
|         tk_patchlevel = self.tk.call('info', 'patchlevel') | ||||
|         ext = '.png' if tk_patchlevel >= '8.6' else '.gif' | ||||
|         tk_patchlevel = self.info_patchlevel() | ||||
|         ext = '.png' if tk_patchlevel >= (8, 6) else '.gif' | ||||
|         icon = os.path.join(os.path.abspath(os.path.dirname(__file__)), | ||||
|                             'Icons', f'idle_48{ext}') | ||||
|         self.icon_image = PhotoImage(master=self._root(), file=icon) | ||||
|  | @ -105,7 +105,7 @@ def create_widgets(self): | |||
|                       text='Python version:  ' + version, | ||||
|                       fg=self.fg, bg=self.bg) | ||||
|         pyver.grid(row=9, column=0, sticky=W, padx=10, pady=0) | ||||
|         tkver = Label(frame_background, text='Tk version:  ' + tk_patchlevel, | ||||
|         tkver = Label(frame_background, text=f'Tk version:  {tk_patchlevel}', | ||||
|                       fg=self.fg, bg=self.bg) | ||||
|         tkver.grid(row=9, column=1, sticky=W, padx=2, pady=0) | ||||
|         py_buttons = Frame(frame_background, bg=self.bg) | ||||
|  |  | |||
|  | @ -28,15 +28,7 @@ def get_tk_patchlevel(): | |||
|     global _tk_patchlevel | ||||
|     if _tk_patchlevel is None: | ||||
|         tcl = Tcl() | ||||
|         patchlevel = tcl.call('info', 'patchlevel') | ||||
|         m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel) | ||||
|         major, minor, releaselevel, serial = m.groups() | ||||
|         major, minor, serial = int(major), int(minor), int(serial) | ||||
|         releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel] | ||||
|         if releaselevel == 'final': | ||||
|             _tk_patchlevel = major, minor, serial, releaselevel, 0 | ||||
|         else: | ||||
|             _tk_patchlevel = major, minor, 0, releaselevel, serial | ||||
|         _tk_patchlevel = tcl.info_patchlevel() | ||||
|     return _tk_patchlevel | ||||
| 
 | ||||
| 
 | ||||
|  | @ -723,7 +715,7 @@ def test_huge_string_builtins2(self, size): | |||
| def setUpModule(): | ||||
|     if support.verbose: | ||||
|         tcl = Tcl() | ||||
|         print('patchlevel =', tcl.call('info', 'patchlevel')) | ||||
|         print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ | |||
| tk.mainloop() | ||||
| """ | ||||
| 
 | ||||
| import collections | ||||
| import enum | ||||
| import sys | ||||
| import types | ||||
|  | @ -143,6 +144,28 @@ def _splitdict(tk, v, cut_minus=True, conv=None): | |||
|         dict[key] = value | ||||
|     return dict | ||||
| 
 | ||||
| class _VersionInfoType(collections.namedtuple('_VersionInfoType', | ||||
|         ('major', 'minor', 'micro', 'releaselevel', 'serial'))): | ||||
|     def __str__(self): | ||||
|         if self.releaselevel == 'final': | ||||
|             return f'{self.major}.{self.minor}.{self.micro}' | ||||
|         else: | ||||
|             return f'{self.major}.{self.minor}{self.releaselevel[0]}{self.serial}' | ||||
| 
 | ||||
| def _parse_version(version): | ||||
|     import re | ||||
|     m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', version) | ||||
|     major, minor, releaselevel, serial = m.groups() | ||||
|     major, minor, serial = int(major), int(minor), int(serial) | ||||
|     if releaselevel == '.': | ||||
|         micro = serial | ||||
|         serial = 0 | ||||
|         releaselevel = 'final' | ||||
|     else: | ||||
|         micro = 0 | ||||
|         releaselevel = {'a': 'alpha', 'b': 'beta'}[releaselevel] | ||||
|     return _VersionInfoType(major, minor, micro, releaselevel, serial) | ||||
| 
 | ||||
| 
 | ||||
| @enum._simple_enum(enum.StrEnum) | ||||
| class EventType: | ||||
|  | @ -1055,6 +1078,11 @@ def tkraise(self, aboveThis=None): | |||
| 
 | ||||
|     lift = tkraise | ||||
| 
 | ||||
|     def info_patchlevel(self): | ||||
|         """Returns the exact version of the Tcl library.""" | ||||
|         patchlevel = self.tk.call('info', 'patchlevel') | ||||
|         return _parse_version(patchlevel) | ||||
| 
 | ||||
|     def winfo_atom(self, name, displayof=0): | ||||
|         """Return integer which represents atom NAME.""" | ||||
|         args = ('winfo', 'atom') + self._displayof(displayof) + (name,) | ||||
|  |  | |||
|  | @ -101,15 +101,7 @@ def get_tk_patchlevel(): | |||
|     global _tk_patchlevel | ||||
|     if _tk_patchlevel is None: | ||||
|         tcl = tkinter.Tcl() | ||||
|         patchlevel = tcl.call('info', 'patchlevel') | ||||
|         m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel) | ||||
|         major, minor, releaselevel, serial = m.groups() | ||||
|         major, minor, serial = int(major), int(minor), int(serial) | ||||
|         releaselevel = {'a': 'alpha', 'b': 'beta', '.': 'final'}[releaselevel] | ||||
|         if releaselevel == 'final': | ||||
|             _tk_patchlevel = major, minor, serial, releaselevel, 0 | ||||
|         else: | ||||
|             _tk_patchlevel = major, minor, 0, releaselevel, serial | ||||
|         _tk_patchlevel = tcl.info_patchlevel() | ||||
|     return _tk_patchlevel | ||||
| 
 | ||||
| units = { | ||||
|  |  | |||
|  | @ -341,6 +341,35 @@ def callback(): | |||
|         self.assertEqual(log, [1]) | ||||
|         self.assertTrue(self.root.winfo_exists()) | ||||
| 
 | ||||
|     def test_info_patchlevel(self): | ||||
|         vi = self.root.info_patchlevel() | ||||
|         f = tkinter.Frame(self.root) | ||||
|         self.assertEqual(f.info_patchlevel(), vi) | ||||
|         # The following is almost a copy of tests for sys.version_info. | ||||
|         self.assertIsInstance(vi[:], tuple) | ||||
|         self.assertEqual(len(vi), 5) | ||||
|         self.assertIsInstance(vi[0], int) | ||||
|         self.assertIsInstance(vi[1], int) | ||||
|         self.assertIsInstance(vi[2], int) | ||||
|         self.assertIn(vi[3], ("alpha", "beta", "candidate", "final")) | ||||
|         self.assertIsInstance(vi[4], int) | ||||
|         self.assertIsInstance(vi.major, int) | ||||
|         self.assertIsInstance(vi.minor, int) | ||||
|         self.assertIsInstance(vi.micro, int) | ||||
|         self.assertIn(vi.releaselevel, ("alpha", "beta", "final")) | ||||
|         self.assertIsInstance(vi.serial, int) | ||||
|         self.assertEqual(vi[0], vi.major) | ||||
|         self.assertEqual(vi[1], vi.minor) | ||||
|         self.assertEqual(vi[2], vi.micro) | ||||
|         self.assertEqual(vi[3], vi.releaselevel) | ||||
|         self.assertEqual(vi[4], vi.serial) | ||||
|         self.assertTrue(vi > (1,0,0)) | ||||
|         if vi.releaselevel == 'final': | ||||
|             self.assertEqual(vi.serial, 0) | ||||
|         else: | ||||
|             self.assertEqual(vi.micro, 0) | ||||
|         self.assertTrue(str(vi).startswith(f'{vi.major}.{vi.minor}')) | ||||
| 
 | ||||
| 
 | ||||
| class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase): | ||||
| 
 | ||||
|  |  | |||
|  | @ -517,4 +517,4 @@ def test(self, option=option): | |||
| def setUpModule(): | ||||
|     if test.support.verbose: | ||||
|         tcl = tkinter.Tcl() | ||||
|         print('patchlevel =', tcl.call('info', 'patchlevel')) | ||||
|         print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True) | ||||
|  |  | |||
|  | @ -0,0 +1,3 @@ | |||
| In the :mod:`tkinter` module add method ``info_patchlevel()`` which returns | ||||
| the exact version of the Tcl library as a named tuple similar to | ||||
| :data:`sys.version_info`. | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka