From 8d717274de2ee73a35863b5a132133a3104ed602 Mon Sep 17 00:00:00 2001 From: Luis Gamez Date: Mon, 18 Mar 2024 12:04:10 -0600 Subject: [PATCH 1/2] code updated to work with python 3 --- inflector.py | 4 ++-- rules/base.py | 2 +- rules/english.py | 4 ++-- rules/spanish.py | 41 +++++++++++++++++++---------------------- tests.py | 4 ++-- tests_es.py | 4 ++-- utils.py | 25 +++++++++++++++++-------- 7 files changed, 45 insertions(+), 39 deletions(-) diff --git a/inflector.py b/inflector.py index c9be1c8..6cca3ab 100644 --- a/inflector.py +++ b/inflector.py @@ -19,7 +19,7 @@ class Inflector: def __init__(self, Inflector=English): assert callable(Inflector), "Inflector should be a callable obj" - self.Inflector = apply(Inflector) + self.Inflector = Inflector() def pluralize(self, word): '''Pluralizes nouns.''' @@ -124,4 +124,4 @@ def foreignKey(self, class_name, separate_class_name_and_id_with_underscore=1): # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THIS SOFTWARE. +# THIS SOFTWARE. \ No newline at end of file diff --git a/rules/base.py b/rules/base.py index bf4d18a..f0ab44d 100644 --- a/rules/base.py +++ b/rules/base.py @@ -147,4 +147,4 @@ def foreignKey(self, class_name, separate_class_name_and_id_with_underscore=1): # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THIS SOFTWARE. +# THIS SOFTWARE. \ No newline at end of file diff --git a/rules/english.py b/rules/english.py index 42d1b2e..df64b9f 100644 --- a/rules/english.py +++ b/rules/english.py @@ -7,7 +7,7 @@ # (BSD-style). import re -from base import Base +from .base import Base class English (Base): @@ -158,4 +158,4 @@ def singularize(self, word): # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THIS SOFTWARE. +# THIS SOFTWARE. \ No newline at end of file diff --git a/rules/spanish.py b/rules/spanish.py index 2c9f283..3a0cc99 100644 --- a/rules/spanish.py +++ b/rules/spanish.py @@ -10,7 +10,7 @@ # (BSD-style). import re -from base import Base +from .base import Base import utils @@ -77,7 +77,7 @@ def pluralize(self, word): if lower_cased_word[-1 * len(uncountable_word):] == uncountable_word: return utils.deunicodify(word, origType) - for irregular_singular, irregular_plural in self.irregular_words.iteritems(): + for irregular_singular, irregular_plural in self.irregular_words.items(): match = re.search(u'(?i)(^' + irregular_singular + u')$', word, re.IGNORECASE) if match: result = re.sub(u'(?i)' + irregular_singular + u'$', match.expand(u'\\1')[0] + irregular_plural[1:], word) @@ -90,7 +90,7 @@ def pluralize(self, word): replacement = rule[1] if re.match(u'\|', replacement): for k in range(1, len(groups)): - replacement = replacement.replace(u'|' + unicode( + replacement = replacement.replace(u'|' + str( k), self.string_replace(groups[k - 1], u'ÁÉÍÓÚáéíóú', u'AEIOUaeiou')) result = re.sub(rule[0], replacement, word) @@ -117,19 +117,19 @@ def singularize(self, word): word, origType = utils.unicodify(word) # all internal calculations are done in Unicode rules = [ - [ur'(?i)^([bcdfghjklmnñpqrstvwxyz]*)([aeiou])([ns])es$', u'\\1\\2\\3'], - [ur'(?i)([aeiou])([ns])es$', u'~1\\2'], - [ur'(?i)shes$', u'sh'], # flashes->flash - [ur'(?i)oides$', u'oide'], # androides->androide - [ur'(?i)(sis|tis|xis)$', u'\\1'], # crisis, apendicitis, praxis - [ur'(?i)(é)s$', u'\\1'], # bebés->bebé - [ur'(?i)(ces)$', u'z'], # luces->luz - [ur'(?i)([^e])s$', u'\\1'], # casas->casa - [ur'(?i)([bcdfghjklmnñprstvwxyz]{2,}e)s$', u'\\1'], # cofres->cofre - [ur'(?i)([ghñptv]e)s$', u'\\1'], # llaves->llave, radiocasetes->radiocasete - [ur'(?i)jes$', u'je'], # ejes->eje - [ur'(?i)ques$', u'que'], # tanques->tanque - [ur'(?i)es$', u''] # ELSE remove _es_ monitores->monitor + [r'(?i)^([bcdfghjklmnñpqrstvwxyz]*)([aeiou])([ns])es$', u'\\1\\2\\3'], + [r'(?i)([aeiou])([ns])es$', r'~1\2'], + [r'(?i)shes$', u'sh'], # flashes->flash + [r'(?i)oides$', u'oide'], # androides->androide + [r'(?i)(sis|tis|xis)$', u'\\1'], # crisis, apendicitis, praxis + [r'(?i)(é)s$', u'\\1'], # bebés->bebé + [r'(?i)(ces)$', u'z'], # luces->luz + [r'(?i)([^e])s$', u'\\1'], # casas->casa + [r'(?i)([bcdfghjklmnñprstvwxyz]{2,}e)s$', u'\\1'], # cofres->cofre + [r'(?i)([ghñptv]e)s$', u'\\1'], # llaves->llave, radiocasetes->radiocasete + [r'(?i)jes$', u'je'], # ejes->eje + [r'(?i)ques$', u'que'], # tanques->tanque + [r'(?i)es$', u''] # ELSE remove _es_ monitores->monitor ] lower_cased_word = word.lower() @@ -138,7 +138,7 @@ def singularize(self, word): if lower_cased_word[-1 * len(uncountable_word):] == uncountable_word: return utils.deunicodify(word, origType) - for irregular_singular, irregular_plural in self.irregular_words.iteritems(): + for irregular_singular, irregular_plural in self.irregular_words.items(): match = re.search(u'(^' + irregular_plural + u')$', word, re.IGNORECASE) if match: result = re.sub(u'(?i)' + irregular_plural + u'$', match.expand(u'\\1')[0] + irregular_singular[1:], word) @@ -151,7 +151,7 @@ def singularize(self, word): replacement = rule[1] if re.match(u'~', replacement): for k in range(1, len(groups)): - replacement = replacement.replace(u'~' + unicode( + replacement = replacement.replace(u'~' + str( k), self.string_replace(groups[k - 1], u'AEIOUaeiou', u'ÁÉÍÓÚáéíóú')) result = re.sub(rule[0], replacement, word) @@ -166,8 +166,6 @@ def singularize(self, word): return utils.deunicodify(result, origType) return utils.deunicodify(word, origType) - - # Copyright (c) 2006 Bermi Ferrer Martinez # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software to deal in this software without restriction, including @@ -182,5 +180,4 @@ def singularize(self, word): # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THIS SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THIS SOFTWARE. - +# THIS SOFTWARE. \ No newline at end of file diff --git a/tests.py b/tests.py index fa897d6..a9ac6a9 100644 --- a/tests.py +++ b/tests.py @@ -113,14 +113,14 @@ def tearDown(self): self.inflector = None def test_pluralize(self): - for singular, plural in self.singular_to_plural.iteritems(): + for singular, plural in self.singular_to_plural.items(): inflector_pluralize = self.inflector.pluralize(singular) assert inflector_pluralize == plural, \ 'English Inflector pluralize(%s) should produce "%s" and NOT "%s"' % ( singular, plural, inflector_pluralize) def test_singularize(self): - for singular, plural in self.singular_to_plural.iteritems(): + for singular, plural in self.singular_to_plural.items(): inflector_singularize = self.inflector.singularize(plural) assert inflector_singularize == singular, \ 'English Inflector singularize(%s) should produce "%s" and NOT "%s"' % ( diff --git a/tests_es.py b/tests_es.py index 6f75030..c2b2d9b 100755 --- a/tests_es.py +++ b/tests_es.py @@ -68,14 +68,14 @@ def tearDown(self): self.inflector = None def test_pluralize(self): - for singular, plural in self.singular_to_plural.iteritems(): + for singular, plural in self.singular_to_plural.items(): inflector_pluralize = self.inflector.pluralize(singular) assert inflector_pluralize == plural, \ 'Spanish Inflector pluralize(%s) should produce "%s" and NOT "%s"' % ( singular, plural, inflector_pluralize) def test_singularize(self): - for singular, plural in self.singular_to_plural.iteritems(): + for singular, plural in self.singular_to_plural.items(): inflector_singularize = self.inflector.singularize(plural) assert inflector_singularize == singular, \ 'Spanish Inflector singularize(%s) should produce "%s" and NOT "%s"' % ( diff --git a/utils.py b/utils.py index e4f572e..19a22c1 100644 --- a/utils.py +++ b/utils.py @@ -10,15 +10,20 @@ def unicodify(st): @return a tuple with the unicodified string and the original string encoding. ''' - # Convert 'st' to Unicode - if isinstance(st, unicode): - origType = 'unicode' - elif isinstance(st, str): + import unicodedata + +def unicodify(st): + # Verificar si la cadena es de tipo str (Unicode en Python 3) + if isinstance(st, str): + origType = 'str' + elif isinstance(st, bytes): try: - st = st.decode('utf8') - origType = 'utf8' + # Decodificar la cadena de bytes a Unicode utilizando utf-8 + st = st.decode('utf-8') + origType = 'utf-8' except UnicodeDecodeError: try: + # Si falla la decodificación utf-8, intentar decodificarla utilizando latin-1 st = st.decode('latin1') origType = 'latin1' except: @@ -26,7 +31,7 @@ def unicodify(st): else: origType = 'noConversion' - # Normalize the Unicode (to combine any combining characters, e.g. accents, into the previous letter) + # Normalizar el Unicode (para combinar cualquier caracter que se combine, por ejemplo, acentos, en la letra anterior) if origType != 'noConversion': st = unicodedata.normalize('NFKC', st) @@ -40,5 +45,9 @@ def deunicodify(unicodifiedStr, origType): if origType == 'unicode': return unicodifiedStr + + # Si origType es 'str', simplemente devuelve la cadena sin codificarla nuevamente + if origType == 'str': + return unicodifiedStr - return unicodifiedStr.encode(origType) + return unicodifiedStr.encode(origType) \ No newline at end of file From cb0e98d4d2a32f0d20490026f8c6dfc070c22c36 Mon Sep 17 00:00:00 2001 From: Luis Gamez Date: Mon, 18 Mar 2024 16:36:38 -0600 Subject: [PATCH 2/2] fix folder structure --- .gitignore | 1 - BSD-LICENSE => LICENSE | 0 README.markdown => README.md | 0 __init__.py => app/__init__.py | 0 app/inflector/__init__.py | 2 ++ {rules => app/inflector/src}/__init__.py | 0 inflector.py => app/inflector/src/inflector.py | 10 +--------- app/inflector/src/rules/__init__.py | 0 {rules => app/inflector/src/rules}/base.py | 7 ------- {rules => app/inflector/src/rules}/english.py | 8 -------- {rules => app/inflector/src/rules}/spanish.py | 14 +------------- utils.py => app/inflector/src/utils.py | 0 app/inflector/tests/__init__.py | 0 tests.py => app/inflector/tests/tests.py | 9 +-------- tests_es.py => app/inflector/tests/tests_es.py | 11 ++--------- setup.py | 12 ++++++++++++ 16 files changed, 19 insertions(+), 55 deletions(-) delete mode 100644 .gitignore rename BSD-LICENSE => LICENSE (100%) rename README.markdown => README.md (100%) rename __init__.py => app/__init__.py (100%) create mode 100644 app/inflector/__init__.py rename {rules => app/inflector/src}/__init__.py (100%) rename inflector.py => app/inflector/src/inflector.py (93%) create mode 100644 app/inflector/src/rules/__init__.py rename {rules => app/inflector/src/rules}/base.py (97%) rename {rules => app/inflector/src/rules}/english.py (96%) rename {rules => app/inflector/src/rules}/spanish.py (96%) rename utils.py => app/inflector/src/utils.py (100%) create mode 100644 app/inflector/tests/__init__.py rename tests.py => app/inflector/tests/tests.py (95%) rename tests_es.py => app/inflector/tests/tests_es.py (93%) create mode 100644 setup.py diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7e99e36..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc \ No newline at end of file diff --git a/BSD-LICENSE b/LICENSE similarity index 100% rename from BSD-LICENSE rename to LICENSE diff --git a/README.markdown b/README.md similarity index 100% rename from README.markdown rename to README.md diff --git a/__init__.py b/app/__init__.py similarity index 100% rename from __init__.py rename to app/__init__.py diff --git a/app/inflector/__init__.py b/app/inflector/__init__.py new file mode 100644 index 0000000..ec21c99 --- /dev/null +++ b/app/inflector/__init__.py @@ -0,0 +1,2 @@ +from .src.inflector import Inflector, English +from .src.rules.spanish import Spanish \ No newline at end of file diff --git a/rules/__init__.py b/app/inflector/src/__init__.py similarity index 100% rename from rules/__init__.py rename to app/inflector/src/__init__.py diff --git a/inflector.py b/app/inflector/src/inflector.py similarity index 93% rename from inflector.py rename to app/inflector/src/inflector.py index 6cca3ab..3baa921 100644 --- a/inflector.py +++ b/app/inflector/src/inflector.py @@ -1,12 +1,4 @@ -#!/usr/bin/env python - -# Copyright (c) 2006 Bermi Ferrer Martinez -# -# bermi a-t bermilabs - com -# See the end of this file for the free software, open source license -# (BSD-style). - -from rules.english import English +from .rules.english import English class Inflector: diff --git a/app/inflector/src/rules/__init__.py b/app/inflector/src/rules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rules/base.py b/app/inflector/src/rules/base.py similarity index 97% rename from rules/base.py rename to app/inflector/src/rules/base.py index f0ab44d..ece2c1d 100644 --- a/rules/base.py +++ b/app/inflector/src/rules/base.py @@ -1,10 +1,3 @@ -#!/usr/bin/env python - -# Copyright (c) 2006 Bermi Ferrer Martinez -# bermi a-t bermilabs - com -# See the end of this file for the free software, open source license -# (BSD-style). - import re diff --git a/rules/english.py b/app/inflector/src/rules/english.py similarity index 96% rename from rules/english.py rename to app/inflector/src/rules/english.py index df64b9f..777fe3b 100644 --- a/rules/english.py +++ b/app/inflector/src/rules/english.py @@ -1,11 +1,3 @@ -#!/usr/bin/env python - -# Copyright (c) 2006 Bermi Ferrer Martinez -# bermi a-t bermilabs - com -# -# See the end of this file for the free software, open source license -# (BSD-style). - import re from .base import Base diff --git a/rules/spanish.py b/app/inflector/src/rules/spanish.py similarity index 96% rename from rules/spanish.py rename to app/inflector/src/rules/spanish.py index 3a0cc99..e6f01cd 100644 --- a/rules/spanish.py +++ b/app/inflector/src/rules/spanish.py @@ -1,18 +1,6 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# coding=utf-8 -# Copyright (c) 2006 Bermi Ferrer Martinez -# Copyright (c) 2006 Carles Sadurní Anguita -# -# bermi a-t bermilabs - com -# -# See the end of this file for the free software, open source license -# (BSD-style). - import re from .base import Base -import utils - +from .. import utils class Spanish (Base): ''' diff --git a/utils.py b/app/inflector/src/utils.py similarity index 100% rename from utils.py rename to app/inflector/src/utils.py diff --git a/app/inflector/tests/__init__.py b/app/inflector/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests.py b/app/inflector/tests/tests.py similarity index 95% rename from tests.py rename to app/inflector/tests/tests.py index a9ac6a9..3fb3a9d 100644 --- a/tests.py +++ b/app/inflector/tests/tests.py @@ -1,12 +1,5 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2006 Bermi Ferrer Martinez -# -# bermi a-t bermilabs - com -# import unittest -from inflector import Inflector, English +from ..src.inflector import Inflector, English class EnglishInflectorTestCase(unittest.TestCase): diff --git a/tests_es.py b/app/inflector/tests/tests_es.py similarity index 93% rename from tests_es.py rename to app/inflector/tests/tests_es.py index c2b2d9b..ac4650d 100755 --- a/tests_es.py +++ b/app/inflector/tests/tests_es.py @@ -1,13 +1,6 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2006 Bermi Ferrer Martinez -# -# bermi a-t bermilabs - com -# import unittest -from inflector import Inflector -from rules.spanish import Spanish +from ..src.inflector import Inflector +from ..src.rules.spanish import Spanish class SpanishInflectorTestCase(unittest.TestCase): diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0ea2b53 --- /dev/null +++ b/setup.py @@ -0,0 +1,12 @@ +from setuptools import find_packages, setup + +setup( + name="python-inflector", + version="0.0.12", + description="The Inflector is used for getting the plural and singular form of nouns", + package_dir={"": "app"}, + packages=find_packages(where="app"), + author="Kemok", + license="MIT", + python_requires=">=3.10", +) \ No newline at end of file