launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32154
[Merge] ~alvarocs/pygettextpo:upgrade-python-version into pygettextpo:main
Alvaro Crespo Serrano has proposed merging ~alvarocs/pygettextpo:upgrade-python-version into pygettextpo:main.
Commit message:
Upgrade python versions 3.8 to 3.13
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~alvarocs/pygettextpo/+git/pygettextpo/+merge/480200
- Add support for Python versions 3.8 to 3.13.
- Drop support for Python 2.
- Add tox testing support.
- Add pre-commit and linting.
- Add NEWS.rst releases file.
Tox runs successfully on all python versions and for lint.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~alvarocs/pygettextpo:upgrade-python-version into pygettextpo:main.
diff --git a/.gitignore b/.gitignore
index d0f7d29..00ccc83 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ gettextpo*.so
/build
/dist
/MANIFEST
+__pycache__
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..f2476ee
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,31 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v5.0.0
+ hooks:
+ - id: check-added-large-files
+ - id: check-merge-conflict
+ - id: check-xml
+ - id: check-yaml
+ - id: debug-statements
+- repo: https://github.com/PyCQA/isort
+ rev: 5.13.2
+ hooks:
+ - id: isort
+- repo: https://github.com/PyCQA/flake8
+ rev: 7.1.1
+ hooks:
+ - id: flake8
+- repo: https://github.com/asottile/pyupgrade
+ rev: v3.19.1
+ hooks:
+ - id: pyupgrade
+- repo: https://github.com/mgedmin/check-manifest
+ rev: "0.50"
+ hooks:
+ - id: check-manifest
+- repo: https://github.com/psf/black
+ rev: 24.10.0
+ hooks:
+ - id: black
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
index 250e48a..3e2cdb2 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,6 @@
include Makefile
include MANIFEST.in
include README
+include *.yaml
+include tox.ini
+include *.rst
diff --git a/NEWS.rst b/NEWS.rst
new file mode 100644
index 0000000..9c9a42b
--- /dev/null
+++ b/NEWS.rst
@@ -0,0 +1,25 @@
+.. This is your project NEWS file which will contain the release notes.
+.. Example: http://www.python.org/download/releases/2.6/NEWS.txt
+.. The content of this file, along with README.rst, will appear in your
+.. project's PyPI page.
+
+News
+====
+
+0.3
+---
+*Release date: (unreleased)
+
+* Add support for Python versions 3.8 to 3.13.
+* Drop support for Python 2.
+* Add tox testing support.
+* Add pre-commit and linting.
+* Add NEWS.rst releases file.
+
+
+0.2
+---
+
+*Release date: 28-Sep-2022*
+
+* Initial release of pygettextpo.
diff --git a/README b/README.rst
similarity index 100%
rename from README
rename to README.rst
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..edac645
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,21 @@
+[metadata]
+name = pygettextpo
+version = 0.3
+description = A binding for the libgettext-po library
+long_description = file: README.rst
+long_description_content_type = text/x-rst
+url = https://launchpad.net/pygettextpo
+author = Canonical Ltd.
+author_email = lazr-developers@xxxxxxxxxxxxxxxxxxx
+license = GNU Affero General Public License v3
+classifiers =
+ License :: OSI Approved :: GNU Affero General Public License v3
+ 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.12
+ Programming Language :: Python :: 3.13
+ Topic :: Software Development :: Version Control
diff --git a/setup.py b/setup.py
old mode 100755
new mode 100644
index 6f1a22c..e0158f1
--- a/setup.py
+++ b/setup.py
@@ -1,25 +1,29 @@
-#!/usr/bin/env python
+#! /usr/bin/python3
+
+# Copyright (C) 2022 Canonical Ltd.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
#
-# Copyright Canonical Ltd. This software is licensed under the GNU
-# Affero General Public License version 3 (see the file LICENSE).
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-from setuptools import setup, Extension
+from setuptools import Extension, setup
gettextpo = Extension(
- 'gettextpo', ['gettextpo.c'],
- libraries=['gettextpo'])
+ "gettextpo",
+ sources=["gettextpo.c"],
+ libraries=["gettextpo"],
+)
setup(
- name='pygettextpo',
- version='0.2',
- author='Canonical Ltd.',
- author_email='lazr-developers@xxxxxxxxxxxxxxxxxxx',
- description='A binding for the libgettext-po library',
- url='https://launchpad.net/pygettextpo',
- classifiers=[
- "License :: OSI Approved :: GNU Affero General Public License v3",
- "Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 3",
- ],
- ext_modules=[gettextpo])
+ ext_modules=[gettextpo],
+)
diff --git a/test_gettextpo.py b/tests/test_gettextpo.py
similarity index 59%
rename from test_gettextpo.py
rename to tests/test_gettextpo.py
index 7dbee20..a79fcbf 100644
--- a/test_gettextpo.py
+++ b/tests/test_gettextpo.py
@@ -2,6 +2,7 @@
# Affero General Public License version 3 (see the file LICENSE).
import unittest
+
import gettextpo
@@ -16,7 +17,7 @@ class PoFileTestCase(unittest.TestCase):
# Test that we can add messages to a new pofile object
pofile = gettextpo.PoFile()
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Hello')
+ msg.set_msgid(b"Hello")
poiter = iter(pofile)
poiter.insert(msg)
@@ -27,7 +28,7 @@ class PoFileTestCase(unittest.TestCase):
pofile1 = gettextpo.PoFile()
pofile2 = gettextpo.PoFile()
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Hello')
+ msg.set_msgid(b"Hello")
poiter = iter(pofile1)
poiter.insert(msg)
@@ -41,38 +42,39 @@ class PoMessageTestCase(unittest.TestCase):
def testCreateMessage(self):
# Test that messages can be created.
msg = gettextpo.PoMessage()
+ self.assertEqual(msg.msgid, None)
def testSetMsgId(self):
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Hello')
- self.assertEqual(msg.msgid, b'Hello')
- msg.set_msgid_plural(b'Hellos')
- self.assertEqual(msg.msgid_plural, b'Hellos')
+ msg.set_msgid(b"Hello")
+ self.assertEqual(msg.msgid, b"Hello")
+ msg.set_msgid_plural(b"Hellos")
+ self.assertEqual(msg.msgid_plural, b"Hellos")
def testSetMsgCtxt(self):
msg = gettextpo.PoMessage()
- msg.set_msgctxt(b'Hello')
- self.assertEqual(msg.msgctxt, b'Hello')
+ msg.set_msgctxt(b"Hello")
+ self.assertEqual(msg.msgctxt, b"Hello")
def testSetMsgStr(self):
msg = gettextpo.PoMessage()
- msg.set_msgstr(b'Hello World')
- self.assertEqual(msg.msgstr, b'Hello World')
+ msg.set_msgstr(b"Hello World")
+ self.assertEqual(msg.msgstr, b"Hello World")
def testSetMsgStrPlural(self):
# Test handling of plural msgstrs. The PoMessage object can
# not hold plural msgstrs if the msgid does not have a plural.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Something')
- self.assertRaises(ValueError, msg.set_msgstr_plural, 0, b'Zero')
+ msg.set_msgid(b"Something")
+ self.assertRaises(ValueError, msg.set_msgstr_plural, 0, b"Zero")
self.assertEqual(msg.msgstr_plural, [])
# need to set the plural msgid first, then add the plural msgstrs
- msg.set_msgid_plural(b'Somethings')
- msg.set_msgstr_plural(0, b'Zero')
- msg.set_msgstr_plural(1, b'One')
- msg.set_msgstr_plural(2, b'Two')
- self.assertEqual(msg.msgstr_plural, [b'Zero', b'One', b'Two'])
+ msg.set_msgid_plural(b"Somethings")
+ msg.set_msgstr_plural(0, b"Zero")
+ msg.set_msgstr_plural(1, b"One")
+ msg.set_msgstr_plural(2, b"Two")
+ self.assertEqual(msg.msgstr_plural, [b"Zero", b"One", b"Two"])
class CheckFormatTestCase(unittest.TestCase):
@@ -83,7 +85,8 @@ class CheckFormatTestCase(unittest.TestCase):
self.assertEqual(expected_errors, raised.exception.error_list)
self.assertEqual(
"\n".join(message for _, _, message in expected_errors),
- str(raised.exception))
+ str(raised.exception),
+ )
def testGoodFormat(self):
# Check that no exception is raised on a good translation.
@@ -93,9 +96,9 @@ class CheckFormatTestCase(unittest.TestCase):
# format a floating point value, so no error should be raised on
# that kind of change.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Hello %s %d %g')
- msg.set_format('c-format', True)
- msg.set_msgstr(b'Bye %s %.2d %f')
+ msg.set_msgid(b"Hello %s %d %g")
+ msg.set_format("c-format", True)
+ msg.set_msgstr(b"Bye %s %.2d %f")
# this should run without an exception
msg.check_format()
@@ -103,39 +106,48 @@ class CheckFormatTestCase(unittest.TestCase):
def testAddFormatSpec(self):
# Test that an exception is raised when a format string is added.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'No format specifiers')
- msg.set_format('c-format', True)
- msg.set_msgstr(b'One format specifier: %20s')
+ msg.set_msgid(b"No format specifiers")
+ msg.set_format("c-format", True)
+ msg.set_msgstr(b"One format specifier: %20s")
expected_errors = [
- ("error", 0,
- "number of format specifications in 'msgid' and 'msgstr' does "
- "not match"),
- ]
+ (
+ "error",
+ 0,
+ "number of format specifications in 'msgid' and 'msgstr' does "
+ "not match",
+ ),
+ ]
self.assertGettextPoError(expected_errors, msg)
def testSwapFormatSpecs(self):
# Test that an exception is raised when format strings are transposed.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Spec 1: %s, Spec 2: %d')
- msg.set_format('c-format', True)
- msg.set_msgstr(b'Spec 1: %d, Spec 2: %s')
+ msg.set_msgid(b"Spec 1: %s, Spec 2: %d")
+ msg.set_format("c-format", True)
+ msg.set_msgstr(b"Spec 1: %d, Spec 2: %s")
expected_errors = [
- ("error", 0,
- "format specifications in 'msgid' and 'msgstr' for argument 1 "
- "are not the same"),
- ("error", 0,
- "format specifications in 'msgid' and 'msgstr' for argument 2 "
- "are not the same"),
- ]
+ (
+ "error",
+ 0,
+ "format specifications in 'msgid' and 'msgstr' for argument 1 "
+ "are not the same",
+ ),
+ (
+ "error",
+ 0,
+ "format specifications in 'msgid' and 'msgstr' for argument 2 "
+ "are not the same",
+ ),
+ ]
self.assertGettextPoError(expected_errors, msg)
def testNonFormatString(self):
# Test that no exception is raised if the message is not marked as
# a format string.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Spec 1: %s, Spec 2: %d')
- msg.set_format('c-format', False)
- msg.set_msgstr(b'Spec 1: %d, Spec 2: %s')
+ msg.set_msgid(b"Spec 1: %s, Spec 2: %d")
+ msg.set_format("c-format", False)
+ msg.set_msgstr(b"Spec 1: %d, Spec 2: %s")
# this should run without an exception
msg.check_format()
@@ -143,8 +155,8 @@ class CheckFormatTestCase(unittest.TestCase):
def testEmptyMsgStr(self):
# Test that empty translations do not trigger a failure.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'Hello %s')
- msg.set_format('c-format', True)
+ msg.set_msgid(b"Hello %s")
+ msg.set_format("c-format", True)
msg.set_msgstr(None)
# this should run without an exception
@@ -153,12 +165,12 @@ class CheckFormatTestCase(unittest.TestCase):
def testGoodPlural(self):
# Test that a good plural message passes without error.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'%d apple')
- msg.set_msgid_plural(b'%d apples')
- msg.set_format('c-format', True)
- msg.set_msgstr_plural(0, b'%d orange')
- msg.set_msgstr_plural(1, b'%d oranges')
- msg.set_msgstr_plural(2, b'%d oranges_')
+ msg.set_msgid(b"%d apple")
+ msg.set_msgid_plural(b"%d apples")
+ msg.set_format("c-format", True)
+ msg.set_msgstr_plural(0, b"%d orange")
+ msg.set_msgstr_plural(1, b"%d oranges")
+ msg.set_msgstr_plural(2, b"%d oranges_")
# this should run without an exception
msg.check_format()
@@ -166,28 +178,32 @@ class CheckFormatTestCase(unittest.TestCase):
def testBadPlural(self):
# Test that bad plural translations raise an error error.
msg = gettextpo.PoMessage()
- msg.set_msgid(b'%d apple')
- msg.set_msgid_plural(b'%d apples')
- msg.set_format('c-format', True)
- msg.set_msgstr_plural(0, b'%d orange')
- msg.set_msgstr_plural(1, b'%d oranges')
- msg.set_msgstr_plural(2, b'%g oranges_')
+ msg.set_msgid(b"%d apple")
+ msg.set_msgid_plural(b"%d apples")
+ msg.set_format("c-format", True)
+ msg.set_msgstr_plural(0, b"%d orange")
+ msg.set_msgstr_plural(1, b"%d oranges")
+ msg.set_msgstr_plural(2, b"%g oranges_")
expected_errors = [
- ("error", 0,
- "format specifications in 'msgid_plural' and 'msgstr[2]' for "
- "argument 1 are not the same"),
- ]
+ (
+ "error",
+ 0,
+ "format specifications in 'msgid_plural' and 'msgstr[2]' for "
+ "argument 1 are not the same",
+ ),
+ ]
self.assertGettextPoError(expected_errors, msg)
def testUnicodeString(self):
# Test that a translation with unicode chars is working.
msg = gettextpo.PoMessage()
- msg.set_msgid(u'Carlos Perell\xf3 Mar\xedn')
- msg.set_msgstr(u'Carlos Perell\xf3 Mar\xedn')
- self.assertEqual(msg.msgid, b'Carlos Perell\xc3\xb3 Mar\xc3\xadn')
- self.assertEqual(msg.msgstr, b'Carlos Perell\xc3\xb3 Mar\xc3\xadn')
+ msg.set_msgid("Carlos Perell\xf3 Mar\xedn")
+ msg.set_msgstr("Carlos Perell\xf3 Mar\xedn")
+ self.assertEqual(msg.msgid, b"Carlos Perell\xc3\xb3 Mar\xc3\xadn")
+ self.assertEqual(msg.msgstr, b"Carlos Perell\xc3\xb3 Mar\xc3\xadn")
+
-## XXXX - gettext doesn't seem to check for this one
+# XXXX - gettext doesn't seem to check for this one
#
# def testBadPluralMsgId(self):
# # Test that conflicting plural msgids raise errors on their own.
@@ -198,5 +214,5 @@ class CheckFormatTestCase(unittest.TestCase):
# self.assertRaises(gettextpo.error, msg.check_format)
#
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..28accfb
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,41 @@
+[tox]
+envlist =
+ py38,py39,py310,py311,py312,py313,lint
+
+[testenv]
+commands =
+ pytest tests {posargs}
+deps =
+ pytest
+ testtools
+
+[testenv:lint]
+basepython =
+ python3.12
+deps =
+ pre-commit
+commands =
+ pre-commit run --all-files
+
+[testenv:coverage]
+basepython =
+ python3.12
+deps =
+ .[testing,test]
+commands =
+ coverage erase
+ coverage run -m pytest tests {posargs}
+ coverage combine
+ coverage html
+ coverage report -m --fail-under=91
+
+[flake8]
+ignore =
+ # Incompatible with Black.
+ E203,
+ W503
+
+[isort]
+known_first_party = pygettextpo
+line_length = 79
+profile = black
\ No newline at end of file