[sdk/pology/python3] /: CMake: Python 2 → Python 3, fix recent issues

Adrián Chaves null at kde.org
Thu Oct 6 14:14:18 BST 2022


Git commit 03e516053ae98f233fe7e37cdc078e86995e340d by Adrián Chaves.
Committed on 06/10/2022 at 13:14.
Pushed by adrianchavesfernandez into branch 'python3'.

CMake: Python 2 → Python 3, fix recent issues

M  +8    -9    CMakeLists.txt
M  +5    -5    cmake/FindPology.cmake
D  +0    -56   cmake/FindPython2.cmake
A  +56   -0    cmake/FindPython3.cmake
M  +3    -3    cmake/PologyTools.cmake
R  +6    -6    cmake/Python3Tools.cmake [from: cmake/Python2Tools.cmake - 084% similarity]
M  +17   -19   doc/user/programming.docbook
M  +5    -4    pology/CMakeLists.txt
M  +2    -2    pology/__init__.py
M  +50   -13   pology/lang/es/compare_with_original.py
M  +3    -3    pology/lang/es/rules/spelling.rules
M  +3    -3    pology/lang/es/scripts/createProperWordsDict.py
M  +11   -11   pology/lang/es/sieve/setUbsp.py
M  +2    -2    pology/lang/ko/language.py
M  +1    -1    pology/lang/sr/charsets.py
M  +1    -1    pology/lang/sr/doc/trapnakron.docbook
M  +1    -1    pology/lang/sr/trapnakron.py
A  +11   -0    pology/spec/CMakeLists.txt
M  +1    -1    util/release-checklist.txt

https://invent.kde.org/sdk/pology/commit/03e516053ae98f233fe7e37cdc078e86995e340d

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 83f211d3..baa06a1f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.3)
+cmake_minimum_required(VERSION 2.8.12)
 
 ###
 ### Set project.
@@ -6,12 +6,14 @@ cmake_minimum_required(VERSION 2.8.3)
 
 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
 
-set(PROJECT_NAME "pology")
 file(READ "VERSION" version)
 string(REPLACE "\n" "" version "${version}")
+
+set(PROJECT_NAME "pology")
 set(PROJECT_VERSION "${version}")
-message(STATUS "Configuring ${PROJECT_NAME} ${PROJECT_VERSION}")
-project(${PROJECT_NAME} NONE)
+
+cmake_policy(SET CMP0048 NEW)
+project(${PROJECT_NAME} VERSION "${version}")
 
 if(NOT cmake_install_prefix_cached)
     if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
@@ -25,7 +27,7 @@ endif()
 set(cmake_install_prefix_cached ${CMAKE_INSTALL_PREFIX}
     CACHE INTERNAL "Cache stamp for CMAKE_INSTALL_PREFIX.")
 
-find_package(Python2 2.5 REQUIRED)
+find_package(Python3 3.7 REQUIRED)
 find_package(DocbookXSL 1.75.2)
 find_package(LibXml2)
 find_package(Xsltproc)
@@ -81,15 +83,12 @@ include(EpydocTools)
 include(GettextTools)
 include(PologyTools)
 include(ProjectTools)
-include(Python2Tools)
+include(Python3Tools)
 
 # Include subdirectories.
 add_subdirectory(pology)
 add_subdirectory(scripts)
-add_subdirectory(sieve)
-add_subdirectory(lang)
 add_subdirectory(doc)
-add_subdirectory(spec)
 add_subdirectory(completion)
 add_subdirectory(syntax)
 add_subdirectory(po)
diff --git a/cmake/FindPology.cmake b/cmake/FindPology.cmake
index a2276da3..d5c50a3f 100644
--- a/cmake/FindPology.cmake
+++ b/cmake/FindPology.cmake
@@ -20,21 +20,21 @@ import sys, pology
 sys.stdout.write(pology.datadir())
 ")
 
-if(NOT PYTHON2_EXECUTABLE)
-    find_package(Python2 2.5)
+if(NOT PYTHON3_EXECUTABLE)
+    find_package(Python3 3.7)
 endif()
 
 message(STATUS "Looking for Pology Python library...")
-execute_process(COMMAND ${PYTHON2_EXECUTABLE} -B ${pl_import_script}
+execute_process(COMMAND ${PYTHON3_EXECUTABLE} -B ${pl_import_script}
                 OUTPUT_VARIABLE POLOGY_LIB_DIR)
 
 if(POLOGY_LIB_DIR)
-    execute_process(COMMAND ${PYTHON2_EXECUTABLE} -B ${pl_version_script}
+    execute_process(COMMAND ${PYTHON3_EXECUTABLE} -B ${pl_version_script}
                     OUTPUT_VARIABLE POLOGY_VERSION)
 
     if(NOT POLOGY_DATA_DIR)
         message(STATUS "Looking for Pology data directory...")
-        execute_process(COMMAND ${PYTHON2_EXECUTABLE} -B ${pl_datadir_script}
+        execute_process(COMMAND ${PYTHON3_EXECUTABLE} -B ${pl_datadir_script}
                         OUTPUT_VARIABLE POLOGY_DATA_DIR)
         if(POLOGY_DATA_DIR)
             message(STATUS
diff --git a/cmake/FindPython2.cmake b/cmake/FindPython2.cmake
deleted file mode 100644
index a9249244..00000000
--- a/cmake/FindPython2.cmake
+++ /dev/null
@@ -1,56 +0,0 @@
-# TODO: Add doc comments.
-
-include(FindPackageHandleStandardArgs)
-
-set(py_version_script ${CMAKE_BINARY_DIR}/python3_version.py)
-file(WRITE ${py_version_script} "
-import sys
-sys.stdout.write('.'.join(map(str, sys.version_info[:3])))
-")
-
-set(py_pkgdir_script ${CMAKE_BINARY_DIR}/python3_pkgdir.py)
-file(WRITE ${py_pkgdir_script} "
-import sys, distutils.sysconfig
-sys.stdout.write(distutils.sysconfig.get_python_lib())
-")
-
-if(NOT PYTHON2_EXECUTABLE)
-    find_program(PYTHON2_EXECUTABLE NAMES python3 python)
-    message(STATUS
-        "Looking for Python 2 executable "
-        "(use -DPYTHON2_EXECUTABLE= to set manually)...")
-else()
-    if(NOT EXISTS ${PYTHON2_EXECUTABLE})
-        set(PYTHON2_EXECUTABLE no)
-    endif()
-endif()
-
-if(PYTHON2_EXECUTABLE)
-    execute_process(COMMAND ${PYTHON2_EXECUTABLE} ${py_version_script}
-                    OUTPUT_VARIABLE PYTHON2_VERSION)
-
-    if(NOT PYTHON2_PACKAGES_DIR)
-        set(foo ${CMAKE_CURRENT_LIST_DIR})
-        message(STATUS
-            "Looking for Python 2 packages directory "
-            "(use -DPYTHON2_PACKAGES_DIR= to set manually)...")
-        execute_process(COMMAND ${PYTHON2_EXECUTABLE} ${py_pkgdir_script}
-                        OUTPUT_VARIABLE PYTHON2_PACKAGES_DIR)
-        if(PYTHON2_PACKAGES_DIR)
-            message(STATUS
-                "Found Python 2 packages directory: ${PYTHON2_PACKAGES_DIR}")
-        endif()
-    else()
-        if(NOT IS_DIRECTORY ${PYTHON2_PACKAGES_DIR})
-            set(PYTHON2_PACKAGES_DIR no)
-        endif()
-    endif()
-
-    set(PYTHON2_PACKAGES_DIR ${PYTHON2_PACKAGES_DIR}
-        CACHE PATH "Python 2 packages directory.")
-endif()
-
-find_package_handle_standard_args(Python2
-    REQUIRED_VARS PYTHON2_EXECUTABLE PYTHON2_PACKAGES_DIR
-    VERSION_VAR PYTHON2_VERSION
-)
diff --git a/cmake/FindPython3.cmake b/cmake/FindPython3.cmake
new file mode 100644
index 00000000..a44f5b62
--- /dev/null
+++ b/cmake/FindPython3.cmake
@@ -0,0 +1,56 @@
+# TODO: Add doc comments.
+
+include(FindPackageHandleStandardArgs)
+
+set(py_version_script ${CMAKE_BINARY_DIR}/python3_version.py)
+file(WRITE ${py_version_script} "
+import sys
+sys.stdout.write('.'.join(map(str, sys.version_info[:3])))
+")
+
+set(py_pkgdir_script ${CMAKE_BINARY_DIR}/python3_pkgdir.py)
+file(WRITE ${py_pkgdir_script} "
+import sys, distutils.sysconfig
+sys.stdout.write(distutils.sysconfig.get_python_lib())
+")
+
+if(NOT PYTHON3_EXECUTABLE)
+    find_program(PYTHON3_EXECUTABLE NAMES python3 python)
+    message(STATUS
+        "Looking for Python 3 executable "
+        "(use -DPYTHON3_EXECUTABLE= to set manually)...")
+else()
+    if(NOT EXISTS ${PYTHON3_EXECUTABLE})
+        set(PYTHON3_EXECUTABLE no)
+    endif()
+endif()
+
+if(PYTHON3_EXECUTABLE)
+    execute_process(COMMAND ${PYTHON3_EXECUTABLE} ${py_version_script}
+                    OUTPUT_VARIABLE PYTHON3_VERSION)
+
+    if(NOT PYTHON3_PACKAGES_DIR)
+        set(foo ${CMAKE_CURRENT_LIST_DIR})
+        message(STATUS
+            "Looking for Python 3 packages directory "
+            "(use -DPYTHON3_PACKAGES_DIR= to set manually)...")
+        execute_process(COMMAND ${PYTHON3_EXECUTABLE} ${py_pkgdir_script}
+                        OUTPUT_VARIABLE PYTHON3_PACKAGES_DIR)
+        if(PYTHON3_PACKAGES_DIR)
+            message(STATUS
+                "Found Python 3 packages directory: ${PYTHON3_PACKAGES_DIR}")
+        endif()
+    else()
+        if(NOT IS_DIRECTORY ${PYTHON3_PACKAGES_DIR})
+            set(PYTHON3_PACKAGES_DIR no)
+        endif()
+    endif()
+
+    set(PYTHON3_PACKAGES_DIR ${PYTHON3_PACKAGES_DIR}
+        CACHE PATH "Python 3 packages directory.")
+endif()
+
+find_package_handle_standard_args(Python3
+    REQUIRED_VARS PYTHON3_EXECUTABLE PYTHON3_PACKAGES_DIR
+    VERSION_VAR PYTHON3_VERSION
+)
diff --git a/cmake/PologyTools.cmake b/cmake/PologyTools.cmake
index e98e380d..5377f26e 100644
--- a/cmake/PologyTools.cmake
+++ b/cmake/PologyTools.cmake
@@ -20,8 +20,8 @@ pology.synder.compile_file(sdfile, sdcfile, doraise=True)
 macro(INSTALL_SYNDER_FILES instdir)
     set(sdfiles ${ARGN})
 
-    if(NOT PYTHON2_EXECUTABLE)
-        message(FATAL_ERROR "PYTHON2_EXECUTABLE is not set.")
+    if(NOT PYTHON3_EXECUTABLE)
+        message(FATAL_ERROR "PYTHON3_EXECUTABLE is not set.")
     endif()
 
     string(REPLACE ${CMAKE_SOURCE_DIR}/ "" srcsubdir
@@ -40,7 +40,7 @@ macro(INSTALL_SYNDER_FILES instdir)
             set(sdcfile ${sdfile}c)
         endif()
         add_custom_command(OUTPUT ${sdcfile}
-                           COMMAND ${PYTHON2_EXECUTABLE} -B ${pl_compsyn_script}
+                           COMMAND ${PYTHON3_EXECUTABLE} -B ${pl_compsyn_script}
                                    ${sdfile} ${sdcfile}
                            DEPENDS ${sdfile})
         set(sdcfiles ${sdcfiles} ${sdcfile})
diff --git a/cmake/Python2Tools.cmake b/cmake/Python3Tools.cmake
similarity index 84%
rename from cmake/Python2Tools.cmake
rename to cmake/Python3Tools.cmake
index b2cd6cc7..3784a266 100644
--- a/cmake/Python2Tools.cmake
+++ b/cmake/Python3Tools.cmake
@@ -1,7 +1,7 @@
 # TODO: Add doc comments for all this stuff.
 
-if(NOT PYTHON2_EXECUTABLE)
-    find_package(Python2 2)
+if(NOT PYTHON3_EXECUTABLE)
+    find_package(Python3)
 endif()
 
 if(NOT py2t_target_count)
@@ -17,16 +17,16 @@ py_compile.compile(pyfile, pycfile, doraise=True)
 ")
 
 
-macro(INSTALL_PYTHON2_MODULE_FILES pkgdirpath)
+macro(INSTALL_PYTHON3_MODULE_FILES pkgdirpath)
     set(pyfiles ${ARGN})
 
     if(IS_ABSOLUTE pkgdirpath)
         message(FATAL_ERROR
             "Installation directory for Python modules must be "
-            "a relative path (subdirectory of PYTHON2_PACKAGES_DIR).")
+            "a relative path (subdirectory of PYTHON3_PACKAGES_DIR).")
     endif()
 
-    set(instdir ${PYTHON2_PACKAGES_DIR}/${pkgdirpath})
+    set(instdir ${PYTHON3_PACKAGES_DIR}/${pkgdirpath})
 
     string(REPLACE ${CMAKE_SOURCE_DIR}/ "" srcsubdir
                    ${CMAKE_CURRENT_SOURCE_DIR})
@@ -44,7 +44,7 @@ macro(INSTALL_PYTHON2_MODULE_FILES pkgdirpath)
             set(pycfile ${pyfile}c)
         endif()
         add_custom_command(OUTPUT ${pycfile}
-                           COMMAND ${PYTHON2_EXECUTABLE} ${py_compfile_script}
+                           COMMAND ${PYTHON3_EXECUTABLE} ${py_compfile_script}
                                    ${pyfile} ${pycfile}
                            DEPENDS ${pyfile})
         set(pycfiles ${pycfiles} ${pycfile})
diff --git a/doc/user/programming.docbook b/doc/user/programming.docbook
index df6857cd..b5ff2e46 100644
--- a/doc/user/programming.docbook
+++ b/doc/user/programming.docbook
@@ -33,12 +33,12 @@
 <para>To take a <classname>Monlist</classname> instance as an example, here is how it behaves on its own:
 <programlisting language="python">
 >>> from pology.monitored import Monlist
->>> l = Monlist([u"a", u"b", u"c"])
+>>> l = Monlist(["a", "b", "c"])
 >>> l.modcount
 0
 >>> l.append(10)
 >>> l
-Monlist([u"a", u"b", u"c", 10])
+Monlist(["a", "b", "c", 10])
 >>> l.modcount
 1
 >>>
@@ -53,41 +53,39 @@ Monlist([])
 Traceback (most recent call last):
 ...
 pology.PologyError: Expected <type 'unicode'> for sequence element, got <type 'int'>.
->>> msg.msgstr.append(u"bar")
+>>> msg.msgstr.append("bar")
 >>> msg.msgstr.modcount
 1
 >>> msg.modcount
 1
 </programlisting>
-The <classname>Message</classname> class has type constraints added to its attributes, and therefore addition of an integer to the <varname>.msgstr</varname> list was rejected: only <type>unicode</type> values are allowed. This is particularly important due to the basic string type in Python being the raw byte array <type>str</type><footnote>
-<para>In Python 2 to be precise, on which Pology is based, while in Python 3 there are only Unicode strings.</para>
-</footnote>, to automatically prevent carelessness with encodings. Once a proper string was added to <varname>.msgstr</varname> list, its modification counter increased, but also the modification counter of the parent object.</para>
+The <classname>Message</classname> class has type constraints added to its attributes, and therefore addition of an integer to the <varname>.msgstr</varname> list was rejected: only <type>str</type> values are allowed, to prevent carelessness with encodings. Once a proper string was added to <varname>.msgstr</varname> list, its modification counter increased, but also the modification counter of the parent object.</para>
 
 <para>A few more notes on modification counters. Consider this example:
 <programlisting language="python">
 >>> msg = Message()
->>> msg.msgstr = Monlist(u"foo")
+>>> msg.msgstr = Monlist("foo")
 >>> msg.msgstr.modcount
 0
 >>> msg.msgstr_modcount
 1
 >>> msg.modcount
 1
->>> msg.msgstr[0] = u"foo"
+>>> msg.msgstr[0] = "foo"
 >>> msg.msgstr.modcount
 0
->>> msg.msgstr = Monlist(u"foo")
+>>> msg.msgstr = Monlist("foo")
 >>> msg.msgstr_modcount
 1
 >>> msg.modcount
 1
 </programlisting>
-<literal>Monlist(u"foo")</literal> itself is a fresh list with modification counter at 0, so after it was assigned to <varname>msg.msgstr</varname>, its modification counter is still 0. However, every attribute of a parent monitored object also has the associated <emphasis>attribute</emphasis> modification counter, denoted with trailing <literal>_modcount</literal>; therefore <varname>msg.msgstr_modcount</varname> did increase on assignment, and so did the parent <varname>msg.modcount</varname>. Modification tracking actually checks for equality of values, so when same-valued objects are repeadetly assigned (starting from <literal>msg.msgstr[0] = u"foo"</literal> above), modification counters do not increase.</para>
+<literal>Monlist("foo")</literal> itself is a fresh list with modification counter at 0, so after it was assigned to <varname>msg.msgstr</varname>, its modification counter is still 0. However, every attribute of a parent monitored object also has the associated <emphasis>attribute</emphasis> modification counter, denoted with trailing <literal>_modcount</literal>; therefore <varname>msg.msgstr_modcount</varname> did increase on assignment, and so did the parent <varname>msg.modcount</varname>. Modification tracking actually checks for equality of values, so when same-valued objects are repeadetly assigned (starting from <literal>msg.msgstr[0] = "foo"</literal> above), modification counters do not increase.</para>
 
 <para>Compound monitored objects may also have the attributes themselves constrained, to prevent typos and other brain glitches from causing mysterious wrong behavior when processing PO files. For example:
 <programlisting language="python">
 >>> msg = Message()
->>> msg.msgtsr = Monlist(u"foo")
+>>> msg.msgtsr = Monlist("foo")
 Traceback (most recent call last):
 ...
 pology.PologyError: Attribute 'msgtsr' is not among specified.
@@ -107,9 +105,9 @@ pology.PologyError: Attribute 'msgtsr' is not among specified.
 >>> from pology.monitored import Monpair
 >>> from pology.message import Message
 >>> msg = Message()
->>> msg.msgid = u"Foo %s"
->>> msg.msgstr.append(u"Bar %s")
->>> msg.flag.add(u"c-format")
+>>> msg.msgid = "Foo %s"
+>>> msg.msgstr.append("Bar %s")
+>>> msg.flag.add("c-format")
 >>> msg.fuzzy = True
 >>> print msg.to_string(),
 #, fuzzy, c-format
@@ -126,7 +124,7 @@ Attribute access provides the least hassle, while being guarded by monitoring, a
 
 <para>There are also several derived, read-only attributes for special purposes. For example, if in some context the messages are to be tracked in a dictionary by their keys, there is the <varname>.key</varname> attribute available, which is an undefined but unique combination of <varname>.msgctxt</varname> and <varname>.msgid</varname> attributes. Or, there is the <varname>.active</varname> attribute which is <literal>True</literal> if the message is neither fuzzy nor obsolete, i.e. its translation (if there is one) would be used by the consumer of the PO file that the message is part of.</para>
 
-<para><classname>Message</classname> has a number of methods for frequent operations that need to read or modify more than one attribute. For example, to thoroughly unfuzzy a message, it is not sufficient to just remove its fuzzy flag (by setting <varname>.fuzzy</varname> to <literal>False</literal> or removing <literal>u"fuzzy"</literal> from <varname>.flag</varname> set), but previous field comments (<literal>#| ...</literal>) should be removed as well, and this is what <function>.unfuzzy()</function> method does:
+<para><classname>Message</classname> has a number of methods for frequent operations that need to read or modify more than one attribute. For example, to thoroughly unfuzzy a message, it is not sufficient to just remove its fuzzy flag (by setting <varname>.fuzzy</varname> to <literal>False</literal> or removing <literal>"fuzzy"</literal> from <varname>.flag</varname> set), but previous field comments (<literal>#| ...</literal>) should be removed as well, and this is what <function>.unfuzzy()</function> method does:
 <programlisting language="python">
 >>> print msg.to_string(),
 #| msgid "Foubar"
@@ -148,10 +146,10 @@ Other methods include those to copy over a subset of parts from another message,
 <programlisting language="python">
 def translate_moo_as_mu (msg):
 
-    if msg.msgid == u"Moo!":  # works for both
-        msg.msgstr = [u"Mu!"]  # raises exception if Message
-        msg.msgstr[:] = [u"Mu!"]  # works for both
-        msg.msgstr[0] = u"Mu!"  # works for both (when not empty)
+    if msg.msgid == "Moo!":  # works for both
+        msg.msgstr = ["Mu!"]  # raises exception if Message
+        msg.msgstr[:] = ["Mu!"]  # works for both
+        msg.msgstr[0] = "Mu!"  # works for both (when not empty)
 </programlisting>
 If you need to create an empty message of the same type as another message, or make a same-type copy of the message, you can use <function>type</function> built-in:
 <programlisting language="python">
diff --git a/pology/CMakeLists.txt b/pology/CMakeLists.txt
index a6f22d41..a871fdde 100644
--- a/pology/CMakeLists.txt
+++ b/pology/CMakeLists.txt
@@ -33,7 +33,6 @@ set(modules
     report.py
     resolve.py
     rules.py
-    sieve.py
     spell.py
     split.py
     stdcmdopt.py
@@ -48,7 +47,9 @@ set(modules
 get_current_source_subdir(srcsubdir)
 install_python3_module_files(${srcsubdir} ${modules})
 
-add_subdirectory(proj)
-add_subdirectory(lang)
-add_subdirectory(internal)
 add_subdirectory(external)
+add_subdirectory(internal)
+add_subdirectory(lang)
+add_subdirectory(proj)
+add_subdirectory(sieve)
+add_subdirectory(spec)
diff --git a/pology/__init__.py b/pology/__init__.py
index e2cb8cdf..48ff038f 100644
--- a/pology/__init__.py
+++ b/pology/__init__.py
@@ -57,7 +57,7 @@ def localedir ():
     @rtype: string
     """
 
-    localedir = "@CONFIG_LOCALEDIR@" # configured if installed
+    localedir = "/usr/local/share/locale" # configured if installed
     if not os.path.isdir(localedir): # if running from source dir
         srcdir = os.path.dirname(os.path.dirname(__file__))
         localedir = os.path.join(srcdir, "mo")
@@ -72,7 +72,7 @@ def version ():
     @rtype: string
     """
 
-    verstr = "@CONFIG_VERSION@" # configured if installed
+    verstr = "0.13" # configured if installed
     if verstr.startswith("@"): # if running from source dir
         try:
             verfile = os.path.join(datadir(), "VERSION")
diff --git a/pology/lang/es/compare_with_original.py b/pology/lang/es/compare_with_original.py
index e966d640..9c15071c 100644
--- a/pology/lang/es/compare_with_original.py
+++ b/pology/lang/es/compare_with_original.py
@@ -50,7 +50,7 @@ def test_if_purepunc (msg, cat):
 
 	for i in range(len(msg.msgstr)):
 		msgstr = msg.msgstr[i]
-                if i > 0:
+		if i > 0:
 			msgid = msg.msgid_plural
 		else:
 			msgid = msg.msgid
@@ -65,7 +65,7 @@ def test_if_purepunc (msg, cat):
 			msgstr = msgstr.replace("»", "")
 			msgstr = msgstr.replace(" ", "")
 			msgstr = msgstr.replace("\"", "")
-			if msgid != msgstr:    
+			if msgid != msgstr:
 				return [("msgstr", 0, [(0, 0, 'Se ha traducido un texto no alfanumérico')])]
 
 	return []
@@ -91,10 +91,47 @@ def test_if_non_printable_characters (msg, cat):
 	else:
 	    msgid = msg.msgid
 	for c in msgstr:
-	    if (c not in string.printable) and (c not in msgid) and (c not in "áéíóúüñçÁÉÍÓÚÜÑÇ¿¡|«»©ºª€/"):
-			return [("msgstr", 0, [(0, 0, 'La traducción contiene caracteres no imprimibles')])]
-	    elif (c in string.punctuation) and (c not in msgid) and (c not in "¿¡|«»©ºª€/.,;:()_-"):
-			return [("msgstr", 0, [(0, 0, 'La traducción contiene signos de puntuación no incluidos en el original')])]
+		if (
+			(c not in string.printable)
+			and (c not in msgid)
+			and (c not in "áéíóúüñçÁÉÍÓÚÜÑÇ¿¡|«»©ºª€/")
+		):
+			return [
+				(
+					"msgstr",
+					0,
+					[
+						(
+							0,
+							0,
+							(
+								'La traducción contiene caracteres no ' 'imprimibles'
+							)
+						)
+					]
+				)
+			]
+		elif (
+			(c in string.punctuation)
+			and (c not in msgid)
+			and (c not in "¿¡|«»©ºª€/.,;:()_-")
+		):
+			return [
+				(
+					"msgstr",
+					0,
+					[
+						(
+							0,
+							0,
+							(
+								'La traducción contiene signos de puntuación '
+								'no incluidos en el original'
+							)
+						)
+					]
+				)
+			]
 	return []
 
 def test_if_very_long_translation (msg, cat):
@@ -161,7 +198,7 @@ def test_if_not_translated (msg, cat):
 	[type V4A hook].
 	@return: parts
 	"""
-	
+
 	if msg.msgctxt in ("EMAIL OF TRANSLATORS", "NAME OF TRANSLATORS", "ROLES OF TRANSLATORS"):
 		return []
 
@@ -173,14 +210,14 @@ def test_if_not_translated (msg, cat):
 			msgid = msg.msgid_plural
 		else:
 			msgid = msg.msgid
-			
+
 		if _proper_name.match(msg.msgstr[i]) or _purepunc.match(msgid):
 			continue
 
-                e = None
-                l = None
+		e = None
+		l = None
 		if len(msgid) > 0 and msgid == msg.msgstr[i]:
-			 for word in split.proper_words(msgid, markup=True, accels=['&']):
+			for word in split.proper_words(msgid, markup=True, accels=['&']):
 				if _valid_word.match(word) and not _capital_word.match(word):
 					word = word.encode("utf-8")
 					if e is None:
@@ -344,10 +381,10 @@ def test_paired_numbers (msg, cat):
 	"""
 	if msg.msgctxt in ("EMAIL OF TRANSLATORS", "NAME OF TRANSLATORS", "ROLES OF TRANSLATORS"):
 		return []
- 
+
 	if msg.msgid in ("Your emails", "Your names", "CREDIT_FOR_TRANSLATORS", "ROLES_OF_TRANSLATORS"):
 		return []
-   
+
 	for i in range(len(msg.msgstr)):
 		if i > 0:
 			msgid = msg.msgid_plural
diff --git a/pology/lang/es/rules/spelling.rules b/pology/lang/es/rules/spelling.rules
index 6a1f37d8..e4f256ea 100644
--- a/pology/lang/es/rules/spelling.rules
+++ b/pology/lang/es/rules/spelling.rules
@@ -64,9 +64,9 @@ addFilterRegex match="(?<=\w)\'(?=\w)" repl="" on="pmsgid,pmsgstr"
 addFilterRegex match="(?u)(?<=\w)\.(?=\s[A-Z])" repl="" casesens="yes" on="pmsgid,pmsgstr"
 
 # Omit some Spanish sufixes and prefixes
-#addFilterRegex match=u"(?u)(?<=\w)(mente|lo|la|le|los|las|les)\b" repl="" on="pmsgid,pmsgstr"
-#addFilterRegex match=u"(?u)(?<=\w)(ando|ación|ble|bles)\b" repl="r" on="pmsgid,pmsgstr"
-#addFilterRegex match=u"(?u)\b(anti|archi|auto|contra|cuasi|des|epi|eqi|ex|extra|foto|geo|h[ií]per|infra|inter|intra|macro|maxi|mega|meta|micro|mini|mono|multi|peri|pluri|poli|pos|post|pre|pro|retro|semi|seudo|sobre|sub|s[uú]per|supra|tele|trans|ultra|vice)(?=\w+\b)" repl="" on="pmsgid,pmsgstr"
+#addFilterRegex match="(?u)(?<=\w)(mente|lo|la|le|los|las|les)\b" repl="" on="pmsgid,pmsgstr"
+#addFilterRegex match="(?u)(?<=\w)(ando|ación|ble|bles)\b" repl="r" on="pmsgid,pmsgstr"
+#addFilterRegex match="(?u)\b(anti|archi|auto|contra|cuasi|des|epi|eqi|ex|extra|foto|geo|h[ií]per|infra|inter|intra|macro|maxi|mega|meta|micro|mini|mono|multi|peri|pluri|poli|pos|post|pre|pro|retro|semi|seudo|sobre|sub|s[uú]per|supra|tele|trans|ultra|vice)(?=\w+\b)" repl="" on="pmsgid,pmsgstr"
 
 # Omit paired capitalized words.
 addFilterHook name="es:remove_subs/remove_original_capital_words" on="msg"
diff --git a/pology/lang/es/scripts/createProperWordsDict.py b/pology/lang/es/scripts/createProperWordsDict.py
index 6939df75..cae3c8f7 100755
--- a/pology/lang/es/scripts/createProperWordsDict.py
+++ b/pology/lang/es/scripts/createProperWordsDict.py
@@ -34,9 +34,9 @@ def _main ():
 	desc = _("@info command description",
 		"Obtains a list of proper words from the message text ")
 	ver = _("@info command version",
-		u"%(cmd)s (Pology) %(version)s\n"
-		u"Copyright ©  2011 "
-		u"Javier Viñal <%(email)s>",
+		"%(cmd)s (Pology) %(version)s\n"
+		"Copyright ©  2011 "
+		"Javier Viñal <%(email)s>",
 		cmd="%prog", version=version(), email="fjvinal at gmail.com")
 
 	opars = ColorOptionParser(usage=usage, description=desc, version=ver)
diff --git a/pology/lang/es/sieve/setUbsp.py b/pology/lang/es/sieve/setUbsp.py
index 1f775be9..468a5ee8 100644
--- a/pology/lang/es/sieve/setUbsp.py
+++ b/pology/lang/es/sieve/setUbsp.py
@@ -37,15 +37,15 @@ class Sieve (object):
 
     def setUbsp(self, text):
         """Set correctly unbreakable spaces"""
-        text=text.replace(u"\xa0", u" ")
-        text=text.replace(u" :", u"\xc2\xa0:")
-        text=text.replace(u" :", u"\xa0:")
-        text=text.replace(u" ;", u"\xa0;")
-        text=text.replace(u" ?", u"\xa0?")
-        text=text.replace(u" !", u"\xa0!")
-        text=text.replace(u"« ", u"«\xa0")
-        text=text.replace(u" »", u"\xa0»")
-        text=text.replace(u" / ", u"\xa0/ ")
-        text=self.percent.sub(u"\xa0%", text)
-        
+        text=text.replace("\xa0", " ")
+        text=text.replace(" :", "\xc2\xa0:")
+        text=text.replace(" :", "\xa0:")
+        text=text.replace(" ;", "\xa0;")
+        text=text.replace(" ?", "\xa0?")
+        text=text.replace(" !", "\xa0!")
+        text=text.replace("« ", "«\xa0")
+        text=text.replace(" »", "\xa0»")
+        text=text.replace(" / ", "\xa0/ ")
+        text=self.percent.sub("\xa0%", text)
+
         return text
diff --git a/pology/lang/ko/language.py b/pology/lang/ko/language.py
index 2911d0c1..1619eca4 100644
--- a/pology/lang/ko/language.py
+++ b/pology/lang/ko/language.py
@@ -38,7 +38,7 @@ def redundant_plural (msgstr, msg, cat):
     @rtype: C{(msgstr, msg, cat) -> spans}
     """
 
-    return check(PLURAL_R, PLURAL_EXCLUDE, msgstr, msg, cat, u"Unnecessary plural '%(match)s'.")
+    return check(PLURAL_R, PLURAL_EXCLUDE, msgstr, msg, cat, "Unnecessary plural '%(match)s'.")
 
 SYLLABLE_WITH_T_RIEUL = '[%s]' % ''.join([chr(c) for c in
                                           range(0xAC00 + 8, 0xD7A4, 28)])
@@ -67,6 +67,6 @@ def check(r, exclude, msgstr, msg, cat, errmsg):
         p1, p2 = m.span()
         if exclude and exclude.match(msgstr[p1:p2].strip()):
             continue
-        spans.append((p1, p2, _(u"@info", errmsg, match=msgstr[p1:p2].strip())))
+        spans.append((p1, p2, _("@info", errmsg, match=msgstr[p1:p2].strip())))
 
     return spans
diff --git a/pology/lang/sr/charsets.py b/pology/lang/sr/charsets.py
index d3abcaca..b47f78e4 100644
--- a/pology/lang/sr/charsets.py
+++ b/pology/lang/sr/charsets.py
@@ -55,7 +55,7 @@ translit_ascii = {
     "ö": "oe",
     "ü": "ue",
     # TODO: Add more.
-    #u"": "",
+    #"": "",
 }
 
 
diff --git a/pology/lang/sr/doc/trapnakron.docbook b/pology/lang/sr/doc/trapnakron.docbook
index 5a75b884..24b6cb20 100644
--- a/pology/lang/sr/doc/trapnakron.docbook
+++ b/pology/lang/sr/doc/trapnakron.docbook
@@ -54,7 +54,7 @@ $ python
 >>> from pology.l10n.sr.trapnakron import trapnakron_plain
 >>> from pology.misc.resolve import resolve_entities_simple
 >>> t = trapnakron_plain()
->>> s = u"…на предлог &tsienhsueshen-g;, оца кинеског ракетног програма…"
+>>> s = "…на предлог &tsienhsueshen-g;, оца кинеског ракетног програма…"
 >>> print resolve_entities_simple(s, t)
 …на предлог Ћена Сјуесена, оца кинеског ракетног програма,…
 </programlisting>
diff --git a/pology/lang/sr/trapnakron.py b/pology/lang/sr/trapnakron.py
index d0a6ba96..bbe153ad 100644
--- a/pology/lang/sr/trapnakron.py
+++ b/pology/lang/sr/trapnakron.py
@@ -54,7 +54,7 @@ to readers), using a script based on these few lines::
     >>> from pology.resolve import resolve_entities_simple as resents
     >>> tp = trapnakron_plain()
     >>>
-    >>> s = u"...пројектовању ракета &qianxuesen-g; привукле су идеје..."
+    >>> s = "...пројектовању ракета &qianxuesen-g; привукле су идеје..."
     >>> print resents(s, tp)
     ...пројектовању ракета Ћена Сјуесена привукле су идеје...
     >>>
diff --git a/pology/spec/CMakeLists.txt b/pology/spec/CMakeLists.txt
new file mode 100644
index 00000000..1f8f9901
--- /dev/null
+++ b/pology/spec/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(files
+    docbook4.l1
+    html.entities
+    html.l1
+    kuit.l1
+    kuit.entities
+    pango.l1
+    qtrich.l1
+)
+get_current_source_subdir(srcsubdir)
+install(FILES ${files} DESTINATION ${DATA_INSTALL_DIR}/${srcsubdir})
diff --git a/util/release-checklist.txt b/util/release-checklist.txt
index b121fd47..bf986394 100644
--- a/util/release-checklist.txt
+++ b/util/release-checklist.txt
@@ -39,7 +39,7 @@
 
     cd /tmp/pology-$version
     mkdir build && cd build
-    cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/pology-$version-inst -DPYTHON2_PACKAGES_DIR=/tmp/pology-$version-inst/lib/python/dist-packages
+    cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/pology-$version-inst -DPYTHON3_PACKAGES_DIR=/tmp/pology-$version-inst/lib/python/dist-packages
     make && make install
 
   on errors: fix, commit, merge to trunk, go back to tarball creation or earlier.


More information about the kde-doc-english mailing list