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 92% rename from inflector.py rename to app/inflector/src/inflector.py index c9be1c8..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: @@ -19,7 +11,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 +116,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/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 bf4d18a..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 @@ -147,4 +140,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/app/inflector/src/rules/english.py similarity index 96% rename from rules/english.py rename to app/inflector/src/rules/english.py index 42d1b2e..777fe3b 100644 --- a/rules/english.py +++ b/app/inflector/src/rules/english.py @@ -1,13 +1,5 @@ -#!/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 +from .base import Base class English (Base): @@ -158,4 +150,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/app/inflector/src/rules/spanish.py similarity index 84% rename from rules/spanish.py rename to app/inflector/src/rules/spanish.py index 2c9f283..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 .base import Base +from .. import utils class Spanish (Base): ''' @@ -77,7 +65,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 +78,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 +105,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 +126,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 +139,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 +154,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 +168,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/utils.py b/app/inflector/src/utils.py similarity index 57% rename from utils.py rename to app/inflector/src/utils.py index e4f572e..19a22c1 100644 --- a/utils.py +++ b/app/inflector/src/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 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 91% rename from tests.py rename to app/inflector/tests/tests.py index fa897d6..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): @@ -113,14 +106,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/app/inflector/tests/tests_es.py similarity index 88% rename from tests_es.py rename to app/inflector/tests/tests_es.py index 6f75030..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): @@ -68,14 +61,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/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