Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Python 3 port of urlgrabber #8

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -6,5 +6,6 @@ build
*.kateproject
ipython.log*

# virtualenv
# virtualenvs
sandbox/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/sandbox/* ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's the folder we are most of the times using for virtualenv internally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A leading slash may be used to only match the folder if it appears in this directory, and not any of the subdirectories. Unless you actually want to match the same name in subdirectories, it's generally recommended to always lead with a slash in .gitignore.

sandbox3/*
99 changes: 58 additions & 41 deletions test/munittest.py
Expand Up @@ -107,6 +107,15 @@ def testMultiply(self):
import os
import types

from six import class_types


def cmp(a, b):
try:
return (a > b) - (a < b)
except TypeError:
import pudb; pudb.set_trace()

##############################################################################
# Exported classes and functions
##############################################################################
Expand Down Expand Up @@ -190,7 +199,7 @@ def stop(self):

def _exc_info_to_string(self, err):
"""Converts a sys.exc_info()-style tuple of values into a string."""
return string.join(traceback.format_exception(*err), '')
return ''.join(traceback.format_exception(*err))

def __repr__(self):
return "<%s run=%i errors=%i failures=%i>" % \
Expand Down Expand Up @@ -251,8 +260,8 @@ def __init__(self, methodName='runTest'):
testMethod = getattr(self, methodName)
self._testMethodDoc = testMethod.__doc__
except AttributeError:
raise ValueError, "no such test method in %s: %s" % \
(self.__class__, methodName)
raise(ValueError, "no such test method in %s: %s" % \
(self.__class__, methodName))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is very wrong. raise is not a function, so it does not need parentheses, and they should not be used in this misleading way.

Something like this:

 raise ValueError("no such test method in %s: %s" %
                  (self.__class__, methodName))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I hope I'll be able to take a look again this week. To be hones I don't remember where this is coming from. Let me check this.


def setUp(self):
"Hook method for setting up the test fixture before exercising it."
Expand All @@ -276,7 +285,7 @@ def shortDescription(self):
the specified test method's docstring.
"""
doc = self._testMethodDoc
return doc and string.strip(string.split(doc, "\n")[0]) or None
return doc and doc.split("\n")[0].strip() or None

def id(self):
return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
Expand Down Expand Up @@ -361,15 +370,15 @@ def _exc_info(self):

def fail(self, msg=None):
"""Fail immediately, with the given message."""
raise self.failureException, msg
raise(self.failureException, msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noooooo

raise self.failureException(msg)

It usually is not necessary to do such changes by hand. Please run 2to3-3.6 -f raise -nw . in a clean repo, and commit that as a separate commit.


def failIf(self, expr, msg=None):
"Fail the test if the expression is true."
if expr: raise self.failureException, msg
if expr: raise(self.failureException, msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise


def failUnless(self, expr, msg=None):
"""Fail the test unless the expression is true."""
if not expr: raise self.failureException, msg
if not expr: raise(self.failureException, msg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too


def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
"""Fail unless an exception of class excClass is thrown
Expand All @@ -386,23 +395,23 @@ def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
else:
if hasattr(excClass,'__name__'): excName = excClass.__name__
else: excName = str(excClass)
raise self.failureException, excName
raise(self.failureException, excName)

def failUnlessEqual(self, first, second, msg=None):
"""Fail if the two objects are unequal as determined by the '=='
operator.
"""
if not first == second:
raise self.failureException, \
(msg or '%s != %s' % (`first`, `second`))
raise(self.failureException, \
(msg or '%s != %s' % (repr(first), repr(second))))

def failIfEqual(self, first, second, msg=None):
"""Fail if the two objects are equal as determined by the '=='
operator.
"""
if first == second:
raise self.failureException, \
(msg or '%s == %s' % (`first`, `second`))
raise(self.failureException, \
(msg or '%s == %s' % (repr(first), repr(second))))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raise is wrong, as above. Also, %r should be used instead:

... '%r == %r' % (first, second)


def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
"""Fail if the two objects are unequal as determined by their
Expand All @@ -413,8 +422,8 @@ def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
as significant digits (measured from the most significant digit).
"""
if round(second-first, places) != 0:
raise self.failureException, \
(msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
raise(self.failureException, \
(msg or '%s != %s within %s places' % (repr(first), repr(second), repr(places) )))

def failIfAlmostEqual(self, first, second, places=7, msg=None):
"""Fail if the two objects are equal as determined by their
Expand All @@ -425,8 +434,8 @@ def failIfAlmostEqual(self, first, second, places=7, msg=None):
as significant digits (measured from the most significant digit).
"""
if round(second-first, places) == 0:
raise self.failureException, \
(msg or '%s == %s within %s places' % (`first`, `second`, `places`))
raise(self.failureException, \
(msg or '%s == %s within %s places' % (repr(first), repr(second), repr(places))))

assertEqual = assertEquals = failUnlessEqual

Expand All @@ -442,15 +451,16 @@ def failIfAlmostEqual(self, first, second, places=7, msg=None):

def skip(self, msg=None):
"""Skip the test"""
raise self.skipException, msg
raise(self.skipException, msg)

def skipIf(self, expr, msg=None):
"Skip the test if the expression is true."
if expr: raise self.skipException, msg
if expr:
raise(self.skipException, msg)

def skipUnless(self, expr, msg=None):
"""Skip the test unless the expression is true."""
if not expr: raise self.skipException, msg
if not expr: raise(self.skipException, msg)



Expand Down Expand Up @@ -496,16 +506,20 @@ def run(self, result):
return self(result)

def __call__(self, result):
try: result.startSuite(self)
except AttributeError: pass
try:
result.startSuite(self)
except AttributeError:
pass

for test in self._tests:
if result.shouldStop:
break
test(result)

try: result.endSuite(self)
except AttributeError: pass
try:
result.endSuite(self)
except AttributeError:
pass

return result

Expand Down Expand Up @@ -585,9 +599,9 @@ def loadTestsFromModule(self, module):
tests = []
for name in dir(module):
obj = getattr(module, name)
if (isinstance(obj, (type, types.ClassType)) and
if (isinstance(obj, class_types) and
issubclass(obj, TestCase) and
not obj in [TestCase, FunctionTestCase]):
obj not in [TestCase, FunctionTestCase]):
tests.append(self.loadTestsFromTestCase(obj))
description = getattr(module, '__doc__') \
or module.__name__
Expand All @@ -606,7 +620,7 @@ def loadTestsFromName(self, name, module=None):
parts = string.split(name, '.')
if module is None:
if not parts:
raise ValueError, "incomplete test name: %s" % name
raise(ValueError, "incomplete test name: %s" % name)
else:
parts_copy = parts[:]
while parts_copy:
Expand All @@ -633,11 +647,11 @@ def loadTestsFromName(self, name, module=None):
test = obj()
if not isinstance(test, unittest.TestCase) and \
not isinstance(test, unittest.TestSuite):
raise ValueError, \
"calling %s returned %s, not a test" % (obj,test)
raise(ValueError,
"calling %s returned %s, not a test" % (obj, test))
return test
else:
raise ValueError, "don't know how to make test from: %s" % obj
raise(ValueError, "don't know how to make test from: %s" % obj)

def loadTestsFromNames(self, names, module=None):
"""Return a suite of all tests cases found using the given sequence
Expand All @@ -651,14 +665,15 @@ def loadTestsFromNames(self, names, module=None):
def getTestCaseNames(self, testCaseClass):
"""Return a sorted sequence of method names found within testCaseClass
"""
testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
dir(testCaseClass))
def _f(n):
return n.startswith(self.testMethodPrefix)
testFnNames = list(filter(_f, dir(testCaseClass)))
for baseclass in testCaseClass.__bases__:
for testFnName in self.getTestCaseNames(baseclass):
if testFnName not in testFnNames: # handle overridden methods
testFnNames.append(testFnName)
if self.sortTestMethodsUsing:
testFnNames.sort(self.sortTestMethodsUsing)
# if self.sortTestMethodsUsing:
# testFnNames.sort(key=self.sortTestMethodsUsing)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

return testFnNames


Expand Down Expand Up @@ -737,7 +752,8 @@ def startSuite(self, suite):
if self.showAll and self.descriptions:
self.stream.write(self.indent * self.depth)
try: desc = self.getDescription(suite)
except AttributeError: desc = '(no description)'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems strange to leave try as it was.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. But at that time the focus was on getting it running, not refactoring the code - which has it's own style in various places.

except AttributeError:
desc = '(no description)'
self.stream.writeln(desc)
self.depth += 1

Expand Down Expand Up @@ -886,21 +902,22 @@ def __init__(self, module='__main__', defaultTest=None,
self.runTests()

def usageExit(self, msg=None):
if msg: print msg
print self.USAGE % self.__dict__
if msg:
print(msg)
print(self.USAGE % self.__dict__)
sys.exit(2)

def parseArgs(self, argv):
import getopt
try:
options, args = getopt.getopt(argv[1:], 'hHvq',
['help','verbose','quiet'])
['help', 'verbose', 'quiet'])
for opt, value in options:
if opt in ('-h','-H','--help'):
if opt in ('-h', '-H', '--help'):
self.usageExit()
if opt in ('-q','--quiet'):
if opt in ('-q', '--quiet'):
self.verbosity = 0
if opt in ('-v','--verbose'):
if opt in ('-v', '--verbose'):
self.verbosity = 2
if len(args) == 0 and self.defaultTest is None:
self.test = self.testLoader.loadTestsFromModule(self.module)
Expand All @@ -910,7 +927,7 @@ def parseArgs(self, argv):
else:
self.testNames = (self.defaultTest,)
self.createTests()
except getopt.error, msg:
except getopt.error as msg:
self.usageExit(msg)

def createTests(self):
Expand Down
2 changes: 1 addition & 1 deletion test/runtests.py
Expand Up @@ -54,7 +54,7 @@ def parse_args():
return (descriptions,verbosity)

def usage():
print __doc__
print(__doc__)

if __name__ == '__main__':
main()
9 changes: 8 additions & 1 deletion test/test_byterange.py
Expand Up @@ -25,7 +25,14 @@

import sys

from cStringIO import StringIO
try:
from cStringIO import StringIO
except ImportError:
try:
from StringIO import StringIO
except ImportError:
from io import StringIO

from urlgrabber.byterange import RangeableFileObject

from base_test_code import *
Expand Down