Skip to content

Commit

Permalink
Python3 support
Browse files Browse the repository at this point in the history
  • Loading branch information
vkurup committed Jan 18, 2019
1 parent 8c45902 commit 38916c8
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 31 deletions.
56 changes: 43 additions & 13 deletions pyfribidi.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,25 @@
#include <Python.h>
#include <fribidi.h>

#if PY_MAJOR_VERSION >= 3
#define PYFRIBIDI_UNICODE_OBJECT PyObject
#else
#define PYFRIBIDI_UNICODE_OBJECT PyUnicodeObject
#endif

static PyObject *
unicode_log2vis (PyUnicodeObject* string,
unicode_log2vis (PYFRIBIDI_UNICODE_OBJECT * string,
FriBidiParType base_direction, int clean, int reordernsm)
{
int i;
#if PY_MAJOR_VERSION >= 3
Py_ssize_t length = PyUnicode_GetLength(string);
#else
int length = string->length;
#endif
FriBidiChar *logical = NULL; /* input fribidi unicode buffer */
FriBidiChar *visual = NULL; /* output fribidi unicode buffer */
FriBidiStrIndex new_len = 0; /* length of the UTF-8 buffer */
PyUnicodeObject *result = NULL;
PYFRIBIDI_UNICODE_OBJECT *result = NULL;

/* Allocate fribidi unicode buffers
TODO - Don't copy strings if sizeof(FriBidiChar) == sizeof(Py_UNICODE)
Expand All @@ -49,9 +57,7 @@ unicode_log2vis (PyUnicodeObject* string,
goto cleanup;
}

for (i=0; i<length; ++i) {
logical[i] = string->str[i];
}
PyUnicode_AsWideChar(string, logical, length);

/* Convert to unicode and order visually */
fribidi_set_reorder_nsm(reordernsm);
Expand All @@ -69,15 +75,11 @@ unicode_log2vis (PyUnicodeObject* string,
length = fribidi_remove_bidi_marks (visual, length, NULL, NULL, NULL);
}

result = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, length);
result = PyUnicode_FromWideChar(visual, length);
if (result == NULL) {
goto cleanup;
}

for (i=0; i<length; ++i) {
result->str[i] = visual[i];
}

cleanup:
/* Delete unicode buffers */
PyMem_Del (logical);
Expand All @@ -89,7 +91,7 @@ unicode_log2vis (PyUnicodeObject* string,
static PyObject *
_pyfribidi_log2vis (PyObject * self, PyObject * args, PyObject * kw)
{
PyUnicodeObject *logical = NULL; /* input unicode or string object */
PYFRIBIDI_UNICODE_OBJECT *logical = NULL; /* input unicode or string object */
FriBidiParType base = FRIBIDI_TYPE_RTL; /* optional direction */
int clean = 0; /* optional flag to clean the string */
int reordernsm = 1; /* optional flag to allow reordering of non spacing marks*/
Expand All @@ -112,7 +114,9 @@ _pyfribidi_log2vis (PyObject * self, PyObject * args, PyObject * kw)
base);
}

return unicode_log2vis (logical, base, clean, reordernsm);
PyObject * return_pyobject = unicode_log2vis (logical, base, clean, reordernsm);

return return_pyobject;
}


Expand All @@ -121,12 +125,38 @@ static PyMethodDef PyfribidiMethods[] = {
{NULL, NULL, 0, NULL}
};

#if PY_MAJOR_VERSION >= 3

static struct PyModuleDef pyfribidi_moduledef = {
PyModuleDef_HEAD_INIT, /* m_base */
"pyfribidi", /* m_name */
NULL, /* m_doc */
-1, /* m_size == -1 means cannot be reinitialized */
PyfribidiMethods, //
NULL, // myextension_traverse,
NULL, // myextension_clear,
NULL
};

PyMODINIT_FUNC
PyInit__pyfribidi (void)
#else

void
init_pyfribidi (void)
#endif
{
#if PY_MAJOR_VERSION >= 3
PyObject *module = PyModule_Create (&pyfribidi_moduledef);
#else
PyObject *module = Py_InitModule ("_pyfribidi", PyfribidiMethods);
#endif
if (module == NULL) return NULL;

PyModule_AddIntConstant (module, "RTL", (long) FRIBIDI_TYPE_RTL);
PyModule_AddIntConstant (module, "LTR", (long) FRIBIDI_TYPE_LTR);
PyModule_AddIntConstant (module, "ON", (long) FRIBIDI_TYPE_ON);
#if PY_MAJOR_VERSION >= 3
return module;
#endif
}
5 changes: 3 additions & 2 deletions pyfribidi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""

__version__ = "0.11.0"
import six
from _pyfribidi import LTR, ON, RTL, log2vis as _log2vis

def log2vis(logical, base_direction=RTL, encoding="utf-8", clean=False, reordernsm=True):
Expand All @@ -25,8 +26,8 @@ def log2vis(logical, base_direction=RTL, encoding="utf-8", clean=False, reordern
- encoding: optional string encoding (ignored for unicode input)
"""

if not isinstance(logical, unicode):
logical = unicode(logical, encoding)
if not isinstance(logical, six.text_type):
logical = six.text_type(logical, encoding)
else:
encoding = None
res = _log2vis(logical, base_direction=base_direction, clean=clean, reordernsm=reordernsm)
Expand Down
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def _getpkgconfigvalue(value, package="fribidi"):
def get_version():
d = {}
try:
execfile("pyfribidi.py", d, d)
exec(compile(open("pyfribidi.py", "rb").read(), "pyfribidi.py", 'exec'), d, d)
except (ImportError, RuntimeError):
pass
return d["__version__"]
Expand All @@ -95,6 +95,9 @@ def get_version():
author_email="[email protected]",
url="https://github.com/pediapress/pyfribidi",
license="GPL",
install_requires=[
"six",
],
cmdclass={'build_ext': my_build_ext},
long_description=open("README.rst").read(),
py_modules=["pyfribidi", "pyfribidi2"],
Expand Down
30 changes: 16 additions & 14 deletions test_pyfribidi.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class InputTests(unittest.TestCase):
def testRequireInputString(self):
""" input: require input string or unicode """
self.assertRaises(TypeError, pyfribidi.log2vis)

def testInvalidInputString(self):
""" input: raise TypeError for non string or unicode input """
self.assertRaises(TypeError, pyfribidi.log2vis, 1)
Expand All @@ -33,15 +33,17 @@ def testInvalidDirection(self):

def testUnknownEncoding(self):
""" input: raise LookupError for invalid encoding """
self.assertRaises(LookupError, pyfribidi.log2vis, "שלום",
encoded = u"שלום".encode('utf-8')
self.assertRaises(LookupError, pyfribidi.log2vis, encoded,
encoding='foo')

def testInvalidEncodedString(self):
""" input: raise UnicodeError for invalid encoded string """
self.assertRaises(UnicodeError, pyfribidi.log2vis, "שלום",
encoded = u"שלום".encode('utf-8')
self.assertRaises(UnicodeError, pyfribidi.log2vis, encoded,
encoding='iso8859-8')


class UnicodeTests(unittest.TestCase):

def testEmpty(self):
Expand Down Expand Up @@ -94,11 +96,11 @@ def testReorderNonSpacingMarks(self):
self.assertEqual(pyfribidi.log2vis(u"חַיְפַא", RTL),
u"אפַיְחַ"
)


class UTF8Tests(unittest.TestCase):
""" Same tests for utf8, used mainly on linux """

def testEmpty(self):
""" utf8: empty string """
self.assertEqual(pyfribidi.log2vis(''), '')
Expand All @@ -117,7 +119,7 @@ def testDefaultDirection(self):
""" utf8: use RTL default """
self.assertEqual(pyfribidi.log2vis("hello - שלום"),
pyfribidi.log2vis("hello - שלום", RTL))

def testAsRTL(self):
""" utf8: reorder line as RTL """
self.assertEqual(pyfribidi.log2vis("hello - שלום", RTL),
Expand All @@ -127,12 +129,12 @@ def testAsLTR(self):
""" utf8: reorder line as LTR """
self.assertEqual(pyfribidi.log2vis("hello - שלום", LTR),
"hello - םולש")

def testNaturalLTR(self):
""" utf8: reorder LTR line by natural order """
self.assertEqual(pyfribidi.log2vis("hello - שלום", ON),
"hello - םולש")

def testNaturalRTL(self):
""" utf8: reorder RTL line by natural order """
self.assertEqual(pyfribidi.log2vis("שלום - hello", ON),
Expand All @@ -154,14 +156,14 @@ def testReorderNonSpacingMarks(self):

class OtherEncodingsTests(unittest.TestCase):
""" Minimal tests for other encodings """

def testIso8859_8NaturalRTL(self):
""" other encodings: iso8859-8 """
charset = 'iso8859-8'
self.assertEqual(pyfribidi.log2vis(u"שלום - hello".encode(charset),
encoding=charset),
u"hello - םולש".encode(charset))

def testCp1255NaturalRTL(self):
""" other encodings: cp1255 """
charset = 'cp1255'
Expand All @@ -183,5 +185,5 @@ def test_glibc_free_invalid_next_size(self):

if __name__ == '__main__':
suite = unittest.defaultTestLoader.loadTestsFromName(__name__)
res = unittest.TextTestRunner(verbosity=2).run(suite)
res = unittest.TextTestRunner(verbosity=1).run(suite)
sys.exit(not res.wasSuccessful())
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py24, py25, py26, py27
envlist = py24, py25, py26, py27, py37

[testenv]
deps=
Expand Down

0 comments on commit 38916c8

Please sign in to comment.