classification
Title: idle_test: test_fontlist_key() fails if two font families have the same name
Type: Stage: resolved
Components: IDLE, Tests Versions: Python 3.9, Python 3.8, Python 3.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: terry.reedy Nosy List: cheryl.sabella, miss-islington, serhiy.storchaka, taleinat, terry.reedy, vstinner
Priority: normal Keywords: patch

Created on 2020-02-10 15:44 by vstinner, last changed 2020-02-11 11:59 by vstinner. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 18430 merged vstinner, 2020-02-10 16:10
PR 18436 closed miss-islington, 2020-02-10 20:47
PR 18437 closed miss-islington, 2020-02-10 20:47
PR 18441 merged miss-islington, 2020-02-10 21:20
PR 18442 merged miss-islington, 2020-02-10 21:21
PR 18449 merged terry.reedy, 2020-02-10 23:52
PR 18450 merged miss-islington, 2020-02-11 01:09
PR 18451 merged miss-islington, 2020-02-11 01:09
Messages (15)
msg361700 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-10 15:44
======================================================================
FAIL: test_fontlist_key (idlelib.idle_test.test_configdialog.FontPageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib64/python3.7/idlelib/idle_test/test_configdialog.py", line 104, in test_fontlist_key
    self.assertNotEqual(down_font, font)
AssertionError: 'Cantarell' == 'Cantarell'

Example:
---
import tkinter.ttk
import tkinter.font
frame = tkinter.ttk.Frame()
families=sorted(tkinter.font.families(frame))
for family in families:
    print(family)
---

Truncated output on my Fedora 31:
---
Abyssinica SIL
Android Emoji
AnjaliOldLipi
Bitstream Vera Sans
C059
Caladea
Cantarell
Cantarell
Cantarell
Cantarell
(...)
Comfortaa
Comfortaa
(...))
DejaVu Sans
DejaVu Sans
DejaVu Sans
(...)
Source Han Serif CN
Source Han Serif CN
Source Han Serif CN
Source Han Serif CN
Source Han Serif CN
Source Han Serif CN
Source Han Serif TW
Source Han Serif TW
Source Han Serif TW
Source Han Serif TW
Source Han Serif TW
Source Han Serif TW
(...)
---

I'm not sure if it's an issue in the unit test or an issue with the widget itself. Does it make sense to display the same font family name twice?
msg361701 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-10 16:14
I proposed PR 18430 to remove duplicated font family names.
msg361712 - (view) Author: Carol Willing (willingc) * (Python committer) Date: 2020-02-10 19:41
New changeset ed335cf53b5d4bca9a08c9b83ba684ba17be0f10 by Victor Stinner in branch 'master':
bpo-39600, IDLE: Remove duplicated font names (GH-18430)
https://github.com/python/cpython/commit/ed335cf53b5d4bca9a08c9b83ba684ba17be0f10
msg361721 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-02-10 21:16
Serhiy, do you know anything about the tkinter.font.families() tuple having duplicate names?  It strikes me as an OS or tk error.

On Windows, the tuple has groups of related names with a base name, such as 'Segoe UI' both alone and with suffixes, such as 'light', 'black', and 'symbol'.  I wonder if on Fedora 31 the duplicates are related names with the suffixes somehow left off.  Cheryl, do you see any of the above duplicated names de-duplicated on Ubuntu with suffixes?

Whether the duplicates are true duplicates, (same family repeated) or mistakes (related families missing suffixes), they should be useless to the user.  Clicking or scrolling through the duplicates should not change the font sample as 'Font(family=dupname)' will not change.

Victor, your example does not create a Listbox, so that cannot be the issue.  The only change to ConfigDialog when testing is that it is not made modal.  What puzzles me is that test_fontlist_key starts by explicitly activating the first font on the list, so that the first test on the Fedora machine should be 'Android Emoji' != 'Abyssinica SIL'.  Perhaps there is a bug in the tk on that machine.

Carol Willing merged the PR before I could review and edit.  I will add a follow-up after getting backport to work.
msg361727 - (view) Author: miss-islington (miss-islington) Date: 2020-02-10 21:38
New changeset 021a5694ede9d7be119f9ceb3ee7e8e518ec5002 by Miss Islington (bot) in branch '3.8':
bpo-39600, IDLE: Remove duplicated font names (GH-18430)
https://github.com/python/cpython/commit/021a5694ede9d7be119f9ceb3ee7e8e518ec5002
msg361728 - (view) Author: miss-islington (miss-islington) Date: 2020-02-10 21:39
New changeset 2e8097d1c7c04dd96061ec1498cfa088bce9085b by Miss Islington (bot) in branch '3.7':
bpo-39600, IDLE: Remove duplicated font names (GH-18430)
https://github.com/python/cpython/commit/2e8097d1c7c04dd96061ec1498cfa088bce9085b
msg361729 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-10 21:49
In LibreOffice, I see 4 flavors of "Cantarell" with different *weight* :

Cantarell
Cantarell Extra Bold
Cantarell Light
Cantarell Thin

whereas tkinter.font.families(frame) returns 4 times the same string: "Cantarell". The C function of Tk is TkpGetFontFamilies().

The X11 implementation uses XListFonts() which returns a string like "-foundry-family-weight-slant-(...)" but the function only returns the "family" substring: it ignores the foundy and the weight for example. So it's not surprising to get duplicates. Example: "-adobe-helvetica-bold-o-normal--11-80-100-100-p-60-iso8859-1" becomes "helvetica".

There is also a Xft implementation which uses XftListFonts(). Then it uses XftPatternGetString() to get a font family.

I see no logic in Tcl to exclude duplicated family names of different weights.

--

>>> tkinter.font.names(frame)
('TkCaptionFont', 'TkSmallCaptionFont', 'TkTooltipFont', 'TkFixedFont', 'TkHeadingFont', 'TkMenuFont', 'TkIconFont', 'TkTextFont', 'TkDefaultFont')

That's something different that I would call unrelated ;-)
msg361730 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-10 21:51
> Victor, your example does not create a Listbox, so that cannot be the issue.  The only change to ConfigDialog when testing is that it is not made modal.  What puzzles me is that test_fontlist_key starts by explicitly activating the first font on the list, so that the first test on the Fedora machine should be 'Android Emoji' != 'Abyssinica SIL'.  Perhaps there is a bug in the tk on that machine.

The test failure comes from our build system where very few fonts are limited. For example, you can imagine that only a few variants of Cantarell are installed.

Sorry, I forgot to mention that the test failure and the list of strings come from two different machines.

The list comes from my laptop where I have many fonts installed.
msg361767 - (view) Author: Cheryl Sabella (cheryl.sabella) * (Python committer) Date: 2020-02-11 00:51
I don't see the same duplicates that Victor listed, however I do see some duplicates.

(...)
DejaVu Sans
DejaVu Sans Mono
DejaVu Serif
(...)
Manjari
Manjari
Manjari
(...)
Mukti Narrow
Mukti Narrow
(...)
Ubuntu
Ubuntu
Ubuntu Condensed
Ubuntu Mono
(...)
msg361769 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-02-11 01:09
New changeset 96ce22706735779cf8cc46eaaa5ac61359364b5a by Terry Jan Reedy in branch 'master':
bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449)
https://github.com/python/cpython/commit/96ce22706735779cf8cc46eaaa5ac61359364b5a
msg361770 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-02-11 01:13
font.names() lists 'symbolic' family names guaranteed to exist.  'TkDefaultFont' is the default Text widget font on a particular OS.  IDLE replaces that with 'TkFixedFont', which is translated to the actual family name on each OS: Courier on Windows (ugh) and something like Monaco on macOS.

Thank you for the additional information.  For *nix users, removing the useless duplicates should be an improvement.  (This is aside from the test issue, which could have been fixed otherwise: perhaps by inserting 'TestFont' at the top of the list and making other adjustments.)
msg361771 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-02-11 01:21
Cheryl, it appears that only 'weight' words are deleted.  For a given family, Tk only has a (user) settable 'bold', so other weight options must be 'baked in' to the family.  Perhaps X11 allows more weight settings within a family, even if not exposed in Tk.
msg361772 - (view) Author: miss-islington (miss-islington) Date: 2020-02-11 01:27
New changeset c372f9b9e758a22608b8df33423b7413d224fdad by Miss Islington (bot) in branch '3.8':
bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449)
https://github.com/python/cpython/commit/c372f9b9e758a22608b8df33423b7413d224fdad
msg361773 - (view) Author: miss-islington (miss-islington) Date: 2020-02-11 01:28
New changeset 32c88407d24a700946e1a6429cd5ca616cb3a810 by Miss Islington (bot) in branch '3.7':
bpo-39600: Adjust code, add idlelib/NEWS item (GH-18449)
https://github.com/python/cpython/commit/32c88407d24a700946e1a6429cd5ca616cb3a810
msg361802 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2020-02-11 11:59
Thanks to everybody who was involved in this issue, it's nice to see a test fixed so quickly, especially when it enhances IDLE UI for end users ;-)
History
Date User Action Args
2020-02-11 11:59:49vstinnersetmessages: + msg361802
2020-02-11 04:24:24terry.reedysetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2020-02-11 01:28:07miss-islingtonsetmessages: + msg361773
2020-02-11 01:27:38miss-islingtonsetmessages: + msg361772
2020-02-11 01:21:27terry.reedysetmessages: + msg361771
2020-02-11 01:13:25terry.reedysetmessages: + msg361770
2020-02-11 01:09:30miss-islingtonsetpull_requests: + pull_request17825
2020-02-11 01:09:22miss-islingtonsetpull_requests: + pull_request17824
2020-02-11 01:09:05terry.reedysetmessages: + msg361769
2020-02-11 00:51:32cheryl.sabellasetmessages: + msg361767
2020-02-10 23:52:18terry.reedysetpull_requests: + pull_request17823
2020-02-10 21:51:40vstinnersetmessages: + msg361730
2020-02-10 21:49:10vstinnersetmessages: + msg361729
2020-02-10 21:39:47miss-islingtonsetmessages: + msg361728
2020-02-10 21:38:37miss-islingtonsetnosy: + miss-islington
messages: + msg361727
2020-02-10 21:21:04miss-islingtonsetpull_requests: + pull_request17816
2020-02-10 21:20:55miss-islingtonsetpull_requests: + pull_request17815
2020-02-10 21:16:58terry.reedysetnosy: + serhiy.storchaka, - willingc
messages: + msg361721
2020-02-10 20:47:15miss-islingtonsetpull_requests: + pull_request17811
2020-02-10 20:47:06miss-islingtonsetpull_requests: + pull_request17810
2020-02-10 19:41:40willingcsetnosy: + willingc
messages: + msg361712
2020-02-10 16:14:18vstinnersetmessages: + msg361701
2020-02-10 16:14:01vstinnersetversions: + Python 3.7, Python 3.8
2020-02-10 16:10:14vstinnersetkeywords: + patch
stage: patch review
pull_requests: + pull_request17805
2020-02-10 15:44:16vstinnersettitle: idle_test: test_fontlist_key() fails if two fonts have the same name -> idle_test: test_fontlist_key() fails if two font families have the same name
2020-02-10 15:44:03vstinnercreate