Skip to content
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

script to search for and complete probable 'index entries' #2706

Merged
merged 7 commits into from
Dec 14, 2023

Conversation

cacrespo
Copy link
Collaborator

Si trabajamos con el .po directo no es sencillo identificar aquellas entradas que están vinculadas con la contrucción del índice general (y no con la página específica que se está traduciendo) . Acá más contexto.
Dado que mayormente son nombres de funciones, clases, etc. una de las propuestas es mantener el índice sin traducir y asegurar consistencia en los conceptos.

Este script toma un .po específico (o varios) y recorre una a una las entradas, identifica posibles entradas de índice -a partir del orden en el file- y ofrece completar la traducción con el mismo contenido que el original.

Copy link
Collaborator

@rtobar rtobar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cacrespo gracias por este nuevo script! No lo he probado, pero ya leyendo el código te dejo algunos comentarios que ojalá ayuden a organizar un poco mejor las cosas

scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
@rtobar rtobar mentioned this pull request Nov 1, 2023
@mmmarcos
Copy link
Collaborator

mmmarcos commented Nov 1, 2023

Hola @cacrespo ! No vi el script en detalle, pero tengo algunos comentarios:

  1. Yo creo que SI habría que traducir estas entradas: el índice permite buscar por palabras clave. Si en la doc general traducimos "method" por "método", tiene sentido que en el índice aparezca también "método". En la python-docs-fr han hecho esto (méthode). Obvio que no aplica para los nombres de métodos, módulos y demas..

  2. Si la idea es realmente no traducir ninguna entrada del índice, en lugar de tratar de detectar "probables" entradas (puede traer mas confusión para quien colabora por primera vez?), sería mejor identificarlas desde el archivo .rst correspondiente (todas comienzan con .. index:: no?)

scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
@cacrespo
Copy link
Collaborator Author

cacrespo commented Nov 3, 2023

Hola @cacrespo ! No vi el script en detalle, pero tengo algunos comentarios:

  1. Yo creo que SI habría que traducir estas entradas: el índice permite buscar por palabras clave. Si en la doc general traducimos "method" por "método", tiene sentido que en el índice aparezca también "método". En la python-docs-fr han hecho esto (méthode). Obvio que no aplica para los nombres de métodos, módulos y demas..
  2. Si la idea es realmente no traducir ninguna entrada del índice, en lugar de tratar de detectar "probables" entradas (puede traer mas confusión para quien colabora por primera vez?), sería mejor identificarlas desde el archivo .rst correspondiente (todas comienzan con .. index:: no?)

Gracias por los comentarios @mmmarcos. Van mis dos centavos, a ver qué te parece:

1_
Acá lo que me pasa es que si bien hay entradas que se traducen y queda muy bien; hay otras que finalmente van a terminar re-ordenando el índice de una manera poco conveniente.

Tomo el mismo ejemplo de la traducción francesa: fijate que tenés méthode, méthode magique, etc. pero después quedan varios method, methods, methodxxx, method_xxx, etc. Algunas se van a poder traducir, otras son clases y obviamente no; pero quedan todas más o menos juntas. Ahora bien, si fuera otra palabra (por ejemplo 'Función incorporada' por 'Built-in function') hay chances que algunos links queden en la letra "B" y otros en la "F". Esto es lo que me da la impresión que termina siendo perjudicial porque tenés conceptos similares en distintas partes de todo el índice.

A partir de ahí es que llego a la conclusión de que tal vez para esta sección es mejor sacrificar traducción para mantener consistencia. Sobretodo pensando en cómo se utiliza un índice :P

2_
Eso es lo que imagine como solución original pero desistí rápidamente... 👎
No me resultó claro cómo hacer el match vs el .rst. ¿para el .po puntual buscar el original y trabajar en las entradas? ¿generar nuevamente el file .po con algún parámetro que las señale...?

Me imaginaba el caso hipotético de alguien que se lleva el file a otra carpeta y hace el trabajo de forma "aislada". De modo, que opté por descartar la idea de vincular el procedimiento a cualquier otra cosa que no sea el propio .po y el script que trata de marcarlas.

¿Te convence?
Obviamente de ninguna manera es definitiva mi postura y estoy abierto a que reveamos y encontremos la mejor opción.

@mmmarcos
Copy link
Collaborator

mmmarcos commented Nov 5, 2023

1_ Acá lo que me pasa es que si bien hay entradas que se traducen y queda muy bien; hay otras que finalmente van a terminar re-ordenando el índice de una manera poco conveniente.

Tomo el mismo ejemplo de la traducción francesa: fijate que tenés méthode, méthode magique, etc. pero después quedan varios method, methods, methodxxx, method_xxx, etc. Algunas se van a poder traducir, otras son clases y obviamente no; pero quedan todas más o menos juntas. Ahora bien, si fuera otra palabra (por ejemplo 'Función incorporada' por 'Built-in function') hay chances que algunos links queden en la letra "B" y otros en la "F". Esto es lo que me da la impresión que termina siendo perjudicial porque tenés conceptos similares en distintas partes de todo el índice.

A partir de ahí es que llego a la conclusión de que tal vez para esta sección es mejor sacrificar traducción para mantener consistencia. Sobretodo pensando en cómo se utiliza un índice :P

Muy cierto! creo que en algún momento tuve la misma duda con las entradas que no empiezan con la misma letra (me debo haber olvidado ^^). En este sentido eran mas prácticas las instrucciones de Sphinx específicas a Python (module, class, ...) porque se podían traducir automáticamente, ahora con los index de tipo pair son palabras "libres" y pueden haber inconsistencia en las traducciones.

+1 por tu propuesta!

2_ Eso es lo que imagine como solución original pero desistí rápidamente... 👎 No me resultó claro cómo hacer el match vs el .rst. ¿para el .po puntual buscar el original y trabajar en las entradas? ¿generar nuevamente el file .po con algún parámetro que las señale...?

Me imaginaba el caso hipotético de alguien que se lleva el file a otra carpeta y hace el trabajo de forma "aislada". De modo, que opté por descartar la idea de vincular el procedimiento a cualquier otra cosa que no sea el propio .po y el script que trata de marcarlas.

¿Te convence? Obviamente de ninguna manera es definitiva mi postura y estoy abierto a que reveamos y encontremos la mejor opción.

Convencido! 👍

@cacrespo
Copy link
Collaborator Author

cacrespo commented Nov 15, 2023

He vuelto! 🎈
@rtobar muchas gracias -de nuevo- por los comentarios y sugerencias. A ver ahora qué tal...

No me convence mucho el hecho que aplique .save() a todos los files que se iteran. Con idenpendencia si se ajustó o no alguna linea. De hecho todo este bloque me parece que se ve "feo".

    for entry in po_entries:
        source_index = int(entry.occurrences[0][1])

        if source_index <= val_max:
            yield(entry)
            po_file.save()

        val_max = max(val_max, source_index)

¿qué les parece?

Copy link
Collaborator

@rtobar rtobar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cacrespo se ve súper bien, gracias por tomar a cuenta los comentarios! Queda un par de detalles, pero después de resolverlos ya creo que queda todo bastante bien.

scripts/complete_index.py Outdated Show resolved Hide resolved
scripts/complete_index.py Outdated Show resolved Hide resolved
@cacrespo
Copy link
Collaborator Author

@rtobar Impacté las recomendaciones y sumé un pequeño ajuste visual.

A diferencia de la versión anterior, ahora le pasamos a la función out_of_order_entries() un objeto po_file y no la ruta del file. De este modo podemos hacer el po_file.save() en la función principal -y out_of_order_entries() ya no abre el file sino que únicamente identifica las filas que están fuera de orden... tal y como lo señala su nombre ;-) -

Copy link
Collaborator

@rtobar rtobar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

¡Perdón @cacrespo por la demora nuevamente! Te dejo un solo comentario más y ya y lo mergeamos, ¿qué te parece?

scripts/complete_index.py Outdated Show resolved Hide resolved
@rtobar
Copy link
Collaborator

rtobar commented Dec 6, 2023

Otra cosita más: acabo de darle una prueba al script ejecutándolo sobre los contenidos de library/*.po (ejecuté yes | python scripts/complete_index.py library/*.po) y me encontré con dos puntos a notar:

  • polib, al guardar los archivos .po, usa una lógica distinta a la que usa powrap al momento de lidiar con espacios (powrap los tiende a poner al final de línea, mientras que polib los pone al frente de la siguiente). Esto quiere decir que después de ejecutar el script igual es necesario ejecutar powrap sobre los archivos que fueron modificados.
  • Si bien el script parece capturar los casos que nos interesan, hay mucho falso positivo también.. Uno esperaría que en cada archivo no hubiese muchas modificaciones, sin embargo éste es el output de git diff --stat después de ejecutar el script y powrap:
 library/2to3.po                          |   2 +-
 library/__future__.po                    |  24 ++++-----
 library/_thread.po                       |  22 ++++-----
 library/aifc.po                          |   6 +--
 library/array.po                         |  23 +++++----
 library/ast.po                           |  10 ++--
 library/asyncio-eventloop.po             |   6 +--
 library/asyncio-task.po                  |  16 +++---
 library/atexit.po                        |   4 +-
 library/audioop.po                       |  12 ++---
 library/audit_events.po                  |   4 +-
 library/base64.po                        |  19 ++++---
 library/binascii.po                      |  25 +++++-----
 library/calendar.po                      |   4 +-
 library/cgi.po                           |  46 ++++++++---------
 library/chunk.po                         |  28 +++++------
 library/cmath.po                         |   8 +--
 library/cmd.po                           |  10 ++--
 library/collections.abc.po               |  20 ++++----
 library/collections.po                   |  31 ++++--------
 library/compileall.po                    |  12 ++---
 library/concurrent.futures.po            |  25 +++++-----
 library/configparser.po                  |  31 ++++++------
 library/constants.po                     |   8 +--
 library/contextlib.po                    |   8 +--
 library/copy.po                          |  10 ++--
 library/copyreg.po                       |  10 ++--
 library/crypt.po                         |  18 +++----
 library/crypto.po                        |   2 +-
 library/csv.po                           |  14 +++---
 library/ctypes.po                        |  44 ++++++++---------
 library/curses.ascii.po                  |  12 ++---
 library/curses.po                        |  81 ++++++++++++++----------------
 library/dbm.po                           |  27 +++++-----
 library/difflib.po                       |  31 ++++++------
 library/dis.po                           |  43 ++++++++--------
 library/doctest.po                       |  24 ++++-----
 library/email.po                         |  16 +++---
 library/email.policy.po                  |  27 +++++-----
 library/ensurepip.po                     |  20 ++++----
 library/exceptions.po                    |  18 +++----
 library/faulthandler.po                  |   2 +-
 library/fcntl.po                         |  56 ++++++++++-----------
 library/filesys.po                       |  13 +++--
 library/fnmatch.po                       |  36 +++++++-------
 library/ftplib.po                        |  38 +++++++-------
 library/gettext.po                       |   4 +-
 library/glob.po                          |  24 ++++-----
 library/gzip.po                          |   8 +--
 library/html.parser.po                   |   8 +--
 library/http.client.po                   |  33 ++++++-------
 library/http.cookiejar.po                |  24 ++++-----
 library/http.cookies.po                  |  10 ++--
 library/http.po                          | 148 +++++++++++++++++++++++++++----------------------------
 library/http.server.po                   |  28 +++++------
 library/idle.po                          | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------
 library/imaplib.po                       |  30 +++++------
 library/imghdr.po                        |  26 +++++-----
 library/importlib.metadata.po            |  14 +++---
 library/importlib.po                     |  85 ++++++++++++++++----------------
 library/inspect.po                       | 149 +++++++++++++++++++++++++------------------------------
 library/io.po                            |  33 ++++++-------
 library/itertools.po                     |  39 +++++++--------
 library/json.po                          |   4 +-
 library/linecache.po                     |  10 ++--
 library/locale.po                        |  72 +++++++++++++--------------
 library/lzma.po                          |  25 +++++-----
 library/mailbox.po                       |  89 +++++++++++++++++----------------
 library/marshal.po                       |  16 +++---
 library/mimetypes.po                     |  14 +++---
 library/mmap.po                          |  12 ++---
 library/msilib.po                        |   6 +--
 library/multiprocessing.po               |  80 ++++++++++++++++--------------
 library/multiprocessing.shared_memory.po |  10 ++--
 library/nntplib.po                       |  28 +++++------
 library/operator.po                      |   8 +--
 library/optparse.po                      | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------
 library/os.path.po                       |  24 ++++-----
 library/os.po                            |  78 +++++++++++++++--------------
 library/ossaudiodev.po                   |  33 ++++++-------
 library/othergui.po                      |  63 +++++++++++-------------
 library/parser.po                        |  12 ++---
 library/pathlib.po                       |  18 +++----
 library/pdb.po                           |  24 ++++-----
 library/pickle.po                        |  42 ++++++++--------
 library/plistlib.po                      |  10 ++--
 library/poplib.po                        |  35 +++++++------
 library/posix.po                         |  12 ++---
 library/pprint.po                        |  12 ++---
 library/profile.po                       |  91 +++++++++++++++++-----------------
 library/pwd.po                           |  36 +++++++-------
 library/py_compile.po                    |   8 +--
 library/pydoc.po                         |  12 ++---
 library/pyexpat.po                       |  10 ++--
 library/queue.po                         |   8 +--
 library/quopri.po                        |  12 ++---
 library/re.po                            | 735 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------
 library/reprlib.po                       |   4 +-
 library/resource.po                      |  64 ++++++++++++------------
 library/runpy.po                         |   4 +-
 library/security_warnings.po             |   6 +--
 library/select.po                        | 140 +++++++++++++++++++++++++---------------------------
 library/selectors.po                     |  14 +++---
 library/shelve.po                        |  14 +++---
 library/shutil.po                        |  14 +++---
 library/site.po                          |  28 +++++------
 library/smtplib.po                       |  71 +++++++++++++-------------
 library/sndhdr.po                        |  32 ++++++------
 library/socketserver.po                  |  12 ++---
 library/ssl.po                           |  34 ++++++-------
 library/stdtypes.po                      | 606 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------
 library/string.po                        | 147 +++++++++++++++++++++++++++---------------------------
 library/struct.po                        |  50 +++++++++----------
 library/subprocess.po                    |  46 ++++++++---------
 library/sunau.po                         |  25 +++++-----
 library/sys.monitoring.po                |   2 +-
 library/sys.po                           | 102 +++++++++++++++++++-------------------
 library/sysconfig.po                     |  18 +++----
 library/syslog.po                        |  56 ++++++++++-----------
 library/tarfile.po                       |  71 +++++++++++++-------------
 library/telnetlib.po                     |  28 +++++------
 library/tempfile.po                      |  10 ++--
 library/termios.po                       |  10 ++--
 library/test.po                          |   6 +--
 library/textwrap.po                      |   8 +--
 library/threading.po                     |  19 ++++---
 library/time.po                          | 175 ++++++++++++++++++++++++++++++++---------------------------------
 library/timeit.po                        |   8 +--
 library/tk.po                            |   6 +--
 library/tkinter.po                       | 371 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------
 library/tkinter.tix.po                   |  16 +++---
 library/tkinter.ttk.po                   | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------------------------------
 library/token.po                         |  59 +++++++++++-----------
 library/tomllib.po                       |   8 +--
 library/trace.po                         |  10 ++--
 library/traceback.po                     |  14 +++---
 library/tracemalloc.po                   |  12 ++---
 library/types.po                         |  13 +++--
 library/undoc.po                         |   6 +--
 library/unicodedata.po                   |  10 ++--
 library/unittest.po                      |  66 ++++++++++++-------------
 library/urllib.parse.po                  |  72 +++++++++++++--------------
 library/urllib.request.po                |  32 ++++++------
 library/urllib.robotparser.po            |  12 ++---
 library/uu.po                            |   8 +--
 library/uuid.po                          |   5 +-
 library/venv.po                          | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------
 library/warnings.po                      |  68 +++++++++++--------------
 library/wave.po                          |   8 +--
 library/weakref.po                       |   5 +-
 library/webbrowser.po                    |  22 ++++-----
 library/winreg.po                        |  20 ++++----
 library/winsound.po                      |  12 ++---
 library/xdrlib.po                        |  13 +++--
 library/xml.dom.po                       |  37 +++++++-------
 library/xml.etree.elementtree.po         |  77 ++++++++++++++---------------
 library/xml.po                           |  31 ++++++------
 library/xml.sax.po                       |  17 +++----
 library/xmlrpc.client.po                 |  47 +++++++++---------
 library/zipapp.po                        |   6 +--
 library/zipfile.po                       |  26 +++++-----
 library/zipimport.po                     |  15 +++---
 library/zlib.po                          |   8 +--
 library/zoneinfo.po                      |  16 +++---
 166 files changed, 3645 insertions(+), 3862 deletions(-)

(antes de hacer powrap la estadística final decía 170 files changed, 39273 insertions(+), 38281 deletions(-))

Al ir por el diff mismo se hace más obvio cuáles son entradas del índice y cuáles no. Así que igual creo que usar el script sirve. Yo esperaba que quizás la heurística iba a ser suficiente como para hacer un commit con todos los cambios que encontrara, pero claramente no es así, y va a ser necesario ir manualmente verificando los resultados.

¿O quizás hay algún otro patrón que no hemos encontrado?

@cacrespo
Copy link
Collaborator Author

cacrespo commented Dec 11, 2023

@rtobar impactados los ajustes!

polib, al guardar los archivos .po, usa una lógica distinta a la que usa powrap al momento de lidiar con espacios (powrap los tiende a poner al final de línea, mientras que polib los pone al frente de la siguiente). Esto quiere decir que después de ejecutar el script igual es necesario ejecutar powrap sobre los archivos que fueron modificados...

Lo noté... 👎
En este issue mencionan algo parecido.

Aproveché y le cambié el ancho a la hora de cargar los pofiles ya que por lo que vi usamos 79 (y polib setea 78 por defecto).

@cacrespo
Copy link
Collaborator Author

Me quedé pensando en esto...

¿O quizás hay algún otro patrón que no hemos encontrado?

Pienso que una regla adhoc podría ser el largo de las entradas. Se supone que un índice tiene entradas cortas. Tal vez podríamos añadir una regla del tipo si la entrada > xxx caracteres es porque no es índice. Pero lo siento muy forzado.

Copy link
Collaborator

@rtobar rtobar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cacrespo gracias por atender al último set de comentarios que envié, y perdón por la nueva demora!

Estoy de acuerdo contigo que forzar un máximo de caracteres en las entradas como parte de la heurística para dar con las entradas del índice global es un poco forzado. La idea es igual que usemos este script para lidiar con la mayor cantidad de estas entradas, pero de seguro que vamos a tener que hacerlo con cuidado y mirando el output de cada archivo.

Voy a aprobar estos cambios, y mergear ya a 3.12. Y ahora que tenemos este script a disposición: ¡hay que usarlo!

@rtobar rtobar merged commit 58364e2 into python:3.12 Dec 14, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants