New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IDLE Internationalization #61976
Comments
Following the bpo-17760 Internationalization should be implemented. I'm not experienced with the idlelib module but here is a first patch, don't hesitate to comment it. It just add i18n to the menu for now. |
Excellent. I've started playing with pygettext and msgfmt and it looks like this works, from the initial tests I've made |
Whether and how much to internationalize Idle is being discussed on idle-dev thread "I18n of IDLE's interface ?". I was going to suggest there that the menu system would be the first place to start. A prime concern for me is that we not break anything (hence some of the questions below), and the menu labels seem relatively safe (compared to format strings -- see post on thread). While locale is used to format dates and times, I believe this would be the first use of gettext within the stdlib itself. To me it is a plausible to do because the idlelib modules are used to write and run code rather than being imported into code. I still have this concern: if a beginner can manage to handle 'English' keywords, builtin names, and exception names and messages*, does having translated menu labels give enough benefit to be worth the bother? I am open to the answer being yes, but before I were to commit this patch to the CPython repository, I would like to see a working example translation and a report of a field test with real students. (* I an not including stdlib because many beginners programs make little use of imports.) As for the patch: It looks good as far as it goes, but I have little knowledge of locale and gettext beyond the bare bones and no experience with either. The gettext doc is not all that clear to me, and it seems exclusively unix-focused, whereas I am on Windows. My questions:
As for the first part: is the default behavior to simply echo the text passed in? If Idle executes in a non-default environment/locale, but there is no translation file, does it echo the original string (English) or raise an exception? Same question if there is an appropriate translation file but no entry for the particular string? Overall, does gettext *ever* raise an exception, or does it *always* return a string of the correct type, or might it return bytes when unicode is expected (in 3.x)? In other words, can replacing a string literal with a gettext call cause Idle to crash?
Let me put is another way. The patch by itself is useless. In fact, even if it is completely transparent to users, it will *not* be transparent to Idle developers working on the code. It will actually be a detriment* unless there is additional work done. Who do you two, or any other advocates of IdleIl8n envision as doing the various tasks needed to make it useful? Perhaps there should be an IdleIl8n project on PyPI. In fact, such a project could be done without 'official' cooperation. If indeed there is no such project, I would wonder whether such absence indicates an absence of need. Or is it knowledge of how? Testing something as a 3rd party distribution and getting community acceptance is one normal way for things to get added to the stdlib. (6, Suppose English speaking teachers or user might want to customize the menu labels. Can that also be done with .gettext?)
Thought also needs to be given to the extension mechanism. As I understand it, pygettest.py will not pick up menu entries dynamically added by extensions. Roger, the extension expert, might comment on this. |
Extensions would need to be modified to use the gettext module. |
Also, IDLE makes use of features provided by Tk and those vary by platform. In some cases, IDLE uses some Tk-supplied default menus and menu items. So internationalization of IDLE would need to investigate and make use of Tk i18n features on all supported platforms. |
+1 for internationalizing IDLE. Any decent GUI app is internationalized these days, even developer tools. Re: gettext, its semantics and API are a bit of a PITA, but it's basically the standard for internationalization of FLOSS projects. There are all kind of tools to help edit gettext localization files. Re: how to organize translation work, Olivier Berger already answered on idle-dev, I believe. |
Here is a new patch featuring: Things needed: To test it by yourself without touching your /usr/share/local you can modify the binddomain() (in i18n.py) to another dir: And put in this dir the "en" dir in the tar file. The .mo generation is explained in the module documentation. So, here is a tar archive with: |
A side note to justify the localization of IDLE: I think the internationalization part is important, It's a nearly invisible overhead for the code but it will be helpful for example:
But I'm against localizing exception messages and anything built into python I hope I responsed to some concerns. |
I answered my Q1 in msg187219: test.test_gettest is currently passing, with no skips, on 2.7 and 3.4 on Win 7. patch.diff: I would rather add the 4 lines of the proposed idle_i18n.py to an existing module, perhaps Bindings.py itself, since that is the first place _ will be used. I think +-60 modules is already too many. The binding of '_' to gettext.gettext conflicts with the somewhat common use of '_' as a dummy identifier. I do not know of any such uses in idlelib, but there might be. There are about 4500 lines in idlelib with '_'; too many to review. Someone should do a more refined search with an re that excludes '_' preceded or followed by an identifier char, to skip '__xyz__' or '_x' or 'y_'. If '_ is used for gettest, a new rule to not otherwise bind '_' should be added the currently non-existent Idle maintainer guide. patch2.tar.gz is not readable by Rietveld, Firefox, IE, or Windows. Patches should be uploaded as plaintext.diff or .patch. Damien: Contributors must submit a signed Contributor Agreement. See https://www.python.org/psf/contrib/ and https://www.python.org/psf/contrib/contrib-form/ (the online form). Please do this even before re-uploading patch2. Receipt and acceptance of a form is acknowledged by addition of an * after "Author: nick(real name)". |
I've run this regex over all the .py and .pyw files in idlelib: [^_'"a-zA-Z0-9]_[^a-zA-Z0-9_] The only possible conflict I've found is in rpc.py's displayhook() function, which sets builtins._ to the argument passed to displayhook(). There is a cryptic comment: # Set '_' to None to avoid recursion I'm not sure what the reasoning behind this code is. This was written by Andrew Svetlov for bpo-14200 |
I presume setting builtins._ is part of imitating the shell. It could be replace with setattr. |
I just noticed https://pypi.python.org/pypi/idle-lif/1.0 Python IDLE Language Pack. Have not looked at it. If someone decides to work on this, I have ideas on how i18n could be done with minimal impact on the code, partly based on https://pythonhosted.org/flufl.i18n/ |
In the last few months, configdialog has been refactored to have a class for each settings tab. This makes it easier to revise and add new options, such as 'menu language'. With this done, the IDLE features implemented as (optional) extensions were turned into normal features. Non-key option settings were moved to the General tab. The menu items were moved to mainmenu.py. Having everything in one place should make translation easier. When making further menu system changes, I will keep I18n in mind. AFAIK, there is no runtime need to have 60+translation calls in the invisible mainmenu.menudefs structure, which would make it harder to read. I would rather change the 'label=name' option in menu item insertion calls to 'label=_(name)' or 'label=gettext(name)' or possibly 'label=trandict[name]. In macosx the explicit "label='window'" would need the same change. So would the scattered context menu insertion calls. Just for translating the menu, gettext seems possibly like overkill. I remain reluctance to use it without my questions above answered. Another question: can the automatic selection mechanism be overridden by the user? All that is needed is a simple template file that creates a translation dictionary I think translation would be easiest if the template preserved both the order and hierarchical structure. It would be trivial to write a function to create a full version of the following. trandict = {
'file':
'_New File':
...
...
}
[Note: top level names like 'file' are lowercased in menudefs but then capitalized in the menu. Maybe they should be uppercased to start with.] The output instead could match what whatever the gettext machinery requires. I don't know if the gettext extractor preserves the order, but I am sure it will not preserve the structure. Recently, translations were added to the official doc site. A translation of the IDLE section should have a good-enough translation of the menu that can be extracted into a dict for IDLE. The only problem is that they will not have the underscores for hot keys. I don't know if these are universally used. The Japanese translation includes the IDLE section. The top level names (File, Edit, ... Help) are not tranlated. Perhaps the team felt that such terms should be familiar enough to Japanese users to not need translation. The dropdown menu labels *are* translated, but keep the English, as in |
Ned> IDLE uses some Tk-supplied default menus and menu items On Windows and *nix, the visible menu labels all come from IDLE. I don't yet understand what is going on with Mac menus. Some menu items call the tk file dialog, and the config highlight tab calls the color dialog, and these are localized however they are. But that does not affect the menus. Ned> So internationalization of IDLE would need to investigate and make use of Tk i18n features on all supported platforms. Other than the dialogs mentioned above, (and the font dialog that is not used) I don't know what features you mean. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: