././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/0000775000175000017500000000000000000000000013276 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/.coveragerc0000664000175000017500000000015500000000000015420 0ustar00zuulzuul00000000000000[run] branch = True source = oslo_i18n omit = oslo_i18n/tests/* [report] ignore_errors = True precision = 2 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/.mailmap0000664000175000017500000000013000000000000014711 0ustar00zuulzuul00000000000000# Format is: # # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/.pre-commit-config.yaml0000664000175000017500000000252300000000000017561 0ustar00zuulzuul00000000000000# We from the Oslo project decided to pin repos based on the # commit hash instead of the version tag to prevend arbitrary # code from running in developer's machines. To update to a # newer version, run `pre-commit autoupdate` and then replace # the newer versions with their commit hash. default_language_version: python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: 9136088a246768144165fcc3ecc3d31bb686920a # v3.3.0 hooks: - id: trailing-whitespace # Replaces or checks mixed line ending - id: mixed-line-ending args: ['--fix', 'lf'] exclude: '.*\.(svg)$' # Forbid files which have a UTF-8 byte-order marker - id: check-byte-order-marker # Checks that non-binary executables have a proper shebang - id: check-executables-have-shebangs # Check for files that contain merge conflict strings. - id: check-merge-conflict # Check for debugger imports and py37+ breakpoint() # calls in python source - id: debug-statements - id: check-yaml files: .*\.(yaml|yml)$ - repo: local hooks: - id: flake8 name: flake8 additional_dependencies: - hacking>=6.1.0,<6.2.0 language: python entry: flake8 files: '^.*\.py$' exclude: '^(doc|releasenotes|tools)/.*$' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/.stestr.conf0000664000175000017500000000006200000000000015545 0ustar00zuulzuul00000000000000[DEFAULT] test_path=./oslo_i18n/tests top_path=./ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/.zuul.yaml0000664000175000017500000000037000000000000015237 0ustar00zuulzuul00000000000000- project: templates: - check-requirements - lib-forward-testing-python3 - openstack-cover-jobs - openstack-python3-jobs - periodic-stable-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/AUTHORS0000664000175000017500000000677200000000000014362 0ustar00zuulzuul00000000000000Adam Spiers Akihiro Motoki Akihiro Motoki Alessio Ababilov Anderson Mesquita Andreas Jaeger Andreas Jaeger Andrey Kurilin Balazs Gibizer Ben Nemec Ben Nemec Bo Chi Brant Knudson Chang Bo Guo ChangBo Guo(gcb) Charles Short Charles Short Christian Berendt Chuck Short Chuck Short Corey Bryant Dan Prince Daniel Bengtsson Davanum Srinivas Davanum Srinivas David Stanek Dina Belova Doug Hellmann Doug Hellmann Flavio Percoco Ghanshyam Ghanshyam Mann Hervé Beraud James Carey Jason Kölker Jay Pipes Jeremy Stanley Joe Gordon Joe Heck John Warren Joshua Harlow Joshua Harlow Juan Antonio Osorio Julien Danjou Kenneth Giusti Luis A. Garcia Luong Anh Tuan Mark McLoughlin Mathew Odden Matt Odden Michał Górny Moisés Guimarães de Medeiros Monty Taylor Nikhil Manchanda Noorul Islam K M OpenStack Release Bot Peng Wu Pete Zaitcev Rajaram Mallya Ronald Bradford Rosario Di Somma Russell Bryant Sean McGinnis Sean McGinnis Sergey Kraynev Stephen Finucane Steve Martinelli Takashi Kajinami Takashi Kajinami Thomas Herve Tony Breeds Victor Sergeyev Victor Stinner Vu Cong Tuan WangBinbin ZhiQiang Fan ZhijunWei Zhiteng Huang ZhongShengping Zhongyue Luo caoyuan haixin howardlee jacky06 kavithahr lingyongxu malei melissaml ricolin songwenping tonybrad venkatamahesh wangzihao wu.shiming yangyawei yanheven zhoulinhui ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/CONTRIBUTING.rst0000664000175000017500000000134100000000000015736 0ustar00zuulzuul00000000000000If you would like to contribute to the development of oslo's libraries, first you must take a look to this page: https://specs.openstack.org/openstack/oslo-specs/specs/policy/contributing.html If you would like to contribute to the development of OpenStack, you must follow the steps in this page: http://docs.openstack.org/infra/manual/developers.html Once those steps have been completed, changes to OpenStack should be submitted for review via the Gerrit tool, following the workflow documented at: http://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed on Launchpad, not GitHub: https://bugs.launchpad.net/oslo.i18n././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/ChangeLog0000664000175000017500000003457600000000000015067 0ustar00zuulzuul00000000000000CHANGES ======= 6.4.0 ----- * Remove old excludes * Update master for stable/2024.1 * reno: Update master for unmaintained/victoria 6.3.0 ----- * Display coverage report * Bump hacking * Update python classifier in setup.cfg * Fix leftover \`locale.getdefaultlocale\` mock 6.2.0 ----- * Update master for stable/2023.2 * Bump bandit 6.1.0 ----- * Imported Translations from Zanata * Imported Translations from Zanata * Revert "Moves supported python runtimes from version 3.8 to 3.10" * Moves supported python runtimes from version 3.8 to 3.10 * The locale.getdefaultlocale is deprecated * Update master for stable/2023.1 * tox: Remove 'ignore\_base\_python\_conflict' 6.0.0 ----- * Imported Translations from Zanata * Fix formatting of release list * Drop python3.6/3.7 support in testing runtime * Remove unnecessary unicode prefixes * Update CI to use unversioned jobs template * setup.cfg: Replace dashes by underscores 5.1.0 ----- * Changed minversion in tox to 3.18.0 * Switch testing to Xena testing runtime * Upgrade the pre-commit-hooks version * Fix requirements issues * Remove all usage of six library * Use TOX\_CONSTRAINTS\_FILE * Use py3 as the default runtime for tox * Fix hacking min version to 3.0.1 * Remove six.PY3 * Adding pre-commit * Add Python3 wallaby unit tests * Update master for stable/victoria 5.0.1 ----- * Bump bandit version 5.0.0 ----- * Stop to use the \_\_future\_\_ module * Remove a couple more shim tests * Imported Translations from Zanata * Remove Message.translate * Add Babel aliases to get\_available\_languages * Switch to newer openstackdocstheme and reno versions * Remove the unused coding style modules * Remove translation sections from setup.cfg * Align contributing doc with oslo's policy * Bump default tox env from py37 to py38 * Add py38 package metadata * Drop use of babel * Add release notes links to doc index * Add Python3 victoria unit tests * Update master for stable/ussuri 4.0.1 ----- * Use unittest.mock instead of third party mock * Update hacking for Python3 4.0.0 ----- * remove outdated header * [ussuri][goal] Drop python 2.7 support and testing * tox: Trivial cleanup 3.25.1 ------ * Imported Translations from Zanata * Integrate sphinxcontrib-apidoc 3.25.0 ------ * tox: Keeping going with docs * Update master for stable/train * Deprecate Message.translate in favor of Message.translation * Allow Message.translate to handle unhashable inputs 3.24.0 ------ * Add Python 3 Train unit tests * Move doc related modules to doc/requirements.txt * Clarify that translation strings are extracted via source inspection * Fix guidelines w.r.t. translation of log messages * Move to releases.openstack.org * Cap Bandit below 1.6.0 and update Sphinx requirement * Replace git.openstack.org URLs with opendev.org URLs * OpenDev Migration Patch * Dropping the py35 testing * Update master for stable/stein 3.23.1 ------ * add python 3.7 unit test job * Change python3.5 job to python3.7 job on Stein+ * Update hacking version * Update mailinglist from dev to discuss 3.23.0 ------ * Override getttext.find to cache result * Don't quote {posargs} in tox.ini * Clean up .gitignore references to personal tools * Always build universal wheels * Remove references to log translation functions * Use templates for cover and lower-constraints 3.22.1 ------ * Remove unused code * Imported Translations from Zanata * add lib-forward-testing-python3 test job * add python 3.6 unit test job * import zuul job settings from project-config * Update reno for stable/rocky 3.21.0 ------ * Switch to stestr * Add release notes to README.rst * fix tox python3 overrides * Remove moxstubout usage * Remove stale pip-missing-reqs tox test * Trivial: Update pypi url to new url * set default python to python3 * add lower-constraints job * Updated from global requirements 3.20.0 ------ * Imported Translations from Zanata * Update links in README * Imported Translations from Zanata * Update reno for stable/queens * Updated from global requirements * Updated from global requirements * Updated from global requirements 3.19.0 ------ * Remove -U from pip install * Avoid tox\_install.sh for constraints support * add bandit to pep8 job * Updated from global requirements * Remove setting of version/release from releasenotes * Updated from global requirements * Imported Translations from Zanata * Updated from global requirements 3.18.0 ------ * Updated from global requirements * Updated from global requirements * Imported Translations from Zanata * Update reno for stable/pike * Updated from global requirements 3.17.0 ------ * Imported Translations from Zanata * Update URLs in documents according to document migration 3.16.0 ------ * switch from oslosphinx to openstackdocstheme * turn on warning-is-error in doc build * rearrange the documentation to fit into the new standard layout * Updated from global requirements * Enable some off-by-default checks * Updated from global requirements * Updated from global requirements * Updated from global requirements 3.15.3 ------ * Revert "Remove Babel as a runtime requirement" 3.15.2 ------ * Updated from global requirements * Remove Babel as a runtime requirement 3.15.1 ------ * Updated from global requirements * Updated from global requirements * Updated from global requirements * Check reStructuredText documents for common style issues 3.15.0 ------ * add notes about skipping log translation setup * Updated from global requirements 3.14.0 ------ * Python 3.5 is added 3.13.0 ------ * Updated from global requirements * [Fix gate]Update test requirement * Fix wrong response with language zh-TW * Updated from global requirements * Update reno for stable/ocata 3.12.0 ------ * Add Constraints support * Show team and repo badges on README * Replace six.iteritems() with .items() 3.11.0 ------ * Updated from global requirements * Updated from global requirements * Updated from global requirements * Add reno for release notes management * Add missing dependency testscenarios * Typo fix in oslo.i18n * Changed the home-page link * Add docs on how to display translated strings in your app 3.10.0 ------ * Updated from global requirements 3.9.0 ----- * Updated from global requirements * Fix parameters of assertEqual are misplaced 3.8.0 ----- * Updated from global requirements * Don't include openstack/common in flake8 exclude list * Updated from global requirements 3.7.0 ----- * Imported Translations from Zanata * Updated from global requirements 3.6.0 ----- * Updated from global requirements * Updated from global requirements * Better isolate tests and fixtures from environment * Updated from global requirements 3.4.0 ----- * Imported Translations from Zanata 3.3.0 ----- * Update translation setup * Updated from global requirements * Imported Translations from Zanata * Updated from global requirements 3.2.0 ----- * Updated from global requirements * add versionadded designations to newer functions * doc: contextual/plural translation requires oslo.i18n >=2.1.0 * Trival: Remove 'MANIFEST.in' 3.1.0 ----- * [doc] Update \_i18n.py example to pass pep8 * Add missing blank in usage.rst * Remove Python 2.6 workround for logging * Drop python 2.6 support 3.0.0 ----- * Updated from global requirements * Remove python 2.6 classifier * Remove python 2.6 and cleanup tox.ini * Improved integration module documentation * Updated from global requirements * Imported Translations from Zanata 2.7.0 ----- * Fix coverage configuration and execution * No need for Oslo Incubator Sync * Enhance the formatting error robustness patch * Imported Translations from Zanata * Move 'history' -> release notes section * Add shields.io version/downloads links/badges into README.rst * Change ignore-errors to ignore\_errors * Added the home-page value with Oslo wiki * Updated from global requirements 2.6.0 ----- * Updated from global requirements * Updated from global requirements 2.5.0 ----- * Trap formatting errors 2.4.0 ----- * Imported Translations from Transifex * Updated from global requirements * Imported Translations from Transifex * Updated from global requirements * Clean up \_translate\_msgid logic a bit 2.3.0 ----- * Imported Translations from Transifex * Updated from global requirements 2.2.0 ----- * Imported Translations from Transifex * Updated from global requirements * Updated from global requirements * Updated from global requirements * Updated from global requirements * Fix mock use for 1.1.0 * Add requirements for pre-release test scripts * Imported Translations from Transifex 2.1.0 ----- * Only define CONTEXT\_SEPARATOR once * Support contextual and plural form of gettext functions * Imported Translations from Transifex * clarify translation policy * Add tox target to find missing requirements * Imported Translations from Transifex 2.0.0 ----- * Updated from global requirements * Updated from global requirements * Remove oslo namespace package 1.7.0 ----- * Advertise support for Python3.4 / Remove support for Python 3.3 * Updated from global requirements * Misplaced parenthesis causing confusion * Remove run\_cross\_tests.sh * Imported Translations from Transifex 1.6.0 ----- * Uncap library requirements for liberty * Standardize setup.cfg summary for oslo libs * Updated from global requirements * Move to hacking 0.10 * Update guideline doc of multiple use msg case 1.5.0 ----- * Updated from global requirements 1.4.0 ----- * Add test fixture to prefix lazily translated messages 1.3.1 ----- * Clear global cache in test\_get\_available\_languages * Make setup.cfg packages include oslo.i18n * Improve fixture documentation 1.3.0 ----- * Add a fixture to let tests manage the lazy flag * Fix the link to the bug tracker in the README 1.2.0 ----- * Correct the translation domain for loading messages * Move out of the oslo namespace package * Workflow documentation is now in infra-manual * Force code sample to be treated as python 1.1.0 ----- * Imported Translations from Transifex * Add note for integration modules in libraries * Activate pep8 check that \_ is imported * Add pbr to installation requirements * Updated from global requirements * Updated from global requirements * Remove extraneous vim editor configuration comments * Make clear in docs to use \_LE() when using LOG.exception() * Support building wheels (PEP-427) * Imported Translations from Transifex * Fix coverage testing * Imported Translations from Transifex * Use same indentation in doc/source/usage * Imported Translations from Transifex * Imported Translations from Transifex * Updated from global requirements * Remove unused/mutable default args * Fixes a small syntax error in the doc examples 1.0.0 ----- * Add missing six dependency 0.3.0 ----- * Imported Translations from Transifex * Work toward Python 3.4 support and testing * Updated from global requirements * Imported Translations from Transifex * Document how to add import exceptions 0.2.0 ----- * Add a test fixture for translatable strings * Imported Translations from Transifex * Remove mention of Message objects from public docs * Add Changelog to the documentation 0.1.0 ----- * Shift public API to top level package * Add links to policy discussions * Improve initial documentation * Update sphinx and hacking requirements * Fix import grouping in tests * Build locale dir env var name consistently * Updated from global requirements * Remove Babel version workaround code * Trivial refactors for gettextutils * Setup for translation * Update the public API of the library * Check the lazy flag at runtime * Handle . and - in translation domains * Split up monolithic test file * Updated from global requirements * Fix up usage instructions * fix docstring for fakes module * Update default tox settings * update .gitreview * update tests for python 3 * sync cross-test script from incubator * pep8 fixes from import * update .gitignore with new lib name * Make unit tests pass * initial export with graduate.sh * Add API for creating translation functions * Use oslotest instead of common test module * Fix test\_gettextutils on Python 3 * Fix gettextutil.Message handling of deep copy failures * Change lazy translation to retain complete dict * Remove requirements.txt from .gitignore * Add etc/openstack.conf.sample to .gitignore * Add support for translating log levels separately * Fix E501 in individual openstack projects * Fix test method use * Make Message keep string interpolation args * Add support for locales missing from babel * Allow the Message class to have non-English default locales * Implementation of translation log handler * Use hacking import\_exceptions for gettextutils.\_ * Translation Message improvements * Fix violations of H302:import only modules * Fixed misspellings of common words * Trivial: Make vertical white space after license header consistent * Remove vim header * Use six.text\_type instead of unicode function in tests * Fix typos in oslo * Adjust import order according to PEP8 imports rule * Replace assertEquals with assertEqual * When translating if no locale is given use default locale * Type check for Message param to avoid AttributeError * gettextutils: port to Python 3 * Translate all substitution elements of a Message object * python3: Fix UserString import * Replace using tests.utils part2 * Enable multiple translation domains for gettextutils * Bump hacking to 0.7.0 * Allow mapping \_ to lazy gettext path * Fix Message format-string parsing * Add common methods required to allow translation of REST API responses * Add eclipse project files to .gitignore * Add more robust gettext interpolation handling * Add .testrepository to .gitignore * python3: Add basic python3 compatibility * Enable hacking H404 test * Add basic lazy gettext implementation * Ignore backup files in .gitignore * Support overriding oslo localedir too * Add a gettextutils.install() helper function * gettextutils: fix translation domain * Fix Copyright Headers - Rename LLC to Foundation * Add join\_consumer\_pool() to RPC connections * Replace direct use of testtools BaseTestCase * Use testtools as test base class * Fixes import order errors * Add common base weigher/weigher handler for filter scheduler * updating sphinx documentation * Correcting openstack-common mv to oslo-incubator * Update .gitreview for oslo * .gitignore updates for generated files * Add gettext support * Updated tox config for multi-python testing * Added .gitreview file * ignore cover's html directory * Rajaram/Vinkesh|increased tests for Request and Response serializers * Rajaram/Vinkesh|Added nova's serializaiton classes into common * Initial skeleton project ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/HACKING.rst0000664000175000017500000000017000000000000015072 0ustar00zuulzuul00000000000000Style Commandments ================== Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/LICENSE0000664000175000017500000002363600000000000014315 0ustar00zuulzuul00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/PKG-INFO0000664000175000017500000000436600000000000014404 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: oslo.i18n Version: 6.4.0 Summary: Oslo i18n library Home-page: https://docs.openstack.org/oslo.i18n/latest Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: ======================== Team and repository tags ======================== .. image:: https://governance.openstack.org/tc/badges/oslo.i18n.svg :target: https://governance.openstack.org/tc/reference/tags/index.html .. Change things from this point on ================================================== oslo.i18n -- Oslo Internationalization Utilities ================================================== .. image:: https://img.shields.io/pypi/v/oslo.i18n.svg :target: https://pypi.org/project/oslo.i18n/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/oslo.i18n.svg :target: https://pypi.org/project/oslo.i18n/ :alt: Downloads The oslo.i18n library contain utilities for working with internationalization (i18n) features, especially translation for text strings in an application or library. * Free software: Apache license * Documentation: https://docs.openstack.org/oslo.i18n/latest * Source: https://opendev.org/openstack/oslo.i18n * Bugs: https://bugs.launchpad.net/oslo.i18n * Release notes: https://docs.openstack.org/releasenotes/oslo.i18n/ Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: Implementation :: CPython Requires-Python: >=3.8 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/README.rst0000664000175000017500000000210100000000000014757 0ustar00zuulzuul00000000000000======================== Team and repository tags ======================== .. image:: https://governance.openstack.org/tc/badges/oslo.i18n.svg :target: https://governance.openstack.org/tc/reference/tags/index.html .. Change things from this point on ================================================== oslo.i18n -- Oslo Internationalization Utilities ================================================== .. image:: https://img.shields.io/pypi/v/oslo.i18n.svg :target: https://pypi.org/project/oslo.i18n/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/oslo.i18n.svg :target: https://pypi.org/project/oslo.i18n/ :alt: Downloads The oslo.i18n library contain utilities for working with internationalization (i18n) features, especially translation for text strings in an application or library. * Free software: Apache license * Documentation: https://docs.openstack.org/oslo.i18n/latest * Source: https://opendev.org/openstack/oslo.i18n * Bugs: https://bugs.launchpad.net/oslo.i18n * Release notes: https://docs.openstack.org/releasenotes/oslo.i18n/ ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01538 oslo.i18n-6.4.0/doc/0000775000175000017500000000000000000000000014043 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/requirements.txt0000664000175000017500000000016700000000000017333 0ustar00zuulzuul00000000000000sphinx>=2.0.0 # BSD openstackdocstheme>=2.2.1 # Apache-2.0 reno>=3.1.0 # Apache-2.0 sphinxcontrib-apidoc>=0.2.0 # BSD ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01538 oslo.i18n-6.4.0/doc/source/0000775000175000017500000000000000000000000015343 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/conf.py0000664000175000017500000000371700000000000016652 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # -- General configuration ---------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'sphinxcontrib.apidoc', 'openstackdocstheme' ] # openstackdocstheme options openstackdocs_repo_name = 'openstack/oslo.i18n' openstackdocs_bug_project = 'oslo.i18n' openstackdocs_bug_tag = '' # The master toctree document. master_doc = 'index' # General information about the project. project = 'oslo.i18n' copyright = '2014, OpenStack Foundation' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'openstackdocs' # -- sphinxcontrib.apidoc configuration -------------------------------------- apidoc_module_dir = '../../oslo_i18n' apidoc_output_dir = 'reference/api' apidoc_excluded_paths = [ 'tests', ] ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01538 oslo.i18n-6.4.0/doc/source/contributor/0000775000175000017500000000000000000000000017715 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/contributor/contributing.rst0000664000175000017500000000012400000000000023153 0ustar00zuulzuul00000000000000============== Contributing ============== .. include:: ../../../CONTRIBUTING.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/contributor/index.rst0000664000175000017500000000021400000000000021553 0ustar00zuulzuul00000000000000=========================== Contributing to oslo.i18n =========================== .. toctree:: :maxdepth: 2 contributing policy ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/contributor/policy.rst0000664000175000017500000000075300000000000021753 0ustar00zuulzuul00000000000000================ Policy History ================ * `Discussion from Havana Summit `__ * `Discussion from Icehouse Summit `__ * `Discussion from Juno Summit `__ * `I18n team wiki page `__ * `LoggingStandards wiki page `__ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/index.rst0000664000175000017500000000115600000000000017207 0ustar00zuulzuul00000000000000================================================== oslo.i18n -- Oslo Internationalization Utilities ================================================== The oslo.i18n library contain utilities for working with internationalization (i18n) features, especially translation for text strings in an application or library. Contents ======== .. toctree:: :maxdepth: 2 user/index reference/index contributor/index Release Notes ============= Read also the `oslo.i18n Release Notes `_. Indices and tables ================== * :ref:`modindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01538 oslo.i18n-6.4.0/doc/source/reference/0000775000175000017500000000000000000000000017301 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/reference/index.rst0000664000175000017500000000016500000000000021144 0ustar00zuulzuul00000000000000.. _api: ========================= oslo.i18n API Reference ========================= .. toctree:: api/modules ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01538 oslo.i18n-6.4.0/doc/source/user/0000775000175000017500000000000000000000000016321 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/user/guidelines.rst0000664000175000017500000001522500000000000021210 0ustar00zuulzuul00000000000000================================= Guidelines for Use in OpenStack ================================= The OpenStack I18N team has a limited capacity to translate messages, so we want to make their work as effective as possible by identifying the most useful text for them to translate. All text messages *the user sees* via exceptions or API calls should be marked for translation. However, some exceptions are used internally to signal error conditions between modules and are not intended to be presented to the user. Those do not need to be translated. Neither do log messages, as explained below. .. seealso:: * :ref:`usage` * :ref:`api` Gettext Contextual Form and Plural Form ======================================= Sometimes under different contexts, the same word should be translated into different phrases using :py:attr:`TranslatorFactory.contextual_form `. And recommend the following code to use contextual form:: # The contextual translation function using the name "_C" _C = _translators.contextual_form ... msg = _C('context', 'string') In some languages, sometimes the translated strings are different with different item counts using :py:attr:`TranslatorFactory.plural_form ` And recommend the following code to use plural form:: # The plural translation function using the name "_P" _P = _translators.plural_form ... msg = _P('single', 'plural', count) The contextual form and plural form are used only when needed. By default, the translation should use the ``_()``. .. note:: These two functions were only available in oslo.i18n >= 2.1.0. Log Translation =============== .. note:: Starting with the Pike series, OpenStack no longer supports log translation. It is not necessary to add translation instructions to new code, and the instructions can be removed from old code. The following documentation is retained to help developers understand existing usage and how to remove it. Support was `dropped `_ primarily based on `feedback from operators `_ that they were not only not needed but also undesirable, because they fragmented the set of web pages providing helpful information about any particular log message, thereby reducing the chances of finding those web pages by doing a web search for the message. Refer to the email thread `understanding log domain change `_ on the openstack-dev mailing list for more details. OpenStack previously supported translating some log levels using separate message catalogs, and so has separate marker functions. These well-known names were used by the build system jobs that extracted the messages from the source code and passed them to the translation tool. ========== ========== Level Function ========== ========== INFO ``_LI()`` WARNING ``_LW()`` ERROR ``_LE()`` CRITICAL ``_LC()`` ========== ========== .. note:: Debug level log messages were never translated. Using a Marker Function ======================= The marker functions are used to mark the translatable strings in the code. The strings are extracted into catalogs using a tool that performs source inspection to look for these specific markers, so the function argument must just be a string. For example: **do not do this**:: # WRONG msg = _(variable_containing_msg) Instead, use this style:: # RIGHT msg = _('My message.') Choosing a Marker Function ========================== The purpose of the different marker functions is to separate the translatable messages into different catalogs, which the translation teams can prioritize translating. It is important to choose the right marker function, to ensure that strings the user sees will be translated and to help the translation team manage their work load. Everything marked with ``_()`` will be translated. Prioritizing the catalogs created from strings marked with the log marker functions is up to the individual translation teams and their users, but it is expected that they will work on critical and error messages before warning or info. ``_()`` is preferred for any user facing message, even if it is also going to a log file. This ensures that the translated version of the message will be available to the user. The log marker functions (``_LI()``, ``_LW()``, ``_LE()``, and ``_LC()``) should no longer be used, and existing usages should be removed. Anytime that the message is passed outside of the current context (for example as part of an exception) the ``_()`` marker function must be used instead. A common pattern used to be to define a single message object and use it more than once, for the log call and the exception. In that case, ``_()`` had to be used because the message was going to appear in an exception that may be presented to the user. However, now that log messages are no longer translated, it is unfortunately necessary to use two separate strings: a plain one for the log message, and a translatable one for the exception. For example, **do not do this**:: # WRONG msg = _('There was an error.') LOG.error(msg) raise LocalExceptionClass(msg) or this:: # EVEN MORE WRONG msg = _LE('There was an error.') LOG.error(msg) raise LocalExceptionClass(msg) Instead, use this style:: # RIGHT LOG.error('There was an error.') raise LocalExceptionClass(_('An error occurred.')) Adding Variables to Translated Messages ======================================= Translated messages should not be combined with other literal strings to create partially translated messages. For example, **do not do this**:: # WRONG raise ValueError(_('some message') + ': variable=%s' % variable) Instead, use this style:: # RIGHT raise ValueError(_('some message: variable=%s') % variable) Including the variable reference inside the translated message allows the translator to take into account grammar rules, differences in left-right vs. right-left rendering, and other factors to make the translated message more useful to the end user. Any message with more than one variable should use named interpolation instead of positional, to allow translators to move the variables around in the string to account for differences in grammar and writing direction. For example, **do not do this**:: # WRONG raise ValueError(_('some message: v1=%s v2=%s') % (v1, v2)) Instead, use this style:: # RIGHT raise ValueError(_('some message: v1=%(v1)s v2=%(v2)s') % {'v1': v1, 'v2': v2}) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/user/history.rst0000664000175000017500000000004000000000000020546 0ustar00zuulzuul00000000000000.. include:: ../../../ChangeLog ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/user/index.rst0000664000175000017500000000016700000000000020166 0ustar00zuulzuul00000000000000================= Using oslo.i18n ================= .. toctree:: :maxdepth: 2 usage guidelines history ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/doc/source/user/usage.rst0000664000175000017500000001734700000000000020173 0ustar00zuulzuul00000000000000.. _usage: ===================================================== How to Use oslo.i18n in Your Application or Library ===================================================== Installing ========== At the command line:: $ pip install oslo.i18n .. _integration-module: Creating an Integration Module ============================== To use oslo.i18n in a project (e.g. myapp), you will need to create a small integration module to hold an instance of :class:`~oslo_i18n.TranslatorFactory` and references to the marker functions the factory creates. .. note:: Libraries probably do not want to expose the new integration module as part of their public API, so rather than naming it ``myapp.i18n`` it should be called ``myapp._i18n`` to indicate that it is a private implementation detail, and not meant to be used outside of the library's own code. .. note:: Starting with the Pike series, OpenStack no longer supports log translation. It is not necessary to add translation instructions to new code, and the instructions can be removed from old code. Refer to the email thread `understanding log domain change `_ on the openstack-dev mailing list for more details. .. code-block:: python # myapp/_i18n.py import oslo_i18n DOMAIN = "myapp" _translators = oslo_i18n.TranslatorFactory(domain=DOMAIN) # The primary translation function using the well-known name "_" _ = _translators.primary # The contextual translation function using the name "_C" # requires oslo.i18n >=2.1.0 _C = _translators.contextual_form # The plural translation function using the name "_P" # requires oslo.i18n >=2.1.0 _P = _translators.plural_form def get_available_languages(): return oslo_i18n.get_available_languages(DOMAIN) .. TODO: Provide examples for _C and _P Then, in the rest of your code, use the appropriate marker function for each message: .. code-block:: python from myapp._i18n import _ # ... variable = "openstack" some_object.name_msg = _('my name is: %s') % variable # ... try: # ... except AnException1: # Log only, log messages are no longer translated LOG.exception('exception message') except AnException2: # Raise only raise RuntimeError(_('exception message')) else: # Log and Raise msg = _('Unexpected error message') LOG.exception(msg) raise RuntimeError(msg) .. note:: The import of multiple modules from _i18n on a single line is a valid exception to `OpenStack Style Guidelines `_ for import statements. It is important to use the marker functions (e.g. _), rather than the longer form of the name, because the tool that scans the source code for translatable strings looks for the marker function names. .. warning:: The old method of installing a version of ``_()`` in the builtins namespace is deprecated. Modifying the global namespace affects libraries as well as the application, so it may interfere with proper message catalog lookups. Calls to :func:`gettextutils.install` should be replaced with the application or library integration module described here. Handling hacking Objections to Imports ====================================== The `OpenStack Style Guidelines `_ prefer importing modules and accessing names from those modules after import, rather than importing the names directly. For example: :: # WRONG from foo import bar bar() # RIGHT import foo foo.bar() The linting tool hacking_ will typically complain about importing names from within modules. It is acceptable to bypass this for the translation marker functions, because they must have specific names and their use pattern is dictated by the message catalog extraction tools rather than our style guidelines. To bypass the hacking check for imports from this integration module, add an import exception to ``tox.ini``. For example:: # tox.ini [hacking] import_exceptions = myapp._i18n .. _hacking: https://pypi.org/project/hacking .. _lazy-translation: Lazy Translation ================ Lazy translation delays converting a message string to the translated form as long as possible, including possibly never if the message is not logged or delivered to the user in some other way. It also supports logging translated messages in multiple languages, by configuring separate log handlers. Lazy translation is implemented by returning a special object from the translation function, instead of a unicode string. That special message object supports some, but not all, string manipulation APIs. For example, concatenation with addition is not supported, but interpolation of variables is supported. Depending on how translated strings are used in an application, these restrictions may mean that lazy translation cannot be used, and so it is not enabled by default. To enable lazy translation, call :func:`enable_lazy`. :: import oslo_i18n oslo_i18n.enable_lazy() Translating Messages ==================== Use :func:`~oslo_i18n.translate` to translate strings to a specific locale. :func:`translate` handles delayed translation and strings that have already been translated immediately. It should be used at the point where the locale to be used is known, which is often just prior to the message being returned or a log message being emitted. :: import oslo_i18n trans_msg = oslo_i18n.translate(msg, my_locale) If a locale is not specified the default locale is used. Available Languages =================== Only the languages that have translations provided are available for translation. To determine which languages are available the :func:`~oslo_i18n.get_available_languages` is provided. The integration module provides a domain defined specific function. .. code-block:: python import myapp._i18n languages = myapp._i18n.get_available_languages() .. seealso:: * :doc:`guidelines` Displaying translated messages ============================== Several preparations are required to display translated messages in your running application. Preferred language You need to specify your preferred language through an environment variable. The preferred language can be specified by ``LANGUAGE``, ``LC_ALL``, ``LC_MESSAGES``, or ``LANGUAGE`` (A former one has a priority). ``oslo_i18n.translate()`` can be used to translate a string to override the preferred language. .. note:: You need to use ``enable_lazy()`` to override the preferred language by using ``oslo_i18n.translate()``. Locale directory Python ``gettext`` looks for binary ``mo`` files for the given domain using the path ``//LC_MESSAGES/.mo``. The default locale directory varies on distributions, and it is ``/usr/share/locale`` in most cases. If you store message catalogs in a different location, you need to specify the location via an environment variable named ``_LOCALEDIR`` where ```` is an upper-case domain name with replacing ``_`` and ``.`` with ``-``. For example, ``NEUTRON_LOCALEDIR`` for a domain ``neutron`` and ``OSLO_I18N_LOCALEDIR`` for a domain ``oslo_i18n``. .. note:: When you specify locale directories via ``_LOCALEDIR`` environment variables, you need to specify an environment variable per domain. More concretely, if your application using a domain ``myapp` uses oslo.policy, you need to specify both ``MYAPP_LOCALEDIR`` and ``OSLO_POLICY_LOCALEDIR`` to ensure that translation messages from both your application and oslo.policy are displayed. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0193799 oslo.i18n-6.4.0/oslo.i18n.egg-info/0000775000175000017500000000000000000000000016522 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/PKG-INFO0000664000175000017500000000436600000000000017630 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: oslo.i18n Version: 6.4.0 Summary: Oslo i18n library Home-page: https://docs.openstack.org/oslo.i18n/latest Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: ======================== Team and repository tags ======================== .. image:: https://governance.openstack.org/tc/badges/oslo.i18n.svg :target: https://governance.openstack.org/tc/reference/tags/index.html .. Change things from this point on ================================================== oslo.i18n -- Oslo Internationalization Utilities ================================================== .. image:: https://img.shields.io/pypi/v/oslo.i18n.svg :target: https://pypi.org/project/oslo.i18n/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/oslo.i18n.svg :target: https://pypi.org/project/oslo.i18n/ :alt: Downloads The oslo.i18n library contain utilities for working with internationalization (i18n) features, especially translation for text strings in an application or library. * Free software: Apache license * Documentation: https://docs.openstack.org/oslo.i18n/latest * Source: https://opendev.org/openstack/oslo.i18n * Bugs: https://bugs.launchpad.net/oslo.i18n * Release notes: https://docs.openstack.org/releasenotes/oslo.i18n/ Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: Implementation :: CPython Requires-Python: >=3.8 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253426.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/SOURCES.txt0000664000175000017500000000510100000000000020403 0ustar00zuulzuul00000000000000.coveragerc .mailmap .pre-commit-config.yaml .stestr.conf .zuul.yaml AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE README.rst requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/requirements.txt doc/source/conf.py doc/source/index.rst doc/source/contributor/contributing.rst doc/source/contributor/index.rst doc/source/contributor/policy.rst doc/source/reference/index.rst doc/source/user/guidelines.rst doc/source/user/history.rst doc/source/user/index.rst doc/source/user/usage.rst oslo.i18n.egg-info/PKG-INFO oslo.i18n.egg-info/SOURCES.txt oslo.i18n.egg-info/dependency_links.txt oslo.i18n.egg-info/not-zip-safe oslo.i18n.egg-info/pbr.json oslo.i18n.egg-info/requires.txt oslo.i18n.egg-info/top_level.txt oslo_i18n/__init__.py oslo_i18n/_factory.py oslo_i18n/_gettextutils.py oslo_i18n/_i18n.py oslo_i18n/_lazy.py oslo_i18n/_locale.py oslo_i18n/_message.py oslo_i18n/_translate.py oslo_i18n/fixture.py oslo_i18n/log.py oslo_i18n/locale/de/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/en_GB/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/es/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/fr/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/it/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/ja/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/ka_GE/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/ko_KR/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/pl_PL/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/pt/LC_MESSAGES/oslo_i18n.po oslo_i18n/locale/zh_CN/LC_MESSAGES/oslo_i18n.po oslo_i18n/tests/__init__.py oslo_i18n/tests/fakes.py oslo_i18n/tests/test_factory.py oslo_i18n/tests/test_fixture.py oslo_i18n/tests/test_gettextutils.py oslo_i18n/tests/test_handler.py oslo_i18n/tests/test_lazy.py oslo_i18n/tests/test_locale_dir_variable.py oslo_i18n/tests/test_logging.py oslo_i18n/tests/test_message.py oslo_i18n/tests/test_public_api.py oslo_i18n/tests/test_translate.py oslo_i18n/tests/utils.py releasenotes/notes/add-reno-996dd44974d53238.yaml releasenotes/notes/drop-python27-support-eb9c2ad3268f0c1f.yaml releasenotes/source/2023.1.rst releasenotes/source/2023.2.rst releasenotes/source/2024.1.rst releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/ocata.rst releasenotes/source/pike.rst releasenotes/source/queens.rst releasenotes/source/rocky.rst releasenotes/source/stein.rst releasenotes/source/train.rst releasenotes/source/unreleased.rst releasenotes/source/ussuri.rst releasenotes/source/victoria.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/dependency_links.txt0000664000175000017500000000000100000000000022570 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/not-zip-safe0000664000175000017500000000000100000000000020750 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/pbr.json0000664000175000017500000000005600000000000020201 0ustar00zuulzuul00000000000000{"git_version": "efaff62", "is_release": true}././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/requires.txt0000664000175000017500000000001300000000000021114 0ustar00zuulzuul00000000000000pbr>=2.0.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253425.0 oslo.i18n-6.4.0/oslo.i18n.egg-info/top_level.txt0000664000175000017500000000001200000000000021245 0ustar00zuulzuul00000000000000oslo_i18n ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0193799 oslo.i18n-6.4.0/oslo_i18n/0000775000175000017500000000000000000000000015111 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/__init__.py0000664000175000017500000000124100000000000017220 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from ._factory import * from ._gettextutils import * from ._lazy import * from ._translate import * ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_factory.py0000664000175000017500000001555200000000000017301 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Translation function factory """ import gettext import os from oslo_i18n import _lazy from oslo_i18n import _locale from oslo_i18n import _message __all__ = [ 'TranslatorFactory', ] # magic gettext number to separate context from message CONTEXT_SEPARATOR = _message.CONTEXT_SEPARATOR class TranslatorFactory(object): "Create translator functions" def __init__(self, domain, localedir=None): """Establish a set of translation functions for the domain. :param domain: Name of translation domain, specifying a message catalog. :type domain: str :param localedir: Directory with translation catalogs. :type localedir: str """ self.domain = domain if localedir is None: variable_name = _locale.get_locale_dir_variable_name(domain) localedir = os.environ.get(variable_name) self.localedir = localedir def _make_translation_func(self, domain=None): """Return a translation function ready for use with messages. The returned function takes a single value, the unicode string to be translated. The return type varies depending on whether lazy translation is being done. When lazy translation is enabled, :class:`Message` objects are returned instead of regular :class:`unicode` strings. The domain argument can be specified to override the default from the factory, but the localedir from the factory is always used because we assume the log-level translation catalogs are installed in the same directory as the main application catalog. """ if domain is None: domain = self.domain t = gettext.translation(domain, localedir=self.localedir, fallback=True) # Use the appropriate method of the translation object based # on the python version. m = t.gettext def f(msg): """oslo_i18n.gettextutils translation function.""" if _lazy.USE_LAZY: return _message.Message(msg, domain=domain) return m(msg) return f def _make_contextual_translation_func(self, domain=None): """Return a translation function ready for use with context messages. The returned function takes two values, the context of the unicode string, the unicode string to be translated. The returned type is the same as :method:`TranslatorFactory._make_translation_func`. The domain argument is the same as :method:`TranslatorFactory._make_translation_func`. """ if domain is None: domain = self.domain t = gettext.translation(domain, localedir=self.localedir, fallback=True) # Use the appropriate method of the translation object based # on the python version. m = t.gettext def f(ctx, msg): """oslo.i18n.gettextutils translation with context function.""" if _lazy.USE_LAZY: msgid = (ctx, msg) return _message.Message(msgid, domain=domain, has_contextual_form=True) msgctx = "%s%s%s" % (ctx, CONTEXT_SEPARATOR, msg) s = m(msgctx) if CONTEXT_SEPARATOR in s: # Translation not found return msg return s return f def _make_plural_translation_func(self, domain=None): """Return a plural translation function ready for use with messages. The returned function takes three values, the single form of the unicode string, the plural form of the unicode string, the count of items to be translated. The returned type is the same as :method:`TranslatorFactory._make_translation_func`. The domain argument is the same as :method:`TranslatorFactory._make_translation_func`. """ if domain is None: domain = self.domain t = gettext.translation(domain, localedir=self.localedir, fallback=True) # Use the appropriate method of the translation object based # on the python version. m = t.ngettext def f(msgsingle, msgplural, msgcount): """oslo.i18n.gettextutils plural translation function.""" if _lazy.USE_LAZY: msgid = (msgsingle, msgplural, msgcount) return _message.Message(msgid, domain=domain, has_plural_form=True) return m(msgsingle, msgplural, msgcount) return f @property def primary(self): "The default translation function." return self._make_translation_func() @property def contextual_form(self): """The contextual translation function. The returned function takes two values, the context of the unicode string, the unicode string to be translated. .. versionadded:: 2.1.0 """ return self._make_contextual_translation_func() @property def plural_form(self): """The plural translation function. The returned function takes three values, the single form of the unicode string, the plural form of the unicode string, the count of items to be translated. .. versionadded:: 2.1.0 """ return self._make_plural_translation_func() def _make_log_translation_func(self, level): return self._make_translation_func(self.domain + '-log-' + level) @property def log_info(self): "Translate info-level log messages." return self._make_log_translation_func('info') @property def log_warning(self): "Translate warning-level log messages." return self._make_log_translation_func('warning') @property def log_error(self): "Translate error-level log messages." return self._make_log_translation_func('error') @property def log_critical(self): "Translate critical-level log messages." return self._make_log_translation_func('critical') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_gettextutils.py0000664000175000017500000000771300000000000020377 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """gettextutils provides a wrapper around gettext for OpenStack projects """ import copy import gettext import locale import os from oslo_i18n import _factory from oslo_i18n import _locale __all__ = [ 'install', 'get_available_languages', ] def install(domain): """Install a _() function using the given translation domain. Given a translation domain, install a _() function using gettext's install() function. The main difference from gettext.install() is that we allow overriding the default localedir (e.g. /usr/share/locale) using a translation-domain-specific environment variable (e.g. NOVA_LOCALEDIR). :param domain: the translation domain """ import builtins tf = _factory.TranslatorFactory(domain) builtins.__dict__['_'] = tf.primary _AVAILABLE_LANGUAGES = {} # Copied from Babel so anyone using aliases that were previously provided by # the Babel implementation of get_available_languages continues to work. These # are not recommended for use in new code. _BABEL_ALIASES = { 'ar': 'ar_SY', 'bg': 'bg_BG', 'bs': 'bs_BA', 'ca': 'ca_ES', 'cs': 'cs_CZ', 'da': 'da_DK', 'de': 'de_DE', 'el': 'el_GR', 'en': 'en_US', 'es': 'es_ES', 'et': 'et_EE', 'fa': 'fa_IR', 'fi': 'fi_FI', 'fr': 'fr_FR', 'gl': 'gl_ES', 'he': 'he_IL', 'hu': 'hu_HU', 'id': 'id_ID', 'is': 'is_IS', 'it': 'it_IT', 'ja': 'ja_JP', 'km': 'km_KH', 'ko': 'ko_KR', 'lt': 'lt_LT', 'lv': 'lv_LV', 'mk': 'mk_MK', 'nl': 'nl_NL', 'nn': 'nn_NO', 'no': 'nb_NO', 'pl': 'pl_PL', 'pt': 'pt_PT', 'ro': 'ro_RO', 'ru': 'ru_RU', 'sk': 'sk_SK', 'sl': 'sl_SI', 'sv': 'sv_SE', 'th': 'th_TH', 'tr': 'tr_TR', 'uk': 'uk_UA' } def get_available_languages(domain): """Lists the available languages for the given translation domain. :param domain: the domain to get languages for """ if domain in _AVAILABLE_LANGUAGES: return copy.copy(_AVAILABLE_LANGUAGES[domain]) localedir = os.environ.get(_locale.get_locale_dir_variable_name(domain)) def find(x): return gettext.find(domain, localedir=localedir, languages=[x]) # NOTE(mrodden): en_US should always be available (and first in case # order matters) since our in-line message strings are en_US language_list = ['en_US'] locale_identifiers = set(locale.windows_locale.values()) language_list.extend( language for language in locale_identifiers if find(language) ) language_list.extend( alias for alias, _ in _BABEL_ALIASES.items() if find(alias) ) _AVAILABLE_LANGUAGES[domain] = language_list return copy.copy(language_list) _original_find = gettext.find _FIND_CACHE = {} def cached_find(domain, localedir=None, languages=None, all=0): """A version of gettext.find using a cache. gettext.find looks for mo files on the disk using os.path.exists. Those don't tend to change over time, but the system calls pile up with a long-running service. This caches the result so that we return the same mo files, and only call find once per domain. """ key = (domain, localedir, tuple(languages) if languages is not None else None, all) if key in _FIND_CACHE: return _FIND_CACHE[key] result = _original_find(domain, localedir, languages, all) _FIND_CACHE[key] = result return result gettext.find = cached_find ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_i18n.py0000664000175000017500000000164600000000000016410 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Translation support for messages in this library. """ from oslo_i18n import _factory # Create the global translation functions. _translators = _factory.TranslatorFactory('oslo_i18n') # The primary translation function using the well-known name "_" _ = _translators.primary ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_lazy.py0000664000175000017500000000236200000000000016604 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. __all__ = [ 'enable_lazy', ] USE_LAZY = False def enable_lazy(enable=True): """Convenience function for configuring _() to use lazy gettext Call this at the start of execution to enable the gettextutils._ function to use lazy gettext functionality. This is useful if your project is importing _ directly instead of using the gettextutils.install() way of importing the _ function. :param enable: Flag indicating whether lazy translation should be turned on or off. Defaults to True. :type enable: bool """ global USE_LAZY USE_LAZY = enable ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_locale.py0000664000175000017500000000164700000000000017071 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. def get_locale_dir_variable_name(domain): """Build environment variable name for local dir. Convert a translation domain name to a variable for specifying a separate locale dir. """ return domain.upper().replace('.', '_').replace('-', '_') + '_LOCALEDIR' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_message.py0000664000175000017500000002244000000000000017250 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Private Message class for lazy translation support. """ import copy import gettext import locale import logging import os import warnings from oslo_i18n import _locale from oslo_i18n import _translate # magic gettext number to separate context from message CONTEXT_SEPARATOR = "\x04" LOG = logging.getLogger(__name__) class Message(str): """A Message object is a unicode object that can be translated. Translation of Message is done explicitly using the translate() method. For all non-translation intents and purposes, a Message is simply unicode, and can be treated as such. """ def __new__(cls, msgid, msgtext=None, params=None, domain='oslo', has_contextual_form=False, has_plural_form=False, *args): """Create a new Message object. In order for translation to work gettext requires a message ID, this msgid will be used as the base unicode text. It is also possible for the msgid and the base unicode text to be different by passing the msgtext parameter. """ # If the base msgtext is not given, we use the default translation # of the msgid (which is in English) just in case the system locale is # not English, so that the base text will be in that locale by default. if not msgtext: msgtext = Message._translate_msgid(msgid, domain) # We want to initialize the parent unicode with the actual object that # would have been plain unicode if 'Message' was not enabled. msg = super(Message, cls).__new__(cls, msgtext) msg.msgid = msgid msg.domain = domain msg.params = params msg.has_contextual_form = has_contextual_form msg.has_plural_form = has_plural_form return msg def translation(self, desired_locale=None): """Translate this message to the desired locale. :param desired_locale: The desired locale to translate the message to, if no locale is provided the message will be translated to the system's default locale. :returns: the translated message in unicode """ translated_message = Message._translate_msgid(self.msgid, self.domain, desired_locale, self.has_contextual_form, self.has_plural_form) if self.params is None: # No need for more translation return translated_message # This Message object may have been formatted with one or more # Message objects as substitution arguments, given either as a single # argument, part of a tuple, or as one or more values in a dictionary. # When translating this Message we need to translate those Messages too translated_params = _translate.translate_args(self.params, desired_locale) return self._safe_translate(translated_message, translated_params) @staticmethod def _translate_msgid(msgid, domain, desired_locale=None, has_contextual_form=False, has_plural_form=False): if not desired_locale: system_locale = locale.getlocale(locale.LC_CTYPE) # If the system locale is not available to the runtime use English if not system_locale or not system_locale[0]: desired_locale = 'en_US' else: desired_locale = system_locale[0] locale_dir = os.environ.get( _locale.get_locale_dir_variable_name(domain) ) lang = gettext.translation(domain, localedir=locale_dir, languages=[desired_locale], fallback=True) if not has_contextual_form and not has_plural_form: # This is the most common case, so check it first. translator = lang.gettext translated_message = translator(msgid) elif has_contextual_form and has_plural_form: # Reserved for contextual and plural translation function, # which is not yet implemented. raise ValueError("Unimplemented.") elif has_contextual_form: (msgctx, msgtxt) = msgid translator = lang.gettext msg_with_ctx = "%s%s%s" % (msgctx, CONTEXT_SEPARATOR, msgtxt) translated_message = translator(msg_with_ctx) if CONTEXT_SEPARATOR in translated_message: # Translation not found, use the original text translated_message = msgtxt elif has_plural_form: (msgsingle, msgplural, msgcount) = msgid translator = lang.ngettext translated_message = translator(msgsingle, msgplural, msgcount) return translated_message def _safe_translate(self, translated_message, translated_params): """Trap translation errors and fall back to default translation. :param translated_message: the requested translation :param translated_params: the params to be inserted :return: if parameter insertion is successful then it is the translated_message with the translated_params inserted, if the requested translation fails then it is the default translation with the params """ try: translated_message = translated_message % translated_params except (KeyError, TypeError) as err: # KeyError for parameters named in the translated_message # but not found in translated_params and TypeError for # type strings that do not match the type of the # parameter. # # Log the error translating the message and use the # original message string so the translator's bad message # catalog doesn't break the caller. # Do not translate this log message even if it is used as a # warning message as a wrong translation of this message could # cause infinite recursion msg = ('Failed to insert replacement values into translated ' 'message %s (Original: %r): %s') warnings.warn(msg % (translated_message, self.msgid, err)) LOG.debug(msg, translated_message, self.msgid, err) translated_message = self.msgid % translated_params return translated_message def __mod__(self, other): # When we mod a Message we want the actual operation to be performed # by the base class (i.e. unicode()), the only thing we do here is # save the original msgid and the parameters in case of a translation params = self._sanitize_mod_params(other) unicode_mod = self._safe_translate(str(self), params) modded = Message(self.msgid, msgtext=unicode_mod, params=params, domain=self.domain) return modded def _sanitize_mod_params(self, other): """Sanitize the object being modded with this Message. - Add support for modding 'None' so translation supports it - Trim the modded object, which can be a large dictionary, to only those keys that would actually be used in a translation - Snapshot the object being modded, in case the message is translated, it will be used as it was when the Message was created """ if other is None: params = (other,) elif isinstance(other, dict): # Merge the dictionaries # Copy each item in case one does not support deep copy. params = {} if isinstance(self.params, dict): params.update((key, self._copy_param(val)) for key, val in self.params.items()) params.update((key, self._copy_param(val)) for key, val in other.items()) else: params = self._copy_param(other) return params def _copy_param(self, param): try: return copy.deepcopy(param) except Exception: # Fallback to casting to unicode this will handle the # python code-like objects that can't be deep-copied return str(param) def __add__(self, other): from oslo_i18n._i18n import _ msg = _('Message objects do not support addition.') raise TypeError(msg) def __radd__(self, other): return self.__add__(other) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/_translate.py0000664000175000017500000000543400000000000017625 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. __all__ = [ 'translate', ] def translate(obj, desired_locale=None): """Gets the translated unicode representation of the given object. If the object is not translatable it is returned as-is. If the desired_locale argument is None the object is translated to the system locale. :param obj: the object to translate :param desired_locale: the locale to translate the message to, if None the default system locale will be used :returns: the translated object in unicode, or the original object if it could not be translated """ from oslo_i18n import _message # avoid circular dependency at module level message = obj if not isinstance(message, _message.Message): # If the object to translate is not already translatable, # let's first get its unicode representation message = str(obj) if isinstance(message, _message.Message): # Even after unicoding() we still need to check if we are # running with translatable unicode before translating return message.translation(desired_locale) return obj def translate_args(args, desired_locale=None): """Translates all the translatable elements of the given arguments object. This method is used for translating the translatable values in method arguments which include values of tuples or dictionaries. If the object is not a tuple or a dictionary the object itself is translated if it is translatable. If the locale is None the object is translated to the system locale. :param args: the args to translate :param desired_locale: the locale to translate the args to, if None the default system locale will be used :returns: a new args object with the translated contents of the original """ if isinstance(args, tuple): return tuple(translate(v, desired_locale) for v in args) if isinstance(args, dict): translated_dict = dict((key, translate(value, desired_locale)) for key, value in args.items()) return translated_dict return translate(args, desired_locale) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/fixture.py0000664000175000017500000001307700000000000017161 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Test fixtures for working with oslo_i18n. """ import gettext import fixtures from oslo_i18n import _lazy from oslo_i18n import _message class Translation(fixtures.Fixture): """Fixture for managing translatable strings. This class provides methods for creating translatable strings using both lazy translation and immediate translation. It can be used to generate the different types of messages returned from oslo_i18n to test code that may need to know about the type to handle them differently (for example, error handling in WSGI apps, or logging). Use this class to generate messages instead of toggling the global lazy flag and using the regular translation factory. """ def __init__(self, domain='test-domain'): """Initialize the fixture. :param domain: The translation domain. This is not expected to coincide with an actual set of message catalogs, but it can. :type domain: str """ self.domain = domain def lazy(self, msg): """Return a lazily translated message. :param msg: Input message string. May optionally include positional or named string interpolation markers. :type msg: str or unicode """ return _message.Message(msg, domain=self.domain) def immediate(self, msg): """Return a string as though it had been translated immediately. :param msg: Input message string. May optionally include positional or named string interpolation markers. :type msg: str or unicode """ return str(msg) class ToggleLazy(fixtures.Fixture): """Fixture to toggle lazy translation on or off for a test.""" def __init__(self, enabled): """Force lazy translation on or off. :param enabled: Flag controlling whether to enable or disable lazy translation, passed to :func:`~oslo_i18n.enable_lazy`. :type enabled: bool """ super(ToggleLazy, self).__init__() self._enabled = enabled self._original_value = _lazy.USE_LAZY def setUp(self): super(ToggleLazy, self).setUp() self.addCleanup(self._restore_original) _lazy.enable_lazy(self._enabled) def _restore_original(self): _lazy.enable_lazy(self._original_value) class _PrefixTranslator(gettext.NullTranslations): """Translator that adds prefix to message ids NOTE: gettext.NullTranslations is an old style class :parm prefix: prefix to add to message id. If not specified (None) then 'noprefix' is used. :type prefix: string """ def __init__(self, fp=None, prefix='noprefix'): gettext.NullTranslations.__init__(self, fp) self.prefix = prefix def gettext(self, message): msg = gettext.NullTranslations.gettext(self, message) return self.prefix + msg def ugettext(self, message): msg = gettext.NullTranslations.ugettext(self, message) return self.prefix + msg def _prefix_translations(*x, **y): """Use message id prefixed with domain and language as translation """ return _PrefixTranslator(prefix=x[0] + '/' + y['languages'][0] + ': ') class PrefixLazyTranslation(fixtures.Fixture): """Fixture to prefix lazy translation enabled messages Use of this fixture will cause messages supporting lazy translation to be replaced with the message id prefixed with 'domain/language:'. For example, 'oslo/en_US: message about something'. It will also override the available languages returned from oslo_18n.get_available_languages to the specified languages. This will enable tests to ensure that messages were translated lazily with the specified language and not immediately with the default language. NOTE that this does not work unless lazy translation is enabled, so it uses the ToggleLazy fixture to enable lazy translation. :param languages: list of languages to support. If not specified (None) then ['en_US'] is used. :type languages: list of strings """ _DEFAULT_LANG = 'en_US' def __init__(self, languages=None, locale=None): super(PrefixLazyTranslation, self).__init__() self.languages = languages or [PrefixLazyTranslation._DEFAULT_LANG] self.locale = locale def setUp(self): super(PrefixLazyTranslation, self).setUp() self.useFixture(ToggleLazy(True)) self.useFixture(fixtures.MonkeyPatch( 'oslo_i18n._gettextutils.get_available_languages', lambda *x, **y: self.languages)) self.useFixture(fixtures.MonkeyPatch( 'oslo_i18n.get_available_languages', lambda *x, **y: self.languages)) self.useFixture(fixtures.MonkeyPatch('gettext.translation', _prefix_translations)) self.useFixture(fixtures.MonkeyPatch('locale.getlocale', lambda *x, **y: self.locale)) ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/oslo_i18n/locale/0000775000175000017500000000000000000000000016350 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.00738 oslo.i18n-6.4.0/oslo_i18n/locale/de/0000775000175000017500000000000000000000000016740 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0193799 oslo.i18n-6.4.0/oslo_i18n/locale/de/LC_MESSAGES/0000775000175000017500000000000000000000000020525 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/de/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000163400000000000022704 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Andreas Jaeger , 2014 # Robert Simai, 2015 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n 3.6.1.dev1\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-06-04 05:29+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-06-01 09:23+0000\n" "Last-Translator: Andreas Jaeger \n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 3.7.3\n" "Language-Team: German\n" msgid "Message objects do not support addition." msgstr "Message-Objekte unterstützen keine Addition." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.00738 oslo.i18n-6.4.0/oslo_i18n/locale/en_GB/0000775000175000017500000000000000000000000017322 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0193799 oslo.i18n-6.4.0/oslo_i18n/locale/en_GB/LC_MESSAGES/0000775000175000017500000000000000000000000021107 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/en_GB/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000163000000000000023262 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Andi Chandler , 2014 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2018-02-05 13:14+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-04-12 06:17+0000\n" "Last-Translator: Copied by Zanata \n" "Language: en_GB\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 4.3.3\n" "Language-Team: English (United Kingdom)\n" msgid "Message objects do not support addition." msgstr "Message objects do not support addition." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.00738 oslo.i18n-6.4.0/oslo_i18n/locale/es/0000775000175000017500000000000000000000000016757 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/es/LC_MESSAGES/0000775000175000017500000000000000000000000020544 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/es/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000163200000000000022721 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Adriana Chisco Landazábal , 2015 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n 3.6.1.dev1\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-06-04 05:29+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2015-06-22 09:03+0000\n" "Last-Translator: Adriana Chisco Landazábal \n" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 3.7.3\n" "Language-Team: Spanish\n" msgid "Message objects do not support addition." msgstr "Objectos de mensaje no soportan adición." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.00738 oslo.i18n-6.4.0/oslo_i18n/locale/fr/0000775000175000017500000000000000000000000016757 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/fr/LC_MESSAGES/0000775000175000017500000000000000000000000020544 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/fr/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000171400000000000022722 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Jonathan Dupart , 2014 # Maxime COQUEREL , 2014 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n 3.6.1.dev1\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-06-04 05:29+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2014-09-25 09:36+0000\n" "Last-Translator: Jonathan Dupart \n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 3.7.3\n" "Language-Team: French\n" msgid "Message objects do not support addition." msgstr "Les objects message ne supportent pas l'ajout." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.00738 oslo.i18n-6.4.0/oslo_i18n/locale/it/0000775000175000017500000000000000000000000016764 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/it/LC_MESSAGES/0000775000175000017500000000000000000000000020551 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/it/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000162000000000000022723 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # PierAlberto , 2014 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n 3.6.1.dev1\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-06-04 05:29+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2014-08-24 11:27+0000\n" "Last-Translator: PierAlberto \n" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 3.7.3\n" "Language-Team: Italian\n" msgid "Message objects do not support addition." msgstr "I messaggi oggetti non supportano aggiunte." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.00738 oslo.i18n-6.4.0/oslo_i18n/locale/ja/0000775000175000017500000000000000000000000016742 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/ja/LC_MESSAGES/0000775000175000017500000000000000000000000020527 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/ja/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000127700000000000022711 0ustar00zuulzuul00000000000000# Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n 3.6.1.dev1\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-06-04 05:29+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-02-20 06:44+0000\n" "Last-Translator: KATO Tomoyuki \n" "Language-Team: Japanese\n" "Language: ja\n" "X-Generator: Zanata 3.7.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "Message objects do not support addition." msgstr "メッセージオブジェクトは追加機能をサポートしていません。" ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/oslo_i18n/locale/ka_GE/0000775000175000017500000000000000000000000017316 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/ka_GE/LC_MESSAGES/0000775000175000017500000000000000000000000021103 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/ka_GE/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000143600000000000023262 0ustar00zuulzuul00000000000000# Temuri Doghonadze , 2023. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2023-05-05 13:54+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2023-04-14 09:09+0000\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian (Georgia)\n" "Language: ka_GE\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "Message objects do not support addition." msgstr "შეტყობინების ობიექტებს დამატების მხარდაჭერა არ გააჩნიათ." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/oslo_i18n/locale/ko_KR/0000775000175000017500000000000000000000000017355 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/ko_KR/LC_MESSAGES/0000775000175000017500000000000000000000000021142 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/ko_KR/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000163500000000000023322 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Sungjin Kang , 2014 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2018-02-05 13:14+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-04-12 06:17+0000\n" "Last-Translator: Copied by Zanata \n" "Language: ko_KR\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 4.3.3\n" "Language-Team: Korean (South Korea)\n" msgid "Message objects do not support addition." msgstr "메시지 객체는 추가 지원을하지 않습니다." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/oslo_i18n/locale/pl_PL/0000775000175000017500000000000000000000000017356 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/pl_PL/LC_MESSAGES/0000775000175000017500000000000000000000000021143 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/pl_PL/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000171700000000000023324 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Łukasz Jernaś , 2014 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2018-02-05 13:14+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-04-12 06:17+0000\n" "Last-Translator: Copied by Zanata \n" "Language: pl_PL\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 4.3.3\n" "Language-Team: Polish (Poland)\n" msgid "Message objects do not support addition." msgstr "Obiekty Message nie wspierają dodawania." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/oslo_i18n/locale/pt/0000775000175000017500000000000000000000000016773 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/pt/LC_MESSAGES/0000775000175000017500000000000000000000000020560 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/pt/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000161400000000000022735 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # MMSRS , 2015 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n 3.6.1.dev1\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2016-06-04 05:29+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2015-08-11 05:02+0000\n" "Last-Translator: MMSRS \n" "Language: pt\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 3.7.3\n" "Language-Team: Portuguese\n" msgid "Message objects do not support addition." msgstr "Os objetos de mensagem não suportam a adição." ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/oslo_i18n/locale/zh_CN/0000775000175000017500000000000000000000000017351 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0233798 oslo.i18n-6.4.0/oslo_i18n/locale/zh_CN/LC_MESSAGES/0000775000175000017500000000000000000000000021136 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/locale/zh_CN/LC_MESSAGES/oslo_i18n.po0000664000175000017500000000160200000000000023310 0ustar00zuulzuul00000000000000# Translations template for oslo.i18n. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the oslo.i18n project. # # Translators: # Xiao Xi LIU , 2014 # Andreas Jaeger , 2016. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n VERSION\n" "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" "POT-Creation-Date: 2018-02-05 13:14+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2016-04-12 06:17+0000\n" "Last-Translator: Copied by Zanata \n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" "Generated-By: Babel 2.0\n" "X-Generator: Zanata 4.3.3\n" "Language-Team: Chinese (China)\n" msgid "Message objects do not support addition." msgstr "消息对象不支持添加操作。" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/log.py0000664000175000017500000000672600000000000016257 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """logging utilities for translation """ from logging import handlers from oslo_i18n import _translate class TranslationHandler(handlers.MemoryHandler): """Handler that translates records before logging them. When lazy translation is enabled in the application (see :func:`~oslo_i18n.enable_lazy`), the :class:`TranslationHandler` uses its locale configuration setting to determine how to translate LogRecord objects before forwarding them to the logging.Handler. When lazy translation is disabled, the message in the LogRecord is converted to unicode without any changes and then forwarded to the logging.Handler. The handler can be configured declaratively in the ``logging.conf`` as follows:: [handlers] keys = translatedlog, translator [handler_translatedlog] class = handlers.WatchedFileHandler args = ('/var/log/api-localized.log',) formatter = context [handler_translator] class = oslo_i18n.log.TranslationHandler target = translatedlog args = ('zh_CN',) If the specified locale is not available in the system, the handler will log in the default locale. """ def __init__(self, locale=None, target=None): """Initialize a TranslationHandler :param locale: locale to use for translating messages :param target: logging.Handler object to forward LogRecord objects to after translation """ # NOTE(luisg): In order to allow this handler to be a wrapper for # other handlers, such as a FileHandler, and still be able to # configure it using logging.conf, this handler has to extend # MemoryHandler because only the MemoryHandlers' logging.conf # parsing is implemented such that it accepts a target handler. handlers.MemoryHandler.__init__(self, capacity=0, target=target) self.locale = locale def setFormatter(self, fmt): self.target.setFormatter(fmt) def emit(self, record): # We save the message from the original record to restore it # after translation, so other handlers are not affected by this original_msg = record.msg original_args = record.args try: self._translate_and_log_record(record) finally: record.msg = original_msg record.args = original_args def _translate_and_log_record(self, record): record.msg = _translate.translate(record.msg, self.locale) # In addition to translating the message, we also need to translate # arguments that were passed to the log method that were not part # of the main message e.g., log.info(_('Some message %s'), this_one)) record.args = _translate.translate_args(record.args, self.locale) self.target.emit(record) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0273798 oslo.i18n-6.4.0/oslo_i18n/tests/0000775000175000017500000000000000000000000016253 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/__init__.py0000664000175000017500000000000000000000000020352 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/fakes.py0000664000175000017500000000373000000000000017721 0ustar00zuulzuul00000000000000# Copyright 2012 Intel Inc, OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Fakes For translation tests. """ import gettext class FakeTranslations(gettext.GNUTranslations): """A test GNUTranslations class that takes a map of msg -> translations.""" def __init__(self, translations): self.translations = translations # used by Python 3 def gettext(self, msgid): return self.translations.get(msgid, msgid) # used by Python 2 def ugettext(self, msgid): return self.translations.get(msgid, msgid) @staticmethod def translator(locales_map): """Build mock translator for the given locales. Returns a mock gettext.translation function that uses individual TestTranslations to translate in the given locales. :param locales_map: A map from locale name to a translations map. { 'es': {'Hi': 'Hola', 'Bye': 'Adios'}, 'zh': {'Hi': 'Ni Hao', 'Bye': 'Zaijian'} } """ def _translation(domain, localedir=None, languages=None, fallback=None): if languages: language = languages[0] if language in locales_map: return FakeTranslations(locales_map[language]) return gettext.NullTranslations() return _translation ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_factory.py0000664000175000017500000000473000000000000021337 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from unittest import mock from oslotest import base as test_base from oslo_i18n import _factory from oslo_i18n import _lazy from oslo_i18n import _message # magic gettext number to separate context from message CONTEXT_SEPARATOR = _message.CONTEXT_SEPARATOR class TranslatorFactoryTest(test_base.BaseTestCase): def setUp(self): super(TranslatorFactoryTest, self).setUp() # remember so we can reset to it later in case it changes self._USE_LAZY = _lazy.USE_LAZY def tearDown(self): # reset to value before test _lazy.USE_LAZY = self._USE_LAZY super(TranslatorFactoryTest, self).tearDown() def test_lazy(self): _lazy.enable_lazy(True) with mock.patch.object(_message, 'Message') as msg: tf = _factory.TranslatorFactory('domain') tf.primary('some text') msg.assert_called_with('some text', domain='domain') def test_not_lazy(self): _lazy.enable_lazy(False) with mock.patch.object(_message, 'Message') as msg: msg.side_effect = AssertionError('should not use Message') tf = _factory.TranslatorFactory('domain') tf.primary('some text') def test_change_lazy(self): _lazy.enable_lazy(True) tf = _factory.TranslatorFactory('domain') r = tf.primary('some text') self.assertIsInstance(r, _message.Message) _lazy.enable_lazy(False) r = tf.primary('some text') self.assertNotIsInstance(r, _message.Message) def test_log_level_domain_name(self): with mock.patch.object(_factory.TranslatorFactory, '_make_translation_func') as mtf: tf = _factory.TranslatorFactory('domain') tf._make_log_translation_func('mylevel') mtf.assert_called_with('domain-log-mylevel') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_fixture.py0000664000175000017500000001023600000000000021354 0ustar00zuulzuul00000000000000# All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslotest import base as test_base import oslo_i18n from oslo_i18n import _gettextutils from oslo_i18n._i18n import _ from oslo_i18n import _lazy from oslo_i18n import _message from oslo_i18n import _translate from oslo_i18n import fixture class TranslationFixtureTest(test_base.BaseTestCase): def setUp(self): super(TranslationFixtureTest, self).setUp() self.trans_fixture = self.useFixture(fixture.Translation()) def test_lazy(self): msg = self.trans_fixture.lazy('this is a lazy message') self.assertIsInstance(msg, _message.Message) self.assertEqual('this is a lazy message', msg.msgid) def test_immediate(self): msg = self.trans_fixture.immediate('this is a lazy message') self.assertNotIsInstance(msg, _message.Message) self.assertIsInstance(msg, str) self.assertEqual('this is a lazy message', msg) class ToggleLazyFixtureText(test_base.BaseTestCase): def test_on_on(self): _lazy.USE_LAZY = True f = fixture.ToggleLazy(True) f.setUp() self.assertTrue(_lazy.USE_LAZY) f._restore_original() self.assertTrue(_lazy.USE_LAZY) def test_on_off(self): _lazy.USE_LAZY = True f = fixture.ToggleLazy(False) f.setUp() self.assertFalse(_lazy.USE_LAZY) f._restore_original() self.assertTrue(_lazy.USE_LAZY) def test_off_on(self): _lazy.USE_LAZY = False f = fixture.ToggleLazy(True) f.setUp() self.assertTrue(_lazy.USE_LAZY) f._restore_original() self.assertFalse(_lazy.USE_LAZY) def test_off_off(self): _lazy.USE_LAZY = False f = fixture.ToggleLazy(False) f.setUp() self.assertFalse(_lazy.USE_LAZY) f._restore_original() self.assertFalse(_lazy.USE_LAZY) _FAKE_LANG = 'en_ZZ' class PrefixLazyTranslationTest(test_base.BaseTestCase): def test_default(self): # Turn lazy off to check that fixture turns it on self.useFixture(fixture.ToggleLazy(False)) self.useFixture(fixture.PrefixLazyTranslation()) self.assertTrue(_lazy.USE_LAZY) default_lang = fixture.PrefixLazyTranslation._DEFAULT_LANG raw_id1 = 'fake msg1' expected_msg = 'oslo_i18n/' + default_lang + ': ' + raw_id1 msg1 = _(raw_id1) # noqa self.assertEqual([default_lang], _gettextutils.get_available_languages('oslo_i18n')) self.assertEqual([default_lang], oslo_i18n.get_available_languages('oslo_i18n')) self.assertEqual(expected_msg, _translate.translate(msg1)) def test_extra_lang(self): languages = _gettextutils.get_available_languages('oslo') languages.append(_FAKE_LANG) self.useFixture(fixture.PrefixLazyTranslation(languages=languages)) raw_id1 = 'fake msg1' expected_msg_en_US = ('oslo_i18n/' + fixture.PrefixLazyTranslation._DEFAULT_LANG + ': ' + raw_id1) expected_msg_en_ZZ = 'oslo_i18n/' + _FAKE_LANG + ': ' + raw_id1 msg1 = _(raw_id1) # noqa self.assertEqual(languages, _gettextutils.get_available_languages('oslo_i18n')) self.assertEqual(languages, oslo_i18n.get_available_languages('oslo_i18n')) self.assertEqual(expected_msg_en_US, _translate.translate(msg1)) self.assertEqual(expected_msg_en_ZZ, _translate.translate(msg1, desired_locale=_FAKE_LANG)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_gettextutils.py0000664000175000017500000001171100000000000022432 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import builtins import gettext import logging from unittest import mock from oslotest import base as test_base from oslo_i18n import _factory from oslo_i18n import _gettextutils from oslo_i18n import _lazy from oslo_i18n import _message LOG = logging.getLogger(__name__) class GettextTest(test_base.BaseTestCase): def setUp(self): super(GettextTest, self).setUp() # remember so we can reset to it later in case it changes self._USE_LAZY = _lazy.USE_LAZY self.t = _factory.TranslatorFactory('oslo_i18n.test') def tearDown(self): # reset to value before test _lazy.USE_LAZY = self._USE_LAZY super(GettextTest, self).tearDown() def test_gettext_does_not_blow_up(self): LOG.info(self.t.primary('test')) def test__gettextutils_install(self): _gettextutils.install('blaa') _lazy.enable_lazy(False) self.assertTrue(isinstance(self.t.primary('A String'), str)) _gettextutils.install('blaa') _lazy.enable_lazy(True) self.assertTrue(isinstance(self.t.primary('A Message'), _message.Message)) def test_gettext_install_looks_up_localedir(self): with mock.patch('os.environ.get') as environ_get: with mock.patch('gettext.install'): environ_get.return_value = '/foo/bar' _gettextutils.install('blaa') environ_get.assert_has_calls([mock.call('BLAA_LOCALEDIR')]) def test_gettext_install_updates_builtins(self): with mock.patch('os.environ.get') as environ_get: with mock.patch('gettext.install'): environ_get.return_value = '/foo/bar' if '_' in builtins.__dict__: del builtins.__dict__['_'] _gettextutils.install('blaa') self.assertIn('_', builtins.__dict__) def test_get_available_languages(self): # Only the languages available for a specific translation domain def _mock_gettext_find(domain, localedir=None, languages=None, all=0): languages = languages or [] if domain == 'domain_1': if any(x in ['en_GB', 'es_ES', 'fil_PH', 'it'] for x in languages): return 'translation-file' elif domain == 'domain_2': if any(x in ['fr_FR', 'zh_HK'] for x in languages): return 'translation-file' return None mock_patcher = mock.patch.object(gettext, 'find', _mock_gettext_find) mock_patcher.start() self.addCleanup(mock_patcher.stop) # Ensure that no domains are cached _gettextutils._AVAILABLE_LANGUAGES = {} # en_US should always be available no matter the domain # and it should also always be the first element since order matters domain_1_languages = _gettextutils.get_available_languages('domain_1') domain_2_languages = _gettextutils.get_available_languages('domain_2') # The domain languages should be included after en_US with # with their respective aliases when it applies self.assertEqual('en_US', domain_1_languages[0]) self.assertEqual('en_US', domain_2_languages[0]) self.assertEqual(5, len(domain_1_languages), domain_1_languages) self.assertEqual( {'en_US', 'fil_PH', 'en_GB', 'es_ES', 'it'}, set(domain_1_languages), ) self.assertEqual(3, len(domain_2_languages), domain_2_languages) self.assertEqual({'en_US', 'fr_FR', 'zh_HK'}, set(domain_2_languages)) self.assertEqual(2, len(_gettextutils._AVAILABLE_LANGUAGES)) # Now test an unknown domain, only en_US should be included unknown_domain_languages = _gettextutils.get_available_languages('huh') self.assertEqual(1, len(unknown_domain_languages)) self.assertIn('en_US', unknown_domain_languages) def test_cached_find(self): domain = 'my-unique-domain' key = (domain, None, None, 0) self.assertNotIn(key, _gettextutils._FIND_CACHE) gettext.find(domain) self.assertIn(key, _gettextutils._FIND_CACHE) _gettextutils._FIND_CACHE[key] = "spoof result" self.assertEqual("spoof result", gettext.find(domain)) _gettextutils._FIND_CACHE.pop(key) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_handler.py0000664000175000017500000001037100000000000021303 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import io import logging from unittest import mock from oslotest import base as test_base from oslo_i18n import _message from oslo_i18n import log as i18n_log from oslo_i18n.tests import fakes LOG = logging.getLogger(__name__) class TranslationHandlerTestCase(test_base.BaseTestCase): def setUp(self): super(TranslationHandlerTestCase, self).setUp() self.stream = io.StringIO() self.destination_handler = logging.StreamHandler(self.stream) self.translation_handler = i18n_log.TranslationHandler('zh_CN') self.translation_handler.setTarget(self.destination_handler) self.logger = logging.getLogger('localehander_logger') self.logger.setLevel(logging.DEBUG) self.logger.addHandler(self.translation_handler) def test_set_formatter(self): formatter = 'some formatter' self.translation_handler.setFormatter(formatter) self.assertEqual(formatter, self.translation_handler.target.formatter) @mock.patch('gettext.translation') def test_emit_translated_message(self, mock_translation): log_message = 'A message to be logged' log_message_translation = 'A message to be logged in Chinese' translations = {log_message: log_message_translation} translations_map = {'zh_CN': translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator msg = _message.Message(log_message) self.logger.info(msg) self.assertIn(log_message_translation, self.stream.getvalue()) @mock.patch('gettext.translation') def test_emit_translated_message_with_args(self, mock_translation): log_message = 'A message to be logged %s' log_message_translation = 'A message to be logged in Chinese %s' log_arg = 'Arg to be logged' log_arg_translation = 'An arg to be logged in Chinese' translations = {log_message: log_message_translation, log_arg: log_arg_translation} translations_map = {'zh_CN': translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator msg = _message.Message(log_message) arg = _message.Message(log_arg) self.logger.info(msg, arg) self.assertIn(log_message_translation % log_arg_translation, self.stream.getvalue()) @mock.patch('gettext.translation') def test_emit_translated_message_with_named_args(self, mock_translation): log_message = 'A message to be logged %(arg1)s $(arg2)s' log_message_translation = 'Chinese msg to be logged %(arg1)s $(arg2)s' log_arg_1 = 'Arg1 to be logged' log_arg_1_translation = 'Arg1 to be logged in Chinese' log_arg_2 = 'Arg2 to be logged' log_arg_2_translation = 'Arg2 to be logged in Chinese' translations = {log_message: log_message_translation, log_arg_1: log_arg_1_translation, log_arg_2: log_arg_2_translation} translations_map = {'zh_CN': translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator msg = _message.Message(log_message) arg_1 = _message.Message(log_arg_1) arg_2 = _message.Message(log_arg_2) self.logger.info(msg, {'arg1': arg_1, 'arg2': arg_2}) translation = log_message_translation % {'arg1': log_arg_1_translation, 'arg2': log_arg_2_translation} self.assertIn(translation, self.stream.getvalue()) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_lazy.py0000664000175000017500000000233200000000000020643 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslotest import base as test_base from oslo_i18n import _lazy class LazyTest(test_base.BaseTestCase): def setUp(self): super(LazyTest, self).setUp() self._USE_LAZY = _lazy.USE_LAZY def tearDown(self): _lazy.USE_LAZY = self._USE_LAZY super(LazyTest, self).tearDown() def test_enable_lazy(self): _lazy.USE_LAZY = False _lazy.enable_lazy() self.assertTrue(_lazy.USE_LAZY) def test_disable_lazy(self): _lazy.USE_LAZY = True _lazy.enable_lazy(False) self.assertFalse(_lazy.USE_LAZY) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_locale_dir_variable.py0000664000175000017500000000231000000000000023622 0ustar00zuulzuul00000000000000# All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslotest import base as test_base import testscenarios.testcase from oslo_i18n import _locale class LocaleDirVariableTest(testscenarios.testcase.WithScenarios, test_base.BaseTestCase): scenarios = [ ('simple', {'domain': 'simple', 'expected': 'SIMPLE_LOCALEDIR'}), ('with_dot', {'domain': 'one.two', 'expected': 'ONE_TWO_LOCALEDIR'}), ('with_dash', {'domain': 'one-two', 'expected': 'ONE_TWO_LOCALEDIR'}), ] def test_make_variable_name(self): var = _locale.get_locale_dir_variable_name(self.domain) self.assertEqual(self.expected, var) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_logging.py0000664000175000017500000000250500000000000021314 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from unittest import mock from oslotest import base as test_base from oslo_i18n import _factory class LogLevelTranslationsTest(test_base.BaseTestCase): def test_info(self): self._test('info') def test_warning(self): self._test('warning') def test_error(self): self._test('error') def test_critical(self): self._test('critical') def _test(self, level): with mock.patch.object(_factory.TranslatorFactory, '_make_translation_func') as mtf: tf = _factory.TranslatorFactory('domain') getattr(tf, 'log_%s' % level) mtf.assert_called_with('domain-log-%s' % level) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_message.py0000664000175000017500000007035500000000000021322 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import logging from unittest import mock import warnings from oslotest import base as test_base import testtools from oslo_i18n import _message from oslo_i18n.tests import fakes from oslo_i18n.tests import utils LOG = logging.getLogger(__name__) class MessageTestCase(test_base.BaseTestCase): """Unit tests for locale Message class.""" def test_message_id_and_message_text(self): message = _message.Message('1') self.assertEqual('1', message.msgid) self.assertEqual('1', message) message = _message.Message('1', msgtext='A') self.assertEqual('1', message.msgid) self.assertEqual('A', message) def test_message_is_unicode(self): message = _message.Message('some %s') % 'message' self.assertIsInstance(message, str) @mock.patch('locale.getlocale') @mock.patch('gettext.translation') def test_create_message_non_english_default_locale(self, mock_translation, mock_locale): msgid = 'A message in English' es_translation = 'A message in Spanish' es_translations = {msgid: es_translation} translations_map = {'es': es_translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator mock_locale.return_value = ('es',) message = _message.Message(msgid) # The base representation of the message is in Spanish, as well as # the default translation, since the default locale was Spanish. self.assertEqual(es_translation, message) self.assertEqual(es_translation, message.translation()) def test_translation_returns_unicode(self): message = _message.Message('some %s') % 'message' self.assertIsInstance(message.translation(), str) def test_mod_with_named_parameters(self): msgid = ("%(description)s\nCommand: %(cmd)s\n" "Exit code: %(exit_code)s\nStdout: %(stdout)r\n" "Stderr: %(stderr)r %%(something)s") params = {'description': 'test1', 'cmd': 'test2', 'exit_code': 'test3', 'stdout': 'test4', 'stderr': 'test5', 'something': 'trimmed'} result = _message.Message(msgid) % params expected = msgid % params self.assertEqual(expected, result) self.assertEqual(expected, result.translation()) def test_multiple_mod_with_named_parameter(self): msgid = ("%(description)s\nCommand: %(cmd)s\n" "Exit code: %(exit_code)s\nStdout: %(stdout)r\n" "Stderr: %(stderr)r") params = {'description': 'test1', 'cmd': 'test2', 'exit_code': 'test3', 'stdout': 'test4', 'stderr': 'test5'} # Run string interpolation the first time to make a new Message first = _message.Message(msgid) % params # Run string interpolation on the new Message, to replicate # one of the error paths with some Exception classes we've # implemented in OpenStack. We should receive a second Message # object, but the translation results should be the same. # # The production code that triggers this problem does something # like: # # msg = _('there was a problem %(name)s') % {'name': 'some value'} # LOG.error(msg) # raise BadExceptionClass(msg) # # where BadExceptionClass does something like: # # class BadExceptionClass(Exception): # def __init__(self, msg, **kwds): # super(BadExceptionClass, self).__init__(msg % kwds) # expected = first % {} # Base message id should be the same self.assertEqual(first.msgid, expected.msgid) # Preserved arguments should be the same self.assertEqual(first.params, expected.params) # Should have different objects self.assertIsNot(expected, first) # Final translations should be the same self.assertEqual(expected.translation(), first.translation()) def test_mod_with_named_parameters_no_space(self): msgid = ("Request: %(method)s http://%(server)s:" "%(port)s%(url)s with headers %(headers)s") params = {'method': 'POST', 'server': 'test1', 'port': 1234, 'url': 'test2', 'headers': {'h1': 'val1'}} result = _message.Message(msgid) % params expected = msgid % params self.assertEqual(expected, result) self.assertEqual(expected, result.translation()) def test_mod_with_dict_parameter(self): msgid = "Test that we can inject a dictionary %s" params = {'description': 'test1'} result = _message.Message(msgid) % params expected = msgid % params self.assertEqual(expected, result) self.assertEqual(expected, result.translation()) def test_mod_with_wrong_field_type_in_trans(self): msgid = "Correct type %(arg1)s" params = {'arg1': 'test1'} with mock.patch('gettext.translation') as trans: # Set up ugettext to return the original message with the # correct format string. trans.return_value.ugettext.return_value = msgid # Build a message and give it some parameters. result = _message.Message(msgid) % params # Now set up ugettext to return the translated version of # the original message, with a bad format string. wrong_type = 'Wrong type %(arg1)d' trans.return_value.gettext.return_value = wrong_type trans_result = result.translation() expected = msgid % params self.assertEqual(expected, trans_result) def test_mod_with_wrong_field_type(self): msgid = "Test that we handle unused args %(arg1)d" params = {'arg1': 'test1'} with testtools.ExpectedException(TypeError): _message.Message(msgid) % params def test_mod_with_missing_arg(self): msgid = "Test that we handle missing args %(arg1)s %(arg2)s" params = {'arg1': 'test1'} with testtools.ExpectedException(KeyError, '.*arg2.*'): _message.Message(msgid) % params def test_mod_with_integer_parameters(self): msgid = "Some string with params: %d" params = [0, 1, 10, 24124] messages = [] results = [] for param in params: messages.append(msgid % param) results.append(_message.Message(msgid) % param) for message, result in zip(messages, results): self.assertIsInstance(result, _message.Message) self.assertEqual(message, result.translation()) # simulate writing out as string result_str = '%s' % result.translation() self.assertEqual(result_str, message) self.assertEqual(message, result) def test_mod_copies_parameters(self): msgid = "Found object: %(current_value)s" changing_dict = {'current_value': 1} # A message created with some params result = _message.Message(msgid) % changing_dict # The parameters may change changing_dict['current_value'] = 2 # Even if the param changes when the message is # translated it should use the original param self.assertEqual('Found object: 1', result.translation()) def test_mod_deep_copies_parameters(self): msgid = "Found list: %(current_list)s" changing_list = list([1, 2, 3]) params = {'current_list': changing_list} # Apply the params result = _message.Message(msgid) % params # Change the list changing_list.append(4) # Even though the list changed the message # translation should use the original list self.assertEqual("Found list: [1, 2, 3]", result.translation()) def test_mod_deep_copies_param_nodeep_param(self): msgid = "Value: %s" params = utils.NoDeepCopyObject(5) # Apply the params result = _message.Message(msgid) % params self.assertEqual("Value: 5", result.translation()) def test_mod_deep_copies_param_nodeep_dict(self): msgid = "Values: %(val1)s %(val2)s" params = {'val1': 1, 'val2': utils.NoDeepCopyObject(2)} # Apply the params result = _message.Message(msgid) % params self.assertEqual("Values: 1 2", result.translation()) # Apply again to make sure other path works as well params = {'val1': 3, 'val2': utils.NoDeepCopyObject(4)} result = _message.Message(msgid) % params self.assertEqual("Values: 3 4", result.translation()) def test_mod_returns_a_copy(self): msgid = "Some msgid string: %(test1)s %(test2)s" message = _message.Message(msgid) m1 = message % {'test1': 'foo', 'test2': 'bar'} m2 = message % {'test1': 'foo2', 'test2': 'bar2'} self.assertIsNot(message, m1) self.assertIsNot(message, m2) self.assertEqual(m1.translation(), msgid % {'test1': 'foo', 'test2': 'bar'}) self.assertEqual(m2.translation(), msgid % {'test1': 'foo2', 'test2': 'bar2'}) def test_mod_with_none_parameter(self): msgid = "Some string with params: %s" message = _message.Message(msgid) % None self.assertEqual(msgid % None, message) self.assertEqual(msgid % None, message.translation()) def test_mod_with_missing_parameters(self): msgid = "Some string with params: %s %s" test_me = lambda: _message.Message(msgid) % 'just one' # Just like with strings missing parameters raise TypeError self.assertRaises(TypeError, test_me) def test_mod_with_extra_parameters(self): msgid = "Some string with params: %(param1)s %(param2)s" params = {'param1': 'test', 'param2': 'test2', 'param3': 'notinstring'} result = _message.Message(msgid) % params expected = msgid % params self.assertEqual(expected, result) self.assertEqual(expected, result.translation()) # Make sure unused params still there self.assertEqual(params.keys(), result.params.keys()) def test_add_disabled(self): msgid = "A message" test_me = lambda: _message.Message(msgid) + ' some string' self.assertRaises(TypeError, test_me) def test_radd_disabled(self): msgid = "A message" test_me = lambda: utils.SomeObject('test') + _message.Message(msgid) self.assertRaises(TypeError, test_me) @mock.patch('gettext.translation') def test_translation(self, mock_translation): en_message = 'A message in the default locale' es_translation = 'A message in Spanish' message = _message.Message(en_message) es_translations = {en_message: es_translation} translations_map = {'es': es_translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator self.assertEqual(es_translation, message.translation('es')) @mock.patch('gettext.translation') def test_translate_message_from_unicoded_object(self, mock_translation): en_message = 'A message in the default locale' es_translation = 'A message in Spanish' message = _message.Message(en_message) es_translations = {en_message: es_translation} translations_map = {'es': es_translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator # Here we are not testing the Message object directly but the result # of unicoding() an object whose unicode representation is a Message obj = utils.SomeObject(message) unicoded_obj = str(obj) self.assertEqual(es_translation, unicoded_obj.translation('es')) @mock.patch('gettext.translation') def test_translate_multiple_languages(self, mock_translation): en_message = 'A message in the default locale' es_translation = 'A message in Spanish' zh_translation = 'A message in Chinese' message = _message.Message(en_message) es_translations = {en_message: es_translation} zh_translations = {en_message: zh_translation} translations_map = {'es': es_translations, 'zh': zh_translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator self.assertEqual(es_translation, message.translation('es')) self.assertEqual(zh_translation, message.translation('zh')) self.assertEqual(en_message, message.translation(None)) self.assertEqual(en_message, message.translation('en')) self.assertEqual(en_message, message.translation('XX')) @mock.patch('gettext.translation') def test_translate_message_with_param(self, mock_translation): message_with_params = 'A message: %s' es_translation = 'A message in Spanish: %s' param = 'A Message param' translations = {message_with_params: es_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) msg = msg % param default_translation = message_with_params % param expected_translation = es_translation % param self.assertEqual(expected_translation, msg.translation('es')) self.assertEqual(default_translation, msg.translation('XX')) @mock.patch('gettext.translation') @mock.patch('oslo_i18n._message.LOG') def test_translate_message_bad_translation(self, mock_log, mock_translation): message_with_params = 'A message: %s' es_translation = 'A message in Spanish: %s %s' param = 'A Message param' translations = {message_with_params: es_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") msg = _message.Message(message_with_params) msg = msg % param default_translation = message_with_params % param self.assertEqual(default_translation, msg.translation('es')) self.assertEqual(1, len(w)) # Note(gibi): in python 3.4 str.__repr__ does not put the unicode # marker 'u' in front of the string representations so the test # removes that to have the same result in python 2.7 and 3.4 self.assertEqual("Failed to insert replacement values into " "translated message A message in Spanish: %s %s " "(Original: 'A message: %s'): " "not enough arguments for format string", str(w[0].message).replace("u'", "'")) mock_log.debug.assert_called_with(('Failed to insert replacement ' 'values into translated message ' '%s (Original: %r): %s'), es_translation, message_with_params, mock.ANY) @mock.patch('gettext.translation') @mock.patch('locale.getlocale', return_value=('es', '')) @mock.patch('oslo_i18n._message.LOG') def test_translate_message_bad_default_translation(self, mock_log, mock_locale, mock_translation): message_with_params = 'A message: %s' es_translation = 'A message in Spanish: %s %s' param = 'A Message param' translations = {message_with_params: es_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") msg = msg % param self.assertEqual(1, len(w)) # Note(gibi): in python 3.4 str.__repr__ does not put the unicode # marker 'u' in front of the string representations so the test # removes that to have the same result in python 2.7 and 3.4 self.assertEqual("Failed to insert replacement values into " "translated message A message in Spanish: %s %s " "(Original: 'A message: %s'): " "not enough arguments for format string", str(w[0].message).replace("u'", "'")) mock_log.debug.assert_called_with(('Failed to insert replacement ' 'values into translated message ' '%s (Original: %r): %s'), es_translation, message_with_params, mock.ANY) mock_log.reset_mock() default_translation = message_with_params % param self.assertEqual(default_translation, msg) self.assertFalse(mock_log.warning.called) @mock.patch('gettext.translation') def test_translate_message_with_object_param(self, mock_translation): message_with_params = 'A message: %s' es_translation = 'A message in Spanish: %s' param = 'A Message param' param_translation = 'A Message param in Spanish' translations = {message_with_params: es_translation, param: param_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) param_msg = _message.Message(param) # Here we are testing translation of a Message with another object # that can be translated via its unicode() representation, this is # very common for instance when modding an Exception with a Message obj = utils.SomeObject(param_msg) msg = msg % obj default_translation = message_with_params % param expected_translation = es_translation % param_translation self.assertEqual(expected_translation, msg.translation('es')) self.assertEqual(default_translation, msg.translation('XX')) @mock.patch('gettext.translation') def test_translate_message_with_param_from_unicoded_obj(self, mock_translation): message_with_params = 'A message: %s' es_translation = 'A message in Spanish: %s' param = 'A Message param' translations = {message_with_params: es_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) msg = msg % param default_translation = message_with_params % param expected_translation = es_translation % param obj = utils.SomeObject(msg) unicoded_obj = str(obj) self.assertEqual(expected_translation, unicoded_obj.translation('es')) self.assertEqual(default_translation, unicoded_obj.translation('XX')) @mock.patch('gettext.translation') def test_translate_message_with_message_parameter(self, mock_translation): message_with_params = 'A message with param: %s' es_translation = 'A message with param in Spanish: %s' message_param = 'A message param' es_param_translation = 'A message param in Spanish' translations = {message_with_params: es_translation, message_param: es_param_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) msg_param = _message.Message(message_param) msg = msg % msg_param default_translation = message_with_params % message_param expected_translation = es_translation % es_param_translation self.assertEqual(expected_translation, msg.translation('es')) self.assertEqual(default_translation, msg.translation('XX')) @mock.patch('gettext.translation') def test_translate_message_with_message_parameters(self, mock_translation): message_with_params = 'A message with params: %s %s' es_translation = 'A message with params in Spanish: %s %s' message_param = 'A message param' es_param_translation = 'A message param in Spanish' another_message_param = 'Another message param' another_es_param_translation = 'Another message param in Spanish' translations = {message_with_params: es_translation, message_param: es_param_translation, another_message_param: another_es_param_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) param_1 = _message.Message(message_param) param_2 = _message.Message(another_message_param) msg = msg % (param_1, param_2) default_translation = message_with_params % (message_param, another_message_param) expected_translation = es_translation % (es_param_translation, another_es_param_translation) self.assertEqual(expected_translation, msg.translation('es')) self.assertEqual(default_translation, msg.translation('XX')) @mock.patch('gettext.translation') def test_translate_message_with_named_parameters(self, mock_translation): message_with_params = 'A message with params: %(param)s' es_translation = 'A message with params in Spanish: %(param)s' message_param = 'A Message param' es_param_translation = 'A message param in Spanish' translations = {message_with_params: es_translation, message_param: es_param_translation} translator = fakes.FakeTranslations.translator({'es': translations}) mock_translation.side_effect = translator msg = _message.Message(message_with_params) msg_param = _message.Message(message_param) msg = msg % {'param': msg_param} default_translation = message_with_params % {'param': message_param} expected_translation = es_translation % {'param': es_param_translation} self.assertEqual(expected_translation, msg.translation('es')) self.assertEqual(default_translation, msg.translation('XX')) @mock.patch('locale.getlocale') @mock.patch('gettext.translation') def test_translate_message_non_default_locale(self, mock_translation, mock_locale): message_with_params = 'A message with params: %(param)s' es_translation = 'A message with params in Spanish: %(param)s' zh_translation = 'A message with params in Chinese: %(param)s' fr_translation = 'A message with params in French: %(param)s' message_param = 'A Message param' es_param_translation = 'A message param in Spanish' zh_param_translation = 'A message param in Chinese' fr_param_translation = 'A message param in French' es_translations = {message_with_params: es_translation, message_param: es_param_translation} zh_translations = {message_with_params: zh_translation, message_param: zh_param_translation} fr_translations = {message_with_params: fr_translation, message_param: fr_param_translation} translator = fakes.FakeTranslations.translator({'es': es_translations, 'zh': zh_translations, 'fr': fr_translations}) mock_translation.side_effect = translator mock_locale.return_value = ('es',) msg = _message.Message(message_with_params) msg_param = _message.Message(message_param) msg = msg % {'param': msg_param} es_translation = es_translation % {'param': es_param_translation} zh_translation = zh_translation % {'param': zh_param_translation} fr_translation = fr_translation % {'param': fr_param_translation} # Because sys.getlocale() was Spanish, # the default translation will be to Spanish self.assertEqual(es_translation, msg) self.assertEqual(es_translation, msg.translation()) self.assertEqual(es_translation, msg.translation('es')) # Translation into other locales still works self.assertEqual(zh_translation, msg.translation('zh')) self.assertEqual(fr_translation, msg.translation('fr')) class TranslateMsgidTest(test_base.BaseTestCase): @mock.patch('gettext.translation') def test_contextual(self, translation): lang = mock.Mock() translation.return_value = lang trans = mock.Mock() trans.return_value = 'translated' lang.gettext = trans lang.ugettext = trans result = _message.Message._translate_msgid( ('context', 'message'), domain='domain', has_contextual_form=True, has_plural_form=False, ) self.assertEqual('translated', result) trans.assert_called_with( 'context' + _message.CONTEXT_SEPARATOR + 'message' ) @mock.patch('gettext.translation') def test_contextual_untranslatable(self, translation): msg_with_context = 'context' + _message.CONTEXT_SEPARATOR + 'message' lang = mock.Mock() translation.return_value = lang trans = mock.Mock() trans.return_value = msg_with_context lang.gettext = trans lang.ugettext = trans result = _message.Message._translate_msgid( ('context', 'message'), domain='domain', has_contextual_form=True, has_plural_form=False, ) self.assertEqual('message', result) trans.assert_called_with(msg_with_context) @mock.patch('gettext.translation') def test_plural(self, translation): lang = mock.Mock() translation.return_value = lang trans = mock.Mock() trans.return_value = 'translated' lang.ngettext = trans lang.ungettext = trans result = _message.Message._translate_msgid( ('single', 'plural', -1), domain='domain', has_contextual_form=False, has_plural_form=True, ) self.assertEqual('translated', result) trans.assert_called_with( 'single', 'plural', -1, ) @mock.patch('gettext.translation') def test_contextual_and_plural(self, translation): self.assertRaises( ValueError, _message.Message._translate_msgid, 'nothing', domain='domain', has_contextual_form=True, has_plural_form=True, ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_public_api.py0000664000175000017500000000240300000000000021772 0ustar00zuulzuul00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """A few tests that use the public API to ensure the imports work.""" import unittest import oslo_i18n from oslo_i18n import _lazy class PublicAPITest(unittest.TestCase): def test_create_factory(self): oslo_i18n.TranslatorFactory('domain') def test_install(self): oslo_i18n.install('domain') def test_get_available_languages(self): oslo_i18n.get_available_languages('domains') def test_toggle_lazy(self): original = _lazy.USE_LAZY try: oslo_i18n.enable_lazy(True) oslo_i18n.enable_lazy(False) finally: oslo_i18n.enable_lazy(original) def test_translate(self): oslo_i18n.translate('string') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/test_translate.py0000664000175000017500000000315200000000000021662 0ustar00zuulzuul00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from unittest import mock from oslotest import base as test_base from oslo_i18n import _message from oslo_i18n import _translate from oslo_i18n.tests import fakes from oslo_i18n.tests import utils class TranslateTest(test_base.BaseTestCase): @mock.patch('gettext.translation') def test_translate(self, mock_translation): en_message = 'A message in the default locale' es_translation = 'A message in Spanish' message = _message.Message(en_message) es_translations = {en_message: es_translation} translations_map = {'es': es_translations} translator = fakes.FakeTranslations.translator(translations_map) mock_translation.side_effect = translator # translate() works on msgs and on objects whose unicode reps are msgs obj = utils.SomeObject(message) self.assertEqual(es_translation, _translate.translate(message, 'es')) self.assertEqual(es_translation, _translate.translate(obj, 'es')) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/oslo_i18n/tests/utils.py0000664000175000017500000000172000000000000017765 0ustar00zuulzuul00000000000000# All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. class SomeObject(object): def __init__(self, message): self.message = message def __str__(self): return self.message class NoDeepCopyObject(object): def __init__(self, value): self.value = value def __str__(self): return str(self.value) def __deepcopy__(self, memo): raise TypeError('Deep Copy not supported') ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/releasenotes/0000775000175000017500000000000000000000000015767 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0273798 oslo.i18n-6.4.0/releasenotes/notes/0000775000175000017500000000000000000000000017117 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/notes/add-reno-996dd44974d53238.yaml0000664000175000017500000000007200000000000023515 0ustar00zuulzuul00000000000000--- other: - Introduce reno for deployer release notes. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/notes/drop-python27-support-eb9c2ad3268f0c1f.yaml0000664000175000017500000000017700000000000026530 0ustar00zuulzuul00000000000000--- upgrade: - | Support for Python 2.7 has been dropped. The minimum version of Python now supported is Python 3.6. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/releasenotes/source/0000775000175000017500000000000000000000000017267 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/2023.1.rst0000664000175000017500000000020200000000000020540 0ustar00zuulzuul00000000000000=========================== 2023.1 Series Release Notes =========================== .. release-notes:: :branch: stable/2023.1 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/2023.2.rst0000664000175000017500000000020200000000000020541 0ustar00zuulzuul00000000000000=========================== 2023.2 Series Release Notes =========================== .. release-notes:: :branch: stable/2023.2 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/2024.1.rst0000664000175000017500000000020200000000000020541 0ustar00zuulzuul00000000000000=========================== 2024.1 Series Release Notes =========================== .. release-notes:: :branch: stable/2024.1 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/releasenotes/source/_static/0000775000175000017500000000000000000000000020715 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/_static/.placeholder0000664000175000017500000000000000000000000023166 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/releasenotes/source/_templates/0000775000175000017500000000000000000000000021424 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/_templates/.placeholder0000664000175000017500000000000000000000000023675 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/conf.py0000664000175000017500000002151200000000000020567 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'openstackdocstheme', 'reno.sphinxext', ] # openstackdocstheme options openstackdocs_repo_name = 'openstack/oslo.i18n' openstackdocs_bug_project = 'oslo.i18n' openstackdocs_bug_tag = '' openstackdocs_auto_name = False # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'oslo.i18n Release Notes' copyright = '2016, oslo.i18n Developers' # Release notes do not need a version in the title, they span # multiple versions. # The full version, including alpha/beta/rc tags. release = '' # The short X.Y version. version = '' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'oslo.i18nReleaseNotesDoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'oslo.i18nReleaseNotes.tex', 'oslo.i18n Release Notes Documentation', 'oslo.i18n Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'oslo.i18nReleaseNotes', 'oslo.i18n Release Notes Documentation', ['oslo.i18n Developers'], 1) ] # If true, show URL addresses after external links. # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'oslo.i18nReleaseNotes', 'oslo.i18n Release Notes Documentation', 'oslo.i18n Developers', 'oslo.i18nReleaseNotes', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/index.rst0000664000175000017500000000034400000000000021131 0ustar00zuulzuul00000000000000========================= oslo.i18n Release Notes ========================= .. toctree:: :maxdepth: 1 unreleased 2024.1 2023.2 2023.1 victoria ussuri train stein rocky queens pike ocata ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/releasenotes/source/locale/0000775000175000017500000000000000000000000020526 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/releasenotes/source/locale/en_GB/0000775000175000017500000000000000000000000021500 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/releasenotes/source/locale/en_GB/LC_MESSAGES/0000775000175000017500000000000000000000000023265 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po0000664000175000017500000000400700000000000026317 0ustar00zuulzuul00000000000000# Andi Chandler , 2017. #zanata # Andi Chandler , 2018. #zanata # Andi Chandler , 2019. #zanata # Andi Chandler , 2020. #zanata # Andi Chandler , 2022. #zanata # Andi Chandler , 2023. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n Release Notes\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-05-08 09:44+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2023-05-09 12:01+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en_GB\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "2023.1 Series Release Notes" msgstr "2023.1 Series Release Notes" msgid "3.11.0" msgstr "3.11.0" msgid "4.0.0" msgstr "4.0.0" msgid "Introduce reno for deployer release notes." msgstr "Introduce reno for deployer release notes." msgid "Ocata Series Release Notes" msgstr "Ocata Series Release Notes" msgid "Other Notes" msgstr "Other Notes" msgid "Pike Series Release Notes" msgstr "Pike Series Release Notes" msgid "Queens Series Release Notes" msgstr "Queens Series Release Notes" msgid "Rocky Series Release Notes" msgstr "Rocky Series Release Notes" msgid "Stein Series Release Notes" msgstr "Stein Series Release Notes" msgid "" "Support for Python 2.7 has been dropped. The minimum version of Python now " "supported is Python 3.6." msgstr "" "Support for Python 2.7 has been dropped. The minimum version of Python now " "supported is Python 3.6." msgid "Train Series Release Notes" msgstr "Train Series Release Notes" msgid "Unreleased Release Notes" msgstr "Unreleased Release Notes" msgid "Upgrade Notes" msgstr "Upgrade Notes" msgid "Ussuri Series Release Notes" msgstr "Ussuri Series Release Notes" msgid "Victoria Series Release Notes" msgstr "Victoria Series Release Notes" msgid "oslo.i18n Release Notes" msgstr "oslo.i18n Release Notes" ././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724253426.01138 oslo.i18n-6.4.0/releasenotes/source/locale/ko_KR/0000775000175000017500000000000000000000000021533 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/releasenotes/source/locale/ko_KR/LC_MESSAGES/0000775000175000017500000000000000000000000023320 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po0000664000175000017500000000201500000000000026347 0ustar00zuulzuul00000000000000# minwook-shin , 2017. #zanata msgid "" msgstr "" "Project-Id-Version: oslo.i18n Release Notes\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-02-05 13:14+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2017-08-04 07:11+0000\n" "Last-Translator: minwook-shin \n" "Language-Team: Korean (South Korea)\n" "Language: ko_KR\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=1; plural=0\n" msgid "3.11.0" msgstr "3.11.0" msgid "Introduce reno for deployer release notes." msgstr "릴리즈 노트 배포에 reno를 도입하기." msgid "Ocata Series Release Notes" msgstr "Ocata 시리즈에 대한 릴리즈 노트" msgid "Other Notes" msgstr "기타 노트" msgid "Pike Series Release Notes" msgstr "Pike 시리즈에 대한 릴리즈 노트" msgid "Unreleased Release Notes" msgstr "릴리즈되지않은 릴리즈 노트" msgid "oslo.i18n Release Notes" msgstr "oslo.i18n 릴리즈 노트" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/ocata.rst0000664000175000017500000000023000000000000021103 0ustar00zuulzuul00000000000000=================================== Ocata Series Release Notes =================================== .. release-notes:: :branch: origin/stable/ocata ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/pike.rst0000664000175000017500000000021700000000000020751 0ustar00zuulzuul00000000000000=================================== Pike Series Release Notes =================================== .. release-notes:: :branch: stable/pike ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/queens.rst0000664000175000017500000000022300000000000021316 0ustar00zuulzuul00000000000000=================================== Queens Series Release Notes =================================== .. release-notes:: :branch: stable/queens ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/rocky.rst0000664000175000017500000000022100000000000021143 0ustar00zuulzuul00000000000000=================================== Rocky Series Release Notes =================================== .. release-notes:: :branch: stable/rocky ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/stein.rst0000664000175000017500000000022100000000000021136 0ustar00zuulzuul00000000000000=================================== Stein Series Release Notes =================================== .. release-notes:: :branch: stable/stein ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/train.rst0000664000175000017500000000017600000000000021142 0ustar00zuulzuul00000000000000========================== Train Series Release Notes ========================== .. release-notes:: :branch: stable/train ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/unreleased.rst0000664000175000017500000000014400000000000022147 0ustar00zuulzuul00000000000000========================== Unreleased Release Notes ========================== .. release-notes:: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/ussuri.rst0000664000175000017500000000020200000000000021345 0ustar00zuulzuul00000000000000=========================== Ussuri Series Release Notes =========================== .. release-notes:: :branch: stable/ussuri ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/releasenotes/source/victoria.rst0000664000175000017500000000022000000000000021633 0ustar00zuulzuul00000000000000============================= Victoria Series Release Notes ============================= .. release-notes:: :branch: unmaintained/victoria ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/requirements.txt0000664000175000017500000000003000000000000016553 0ustar00zuulzuul00000000000000pbr>=2.0.0 # Apache-2.0 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724253426.0313797 oslo.i18n-6.4.0/setup.cfg0000664000175000017500000000153500000000000015123 0ustar00zuulzuul00000000000000[metadata] name = oslo.i18n summary = Oslo i18n library description_file = README.rst author = OpenStack author_email = openstack-discuss@lists.openstack.org home_page = https://docs.openstack.org/oslo.i18n/latest python_requires = >=3.8 classifier = Environment :: OpenStack Intended Audience :: Information Technology Intended Audience :: System Administrators License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: Implementation :: CPython [files] packages = oslo_i18n [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/setup.py0000664000175000017500000000127100000000000015011 0ustar00zuulzuul00000000000000# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import setuptools setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/test-requirements.txt0000664000175000017500000000045700000000000017545 0ustar00zuulzuul00000000000000hacking>=6.1.0,<6.2.0 # Apache-2.0 stestr>=2.0.0 # Apache-2.0 oslotest>=3.2.0 # Apache-2.0 coverage>=4.0 # Apache-2.0 testscenarios>=0.4 # Apache-2.0/BSD # for pre-release tests oslo.config>=5.2.0 # Apache-2.0 # Bandit security code scanner bandit>=1.7.0,<1.8.0 # Apache-2.0 pre-commit>=2.6.0 # MIT ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724253376.0 oslo.i18n-6.4.0/tox.ini0000664000175000017500000000315100000000000014611 0ustar00zuulzuul00000000000000[tox] minversion = 3.18.0 envlist = py3,pep8 [testenv] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/test-requirements.txt -r{toxinidir}/requirements.txt commands = stestr run --slowest {posargs} [testenv:cover] setenv = PYTHON=coverage run --source oslo_i18n --parallel-mode commands = coverage erase stestr run {posargs} coverage combine coverage html -d cover coverage xml -o cover/coverage.xml coverage report --show-missing [testenv:pep8] deps = -r{toxinidir}/test-requirements.txt commands = pre-commit run -a # Run security linter bandit -r oslo_i18n -x tests -n5 [testenv:venv] commands = {posargs} [testenv:docs] allowlist_externals = rm deps = {[testenv]deps} -r{toxinidir}/doc/requirements.txt commands = rm -rf doc/build sphinx-build -W --keep-going -b html doc/source doc/build/html [testenv:releasenotes] whitelist_externals = rm deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt commands = rm -rf releasenotes/build sphinx-build -a -E -W -d releasenotes/build/doctrees --keep-going -b html releasenotes/source releasenotes/build/html [flake8] show-source = True # E123, E125 skipped as they are invalid PEP-8. # E731 skipped as assign a lambda expression ignore = E123,E125,E731,W504 # H106: Don’t put vim configuration in source files # H203: Use assertIs(Not)None to check for None enable-extensions=H106,H203 exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,__init__.py [hacking] import_exceptions = oslo_i18n._i18n._