From 67e02497372bebd3703b002755c652cc24e35e8f Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Sat, 23 Oct 2010 21:58:21 -0700 Subject: [PATCH] fix issue #4: fix a few Python3 compat things --- CHANGES.md | 2 +- lib/eol.py | 32 ++++++++++++++++++++++++-------- test/api.doctests | 15 +++++++++++---- test/api2.doctests | 8 ++++++++ test/api3.doctests | 8 ++++++++ test/test_eol.py | 14 ++++++++++++++ 6 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 test/api2.doctests create mode 100644 test/api3.doctests diff --git a/CHANGES.md b/CHANGES.md index e719583..4f9682e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## eol 0.7.5 (not yet released) -(nothing yet) +- [Issue #4] Fix a few Python 3 compat issues, add some more test cases. ## eol 0.7.4 diff --git a/lib/eol.py b/lib/eol.py index 6785ef2..fc97cc5 100755 --- a/lib/eol.py +++ b/lib/eol.py @@ -86,6 +86,17 @@ class MIXED(object): } +# Python 2/3 compat +try: + _BASESTRING = basestring +except NameError: + _BASESTRING = str +if sys.version_info[0] > 2: + _BYTES_NULL = bytes([0]) +else: + _BYTES_NULL = '\0' + + #---- public module interface @@ -168,9 +179,14 @@ def eol_info_from_text(text): >>> eol_info_from_text('\nfoo\nbar\r\n') == (MIXED, '\n') # mixed text True """ - numCRLFs = text.count("\r\n") - numCRs = text.count("\r") - numCRLFs - numLFs = text.count("\n") - numCRLFs + if sys.version_info[0] > 2 and type(text) == bytes: + numCRLFs = text.count(bytes([13, 10])) + numCRs = text.count(bytes([13])) - numCRLFs + numLFs = text.count(bytes([10])) - numCRLFs + else: + numCRLFs = text.count("\r\n") + numCRs = text.count("\r") - numCRLFs + numLFs = text.count("\n") - numCRLFs if numCRLFs == numLFs == numCRs == 0: return (None, NATIVE) @@ -215,7 +231,7 @@ def eol_info_from_path_patterns(path_patterns, recursive=False, See eol_info_from_text() docstring for details. """ from os.path import islink - assert not isinstance(path_patterns, basestring), \ + assert not isinstance(path_patterns, _BASESTRING), \ "'path_patterns' must be a sequence, not a string: %r" % path_patterns for path in _paths_from_path_patterns(path_patterns, recursive=recursive, @@ -233,7 +249,7 @@ def eol_info_from_path_patterns(path_patterns, recursive=False, content = fin.read() finally: fin.close() - if '\0' in content: + if _BYTES_NULL in content: log.debug("skipped `%s': binary file (null in content)" % path) continue eol, suggested_eol = eol_info_from_text(content) @@ -268,7 +284,7 @@ def convert_path_eol(path, eol, skip_binary_content=True, log=log): original = fin.read() finally: fin.close() - if skip_binary_content and '\0' in original: + if skip_binary_content and _BYTES_NULL in original: log.debug("skipped `%s': binary file (null in content)" % path) return converted = convert_text_eol(original, eol) @@ -288,7 +304,7 @@ def convert_path_patterns_eol(path_patterns, eol, recursive=False, """Convert the given paths (in-place) to the given EOL. If no changes are necessary the file is not touched. """ - assert not isinstance(path_patterns, basestring), \ + assert not isinstance(path_patterns, _BASESTRING), \ "'path_patterns' must be a sequence, not a string: %r" % path_patterns for path in _paths_from_path_patterns(path_patterns, recursive=recursive, @@ -524,7 +540,7 @@ def _paths_from_path_patterns(path_patterns, files=True, dirs="never", lexists, islink, realpath from glob import glob - assert not isinstance(path_patterns, basestring), \ + assert not isinstance(path_patterns, _BASESTRING), \ "'path_patterns' must be a sequence, not a string: %r" % path_patterns if includes is None: includes = [] if excludes is None: excludes = [] diff --git a/test/api.doctests b/test/api.doctests index 1542d78..3cc2d35 100644 --- a/test/api.doctests +++ b/test/api.doctests @@ -14,16 +14,23 @@ True >>> eol.eol_info_from_text('a\rb\r') ('\r', '\r') + # Create some temp files. ->>> import tempfile +>>> import tempfile, sys >>> from os.path import join >>> d = tempfile.mkdtemp() >>> cr_path = join(d, "cr.tmp") ->>> open(cr_path, 'wb').write('a\rb\r') >>> lf_path = join(d, "lf.tmp") ->>> open(lf_path, 'wb').write('a\nb\n') >>> crlf_path = join(d, "crlf.tmp") ->>> open(crlf_path, 'wb').write('a\r\nb\r\n') +>>> if sys.version_info[0] <= 2: +... open(cr_path, 'wb').write('a\rb\r') +... open(lf_path, 'wb').write('a\nb\n') +... open(crlf_path, 'wb').write('a\r\nb\r\n') +... else: +... _ = open(cr_path, 'wb').write(bytes('a\rb\r', 'ascii')) +... _ = open(lf_path, 'wb').write(bytes('a\nb\n', 'ascii')) +... _ = open(crlf_path, 'wb').write(bytes('a\r\nb\r\n', 'ascii')) + >>> list( eol.eol_info_from_path_patterns([join(d, '*.tmp')]) ) == [ ... (join(d, 'cr.tmp'), '\r', '\r'), diff --git a/test/api2.doctests b/test/api2.doctests new file mode 100644 index 0000000..ce8a7c0 --- /dev/null +++ b/test/api2.doctests @@ -0,0 +1,8 @@ +# Some tests for Python 2-only syntax. + +>>> import eol +>>> eol.eol_info_from_text('a\rb\r') +('\r', '\r') +>>> eol.eol_info_from_text(u'a\rb\r') +('\r', '\r') + diff --git a/test/api3.doctests b/test/api3.doctests new file mode 100644 index 0000000..a380164 --- /dev/null +++ b/test/api3.doctests @@ -0,0 +1,8 @@ +# Some tests for Python 3-only syntax. + +>>> import eol +>>> eol.eol_info_from_text('a\rb\r') +('\r', '\r') +>>> eol.eol_info_from_text(b'a\rb\r') +('\r', '\r') + diff --git a/test/test_eol.py b/test/test_eol.py index f9eb001..3a1f37d 100644 --- a/test/test_eol.py +++ b/test/test_eol.py @@ -18,6 +18,20 @@ def test_api(self): test = doctest.DocFileTest("api.doctests") test.runTest() + if sys.version_info[0] == 2: + def test_api2(self): + """API tests for Python 2 syntax""" + if sys.version_info[:2] < (2,4): + raise TestSkipped("no DocFileTest in Python <=2.3") + test = doctest.DocFileTest("api2.doctests") + test.runTest() + + if sys.version_info[0] > 2: + def test_api3(self): + """API tests for Python 3 syntax""" + test = doctest.DocFileTest("api3.doctests") + test.runTest() + def test_internal(self): import eol doctest.testmod(eol)