]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91827: Add method info_pathlevel() in tkinter (GH-91829)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 6 May 2022 10:50:38 +0000 (13:50 +0300)
committerGitHub <noreply@github.com>
Fri, 6 May 2022 10:50:38 +0000 (13:50 +0300)
Doc/whatsnew/3.11.rst
Lib/idlelib/help_about.py
Lib/test/test_tcl.py
Lib/tkinter/__init__.py
Lib/tkinter/test/support.py
Lib/tkinter/test/test_tkinter/test_misc.py
Lib/tkinter/test/widget_tests.py
Misc/NEWS.d/next/Library/2022-04-22-19-11-31.gh-issue-91827.6P3gOI.rst [new file with mode: 0644]

index f679100863a031101dae6556500425cbd65599af..07e8332d51b61f6328c728cec1b740862673cdcc 100644 (file)
@@ -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
 -----------
 
index c59f49459980680f00497830f5c20f7b8ec47825..9cb3ba78c50ebdf82255b472ffbbaa2f2d5d0940 100644 (file)
@@ -76,8 +76,8 @@ class AboutDialog(Toplevel):
                        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 @@ class AboutDialog(Toplevel):
                       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)
index e73ad596fe6789d9069e1587563a7743f880fcb2..548914796ed762806370b39157b66f531b2393aa 100644 (file)
@@ -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 @@ class BigmemTclTest(unittest.TestCase):
 def setUpModule():
     if support.verbose:
         tcl = Tcl()
-        print('patchlevel =', tcl.call('info', 'patchlevel'))
+        print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True)
 
 
 if __name__ == "__main__":
index 2e7e21c6648ea80d84e87fa662f018e0a3a863da..3d23889c74f24274d1ced01fd0e192f3b066c362 100644 (file)
@@ -30,6 +30,7 @@ button.pack(side=BOTTOM)
 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 @@ class Misc:
 
     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,)
index dbc47a81e6515730e2fb0947668e18fab2e0dbda..9e26d04536f227d3298bada9c0983b18c28974f0 100644 (file)
@@ -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 = {
index 044eb10d688356f7b1229fb8dfdad485cf96e18f..620b6ed638c25aae756a5b73986e7069583174b1 100644 (file)
@@ -341,6 +341,35 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
         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):
 
index 37d1979c23f1d14e39684138e3a64e52f58c91c0..a450544c3ee6b89049cd6d00629ad3199b06f15e 100644 (file)
@@ -517,4 +517,4 @@ def add_standard_options(*source_classes):
 def setUpModule():
     if test.support.verbose:
         tcl = tkinter.Tcl()
-        print('patchlevel =', tcl.call('info', 'patchlevel'))
+        print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True)
diff --git a/Misc/NEWS.d/next/Library/2022-04-22-19-11-31.gh-issue-91827.6P3gOI.rst b/Misc/NEWS.d/next/Library/2022-04-22-19-11-31.gh-issue-91827.6P3gOI.rst
new file mode 100644 (file)
index 0000000..83b7522
--- /dev/null
@@ -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`.