From 9ec2d5767a54af14f889c54c35794d3900a0ef21 Mon Sep 17 00:00:00 2001 From: Andrea Alegre Date: Mon, 6 Nov 2023 08:44:56 +0100 Subject: [PATCH 1/3] Traducido archivo library/weakref (#2733) Closes #2615 --------- Co-authored-by: rtobar --- library/weakref.po | 86 ++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/library/weakref.po b/library/weakref.po index 31e003654f..85279986a1 100644 --- a/library/weakref.po +++ b/library/weakref.po @@ -11,15 +11,16 @@ msgstr "" "Project-Id-Version: Python 3.8\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-10-12 19:43+0200\n" -"PO-Revision-Date: 2021-08-04 21:07+0200\n" -"Last-Translator: Cristián Maureira-Fredes \n" -"Language: es_PE\n" +"PO-Revision-Date: 2023-11-05 22:46+0100\n" +"Last-Translator: Andrea Alegre \n" "Language-Team: python-doc-es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.13.0\n" +"X-Generator: Poedit 3.4\n" #: ../Doc/library/weakref.rst:4 msgid ":mod:`weakref` --- Weak references" @@ -144,7 +145,6 @@ msgstr "" "`weakref` para el beneficio de usuarios avanzados." #: ../Doc/library/weakref.rst:68 -#, fuzzy msgid "" "Not all objects can be weakly referenced. Objects which support weak " "references include class instances, functions written in Python (but not in " @@ -152,12 +152,12 @@ msgid "" "object>`, :term:`generators `, type objects, sockets, arrays, " "deques, regular expression pattern objects, and code objects." msgstr "" -"No todos los objetos pueden ser débilmente referenciados; esos objetos que " -"pueden incluir instancias de clases, funciones escritas en Python (pero no " -"en C), métodos de instancia, conjuntos, frozensets, algunos :term:`objetos " -"de archivo `, :term:`generadores `, objetos de " -"tipos, sockets, arreglos, deques, objetos de patrones de expresiones " -"regulares, y objetos código." +"No todos los objetos pueden ser débilmente referenciados. Objetos que " +"soportan referencias débiles pueden incluir instancias de clases, funciones " +"escritas en Python (pero no en C), métodos de instancia, conjuntos, " +"frozensets, algunos :term:`objetos archivo `, :term:" +"`generadores `, objetos de tipo, sockets, arreglos, deques, " +"objetos de patrones de expresiones regulares, y objetos código." #: ../Doc/library/weakref.rst:74 msgid "Added support for thread.lock, threading.Lock, and code objects." @@ -234,15 +234,15 @@ msgstr "" "retrollamada registrada más antigua." #: ../Doc/library/weakref.rst:112 -#, fuzzy msgid "" "Exceptions raised by the callback will be noted on the standard error " "output, but cannot be propagated; they are handled in exactly the same way " "as exceptions raised from an object's :meth:`~object.__del__` method." msgstr "" -"Las excepciones lanzadas por la retrollamada serán anotadas en la salida de " -"error estándar, pero no pueden ser propagadas; son manejadas igual que las " -"excepciones lanzadas por el método :meth:`__del__` de un objeto." +"Las excepciones lanzadas por la retrollamada serán visibles en la salida de " +"error estándar pero no pueden ser propagadas; son manejadas de la misma " +"forma que las excepciones lanzadas por el método :meth:`~object.__del__` de " +"un objeto." #: ../Doc/library/weakref.rst:116 msgid "" @@ -291,7 +291,6 @@ msgid "Added the :attr:`__callback__` attribute." msgstr "Se añadió el atributo :attr:`__callback__`." #: ../Doc/library/weakref.rst:140 -#, fuzzy msgid "" "Return a proxy to *object* which uses a weak reference. This supports use " "of the proxy in most contexts instead of requiring the explicit " @@ -309,15 +308,18 @@ msgstr "" "retornado tendrá un tipo ``ProxyType`` o ``CallableProxyType``, dependiendo " "si *object* es invocable. Objetos Proxy no son :term:`hashable` " "independiente de la referencia; esto evita un número de problemas " -"relacionados a su naturaleza mutable fundamental, y previene su uso como " -"claves de diccionario. *callback* es el mismo como el parámetro del mismo " -"nombre de la función :func:`ref`." +"relacionados a su naturaleza mutable fundamental, y evita su uso como clave " +"de diccionario. *callback* corresponde al parámetro del mismo nombre de la " +"función :func:`ref`." #: ../Doc/library/weakref.rst:149 msgid "" "Accessing an attribute of the proxy object after the referent is garbage " "collected raises :exc:`ReferenceError`." msgstr "" +"Acceder al atributo de un objeto proxy después de que el objeto referenciado " +"haya sido recolectado por el recolector de basura lanza :exc:" +"`ReferenceError`." #: ../Doc/library/weakref.rst:152 msgid "" @@ -363,10 +365,16 @@ msgid "" "not replace the existing key. Due to this, when the reference to the " "original key is deleted, it also deletes the entry in the dictionary::" msgstr "" +"Nótese que cuando una clave cuyo valor es igual a una clave ya existente " +"(pero no tienen igual identidad) es insertado en el diccionario, el valor es " +"reemplazado pero no se reemplaza la clave existente. Debido a esto, cuando " +"la referencia a la clave original es eliminada, se elimina la entrada en el " +"diccionario::" #: ../Doc/library/weakref.rst:188 msgid "A workaround would be to remove the key prior to reassignment::" msgstr "" +"Una solución alternativa sería remover la clave antes de la reasignación::" #: ../Doc/library/weakref.rst:199 msgid "Added support for ``|`` and ``|=`` operators, specified in :pep:`584`." @@ -412,14 +420,12 @@ msgstr "" "pep:`584`." #: ../Doc/library/weakref.rst:223 -#, fuzzy msgid "" ":class:`WeakValueDictionary` objects have an additional method that has the " "same issues as the :meth:`WeakKeyDictionary.keyrefs` method." msgstr "" "Los objetos :class:`WeakValueDictionary` tienen un método adicional que " -"tiene los mismos problemas que el método :meth:`keyrefs` de los objetos :" -"class:`WeakyKeyDictionary`." +"posee los mismos problemas que el método :meth:`WeakKeyDictionary.keyrefs`." #: ../Doc/library/weakref.rst:229 msgid "Return an iterable of the weak references to the values." @@ -452,6 +458,8 @@ msgid "" "*callback* is the same as the parameter of the same name to the :func:`ref` " "function." msgstr "" +"*callback* corresponde al parámetro del mismo nombre de la función :func:" +"`ref`." #: ../Doc/library/weakref.rst:270 msgid "" @@ -480,7 +488,6 @@ msgstr "" "`None`." #: ../Doc/library/weakref.rst:280 -#, fuzzy msgid "" "Exceptions raised by finalizer callbacks during garbage collection will be " "shown on the standard error output, but cannot be propagated. They are " @@ -490,7 +497,7 @@ msgstr "" "Las excepciones lanzadas por retrollamadas de finalizadores durante la " "recolección de basura serán mostradas en la salida de error estándar, pero " "no pueden ser propagadas. Son gestionados de la misma forma que las " -"excepciones lanzadas del método :meth:`__del__` de un objeto o la " +"excepciones lanzadas por el método :meth:`~object.__del__` de un objeto o la " "retrollamada de una referencia débil." #: ../Doc/library/weakref.rst:286 @@ -510,8 +517,9 @@ msgid "" "replaced by :const:`None`." msgstr "" "Un finalizador nunca invocará su retrollamada durante la última parte del :" -"term:`interpreter shutdown ` cuando los módulos " -"globales están sujetos a ser reemplazados por :const:`None`." +"term:`apagado del intérprete ` cuando las variables " +"globales del módulo (globals) están sujetos a ser reemplazados por :const:" +"`None`." #: ../Doc/library/weakref.rst:296 msgid "" @@ -734,9 +742,8 @@ msgstr "" "Por ejemplo" #: ../Doc/library/weakref.rst:526 -#, fuzzy msgid "Comparing finalizers with :meth:`~object.__del__` methods" -msgstr "Comparando finalizadores con los métodos :meth:`__del__`" +msgstr "Comparando finalizadores con los métodos :meth:`~object.__del__`" #: ../Doc/library/weakref.rst:528 msgid "" @@ -753,45 +760,42 @@ msgid "the object is garbage collected," msgstr "el objeto es recolectado por el recolector de basura," #: ../Doc/library/weakref.rst:533 -#, fuzzy msgid "the object's :meth:`!remove` method is called, or" -msgstr "el método :meth:`remove` del objeto es llamado, o" +msgstr "el método :meth:`!remove` del objeto es llamado, o" #: ../Doc/library/weakref.rst:534 msgid "the program exits." msgstr "el programa sale." #: ../Doc/library/weakref.rst:536 -#, fuzzy msgid "" "We might try to implement the class using a :meth:`~object.__del__` method " "as follows::" msgstr "" -"Nosotros podemos intentar implementar la clase usando el método :meth:" -"`__del__` como sigue::" +"Podemos intentar implementar la clase usando un método :meth:`~object." +"__del__` como se muestra a continuación::" #: ../Doc/library/weakref.rst:555 -#, fuzzy msgid "" "Starting with Python 3.4, :meth:`~object.__del__` methods no longer prevent " "reference cycles from being garbage collected, and module globals are no " "longer forced to :const:`None` during :term:`interpreter shutdown`. So this " "code should work without any issues on CPython." msgstr "" -"Empezando con Python 3.4, Los métodos :meth:`__del__` ya no previenen ciclos " -"de referencia de ser recolectado como basura, y los módulos globales ya no " -"fuerzan :const:`None` durante :term:`interpreter shutdown`. Por lo que este " -"código debe trabajar sin ningún problema en CPython." +"A partir de Python 3.4, los métodos :meth:`~object.__del__` ya no impiden " +"que los ciclos de referencia sean recolectados como basura y las variables " +"globales del módulo (globals) ya no son forzados a :const:`None` durante el :" +"term:`apagado del intérprete `. Por lo tanto, este " +"código debería funcionar sin ningún problema en CPython." #: ../Doc/library/weakref.rst:560 -#, fuzzy msgid "" "However, handling of :meth:`~object.__del__` methods is notoriously " "implementation specific, since it depends on internal details of the " "interpreter's garbage collector implementation." msgstr "" -"Sin embargo, la gestión de métodos :meth:`__del__` es notoriamente " -"específico por la implementación, ya que depende de detalles internos de la " +"Sin embargo, la gestión de métodos :meth:`~object.__del__` es notoriamente " +"específica a la implementación, ya que depende de detalles internos de la " "implementación del recolector de basura del intérprete." #: ../Doc/library/weakref.rst:564 From 811360bb2e1f9ed49b2a5357456c95b4cd617e7e Mon Sep 17 00:00:00 2001 From: rtobar Date: Mon, 6 Nov 2023 20:16:21 +0800 Subject: [PATCH 2/3] Acelera las ejecuciones en CI (#2702) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Este PR modifica el job `Test` del workflow `Test` (i.e., el pipeline que se corre en cada PR y push a 3.12) con los siguientes cambios: * Checkout del submodule cpython se hace como parte de `actions/checkout` (no hay beneficio en hacerlo por cuentra propia) * Re-agrupa y comenta los distintos pasos del workflow * Configure apt and dpkg para correr de manera más eficiente, evitando la ejecución de algunos triggers que son innecesarios y que consumen CPU. * Instala `locales-all` para evitar la generación de los locales en español, ya que esta generación consume un largo tiempo de CPU, mientras que bajar el paquete es mucho más rápido. También se evita correr `apt update`. * Por último, y lo más complejo: cuando el workflow corre como parte de un PR, se calculan los archivos .po que han cambiado dentro del PR, y se corren los chequeos (sphinx-lint, powrap, pospell) sólo sobre estos archivos. Si el workflow corre como parte de un push a 3.12 todos los archivos se chequean. --------- Signed-off-by: Rodrigo Tobar Co-authored-by: Cristián Maureira-Fredes --- .github/workflows/main.yml | 63 ++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8e7dd1474..f3dfb25fc5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,34 +11,77 @@ jobs: name: Test runs-on: ubuntu-22.04 steps: + # Obtención del código - uses: actions/checkout@v4 + with: + submodules: 'true' + # Necesario para que tj-actions/changed-files se ejecute + # dentro de un tiempo adecuado + fetch-depth: 2 + + # Instalación de dependencias - name: Preparar Python v3.11 uses: actions/setup-python@v4 with: python-version: "3.11" cache: "pip" - - name: Sincronizar con CPython + - name: Configura dpkg/apt para ejecutarse de manera eficiente + uses: abbbi/github-actions-tune@v1 + - name: Deshabilita triggers de postgresql-common + run: sudo sed -i '/postgresql-common/d' /var/lib/dpkg/triggers/File + - name: Instalar dependencias de sistema run: | - git submodule update --init --depth=1 cpython - - name: Instalar dependencias + sudo apt-get install -y hunspell hunspell-es gettext language-pack-es locales-all + - name: Instalar dependencias de Python run: | - sudo apt-get update - sudo apt-get install -y hunspell hunspell-es gettext language-pack-es python -m pip install -r requirements.txt + - name: Listar paquetes y versiones + run: | pip list pospell --version powrap --version + + # Cálculo de los archivos .po a verificar. + # En el caso de un PR, sólo se chequean los .po que se están editando, + # mientras que en caseo de un push a las ramas 3.* queremos revisar + # todos los archivos + - name: Obtiene la lista de archivos .po con cambios (sólo en PRs) + if: github.event_name == 'pull_request' + id: changed-po-files + uses: tj-actions/changed-files@v40 + with: + files: | + **/*.po + - name: Calcula lista de archivos .po a revisar + id: po-files-to-check + env: + PO_FILES_TO_CHECK: ${{ steps.changed-po-files.conclusion == 'skipped' && '**/*.po' || steps.changed-po-files.outputs.all_changed_files }} + run: | + echo "po_files_to_check=$PO_FILES_TO_CHECK" >> $GITHUB_OUTPUT + echo "any_po_files_to_check=`test -n \"$PO_FILES_TO_CHECK\" && echo true || echo false`" >> $GITHUB_OUTPUT + - name: Muestra outputs de steps anteriores para debugueo + env: + CHANGED_PO_FILES: ${{ toJson(steps.changed-po-files) }} + PO_FILES_TO_CHECK: ${{ toJson(steps.po-files-to-check) }} + run: | + echo "steps.changed-po-files=$PO_FILES_TO_CHECK" + echo "steps.po-files-to-change.$CHANGED_PO_FILES" + + # Chequeos a realizar - name: TRANSLATORS run: | diff -Naur TRANSLATORS <(LANG=es python scripts/sort.py < TRANSLATORS) - name: Powrap - run: powrap --check --quiet **/*.po + if: steps.po-files-to-check.outputs.any_po_files_to_check == 'true' + run: powrap --check --quiet ${{ steps.po-files-to-check.outputs.po_files_to_check }} - name: Sphinx lint - run: | - sphinx-lint */*.po + if: steps.po-files-to-check.outputs.any_po_files_to_check == 'true' + run: sphinx-lint ${{ steps.po-files-to-check.outputs.po_files_to_check }} - name: Pospell - run: | - python scripts/check_spell.py + if: steps.po-files-to-check.outputs.any_po_files_to_check == 'true' + run: python scripts/check_spell.py ${{ steps.po-files-to-check.outputs.po_files_to_check }} + + # Construcción de la documentación - name: Construir documentación run: | # FIXME: Relative paths for includes in 'cpython' From 7680210a8d086d11436017e64b832b546794f547 Mon Sep 17 00:00:00 2001 From: rtobar Date: Tue, 7 Nov 2023 05:30:18 +0800 Subject: [PATCH 3/3] Agrega comentario a PR con entradas faltantes (#2726) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Este PR agrega una nueva acción que agrega un comentario a los PRs que editan archivos .po indicando qué entradas aún no tienen una traducción. Un ejemplo de esto funcionando se puede ver en https://github.com/rtobar/python-docs-es/pull/3. Hay varios comentarios automáticos porque use ese PR para debuguear el proceso, pero la idea es que finalmente haya un solo comentario que se va actualizando (como se puede ver en el último comentario, que está editado). Otro ejemplo se puede ver en https://github.com/rtobar/python-docs-es/pull/5, donde el PR viene desde un fork en vez de venir desde el mismo repositorio. Otra opción habría sido agregar un check a CI que falle si faltan entradas, pero en 3.11 ya tuvimos el caso en que *tuvimos* que dejar entradas fuzzy a propósito. --------- Signed-off-by: Rodrigo Tobar --- .github/workflows/pr-comment.yml | 45 ++++++++++++++++++++++++++ scripts/list_missing_entries.py | 55 ++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 .github/workflows/pr-comment.yml create mode 100644 scripts/list_missing_entries.py diff --git a/.github/workflows/pr-comment.yml b/.github/workflows/pr-comment.yml new file mode 100644 index 0000000000..7be6faccd1 --- /dev/null +++ b/.github/workflows/pr-comment.yml @@ -0,0 +1,45 @@ +name: Agrega comentario a PR + +on: + pull_request_target: + +jobs: + pr-comment: + name: Entradas sin traducción + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.merge_commit_sha }} + persist-credentials: false + - name: Preparar Python v3.11 + uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: "pip" + - name: Instalar dependencias + run: | + python -m pip install -r requirements.txt + - name: Obtiene lista de archivos con cambios + id: changed-files + uses: tj-actions/changed-files@v39 + with: + files: | + **/*.po + - name: Calcular entradas faltantes + if: steps.changed-files.outputs.any_changed == 'true' + id: create-pr-comment + env: + CHANGED_PO_FILES: ${{ steps.changed-files.outputs.all_changed_files }} + run: | + { + echo 'comment<> "$GITHUB_OUTPUT" + - name: Agregar comentario con entradas faltantes + if: steps.changed-files.outputs.any_changed == 'true' + uses: thollander/actions-comment-pull-request@v2 + with: + message: ${{ steps.create-pr-comment.outputs.comment }} + comment_tag: missing-entries diff --git a/scripts/list_missing_entries.py b/scripts/list_missing_entries.py new file mode 100644 index 0000000000..4c51b37a63 --- /dev/null +++ b/scripts/list_missing_entries.py @@ -0,0 +1,55 @@ +import argparse +import dataclasses +import enum +import glob +import itertools +import os + +import polib +import tabulate + + +class MissingReason(enum.StrEnum): + FUZZY = "fuzzy" + UNTRANSLATED = "untranslated" + + @staticmethod + def from_poentry(poentry: polib.POEntry): + if poentry.fuzzy: + return MissingReason.FUZZY + assert not poentry.translated() + return MissingReason.UNTRANSLATED + +@dataclasses.dataclass +class MissingEntry: + reason: MissingReason + file: str + line: int + + @staticmethod + def from_poentry(pofilename: str, poentry: polib.POEntry) -> "MissingEntry": + return MissingEntry(MissingReason.from_poentry(poentry), pofilename, poentry.linenum) + + +def find_missing_entries(filename: str) -> list[MissingEntry]: + po = polib.pofile(filename) + fuzzy = po.fuzzy_entries() + untranslated = po.untranslated_entries() + return [MissingEntry.from_poentry(filename, entry) for entry in fuzzy + untranslated] + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("files", nargs="+") + parser.add_argument("-g", "--github-mode", help="Produce output as a GitHub comment", action='store_true') + opts = parser.parse_args() + missing_entries = list(itertools.chain.from_iterable(map(find_missing_entries, opts.files))) + if not missing_entries: + print(f"All entries translated, horray!{' :tada:' if opts.github_mode else ''}") + else: + missing_entries.sort(key = lambda entry: (entry.file, entry.line)) + print("Entries missing translation, details follow:\n") + print(tabulate.tabulate(missing_entries,headers=["Reason", "File", "Line"], tablefmt="github")) + + +if __name__ == "__main__": + main()