1 # bootstrapping setuptools 2 import ez_setup 3 ez_setup.use_setuptools() 4 5 import os 6 import sys 7 import textwrap 8 from distutils.errors import * 9 from distutils.command.clean import clean as _clean 10 from distutils.cmd import Command 11 from setuptools import setup 12 from distutils import log 13 14 from distutils.core import setup 15 16 17 class clean(_clean): 18 """Also cleanup local temp files.""" 19 20 def run(self): 21 _clean.run(self) 22 23 import fnmatch 24 25 # kill temporary files 26 patterns = [ 27 # generic tempfiles 28 '*~', '*.bak', '*.pyc', 29 30 # tempfiles generated by ANTLR runs 31 't[0-9]*Lexer.py', 't[0-9]*Parser.py', 32 '*.tokens', '*__.g', 33 ] 34 35 for path in ('antlr3', 'unittests', 'tests'): 36 path = os.path.join(os.path.dirname(__file__), path) 37 if os.path.isdir(path): 38 for root, dirs, files in os.walk(path, topdown=True): 39 graveyard = [] 40 for pat in patterns: 41 graveyard.extend(fnmatch.filter(files, pat)) 42 43 for name in graveyard: 44 filePath = os.path.join(root, name) 45 46 try: 47 log.info("removing '%s'", filePath) 48 os.unlink(filePath) 49 except OSError, exc: 50 log.warn( 51 "Failed to delete '%s': %s", 52 filePath, exc 53 ) 54 55 56 class TestError(DistutilsError): 57 pass 58 59 60 # grml.. the class name appears in the --help output: 61 # ... 62 # Options for 'CmdUnitTest' command 63 # ... 64 # so I have to use a rather ugly name... 65 class unittest(Command): 66 """Run unit tests for package""" 67 68 description = "run unit tests for package" 69 70 user_options = [ 71 ('xml-output=', None, 72 "Directory for JUnit compatible XML files."), 73 ] 74 boolean_options = [] 75 76 def initialize_options(self): 77 self.xml_output = None 78 79 def finalize_options(self): 80 pass 81 82 def run(self): 83 testDir = os.path.join(os.path.dirname(__file__), 'unittests') 84 if not os.path.isdir(testDir): 85 raise DistutilsFileError( 86 "There is not 'unittests' directory. Did you fetch the " 87 "development version?", 88 ) 89 90 import glob 91 import imp 92 import unittest 93 import traceback 94 import StringIO 95 96 suite = unittest.TestSuite() 97 loadFailures = [] 98 99 # collect tests from all unittests/test*.py files 100 testFiles = [] 101 for testPath in glob.glob(os.path.join(testDir, 'test*.py')): 102 testFiles.append(testPath) 103 104 testFiles.sort() 105 for testPath in testFiles: 106 testID = os.path.basename(testPath)[:-3] 107 108 try: 109 modFile, modPathname, modDescription \ 110 = imp.find_module(testID, [testDir]) 111 112 testMod = imp.load_module( 113 testID, modFile, modPathname, modDescription 114 ) 115 116 suite.addTests( 117 unittest.defaultTestLoader.loadTestsFromModule(testMod) 118 ) 119 120 except Exception: 121 buf = StringIO.StringIO() 122 traceback.print_exc(file=buf) 123 124 loadFailures.append( 125 (os.path.basename(testPath), buf.getvalue()) 126 ) 127 128 if self.xml_output: 129 import xmlrunner 130 runner = xmlrunner.XMLTestRunner( 131 stream=open(os.path.join(self.xml_output, 'unittest.xml'), 'w')) 132 else: 133 runner = unittest.TextTestRunner(verbosity=2) 134 result = runner.run(suite) 135 136 for testName, error in loadFailures: 137 sys.stderr.write('\n' + '='*70 + '\n') 138 sys.stderr.write( 139 "Failed to load test module %s\n" % testName 140 ) 141 sys.stderr.write(error) 142 sys.stderr.write('\n') 143 144 if not result.wasSuccessful() or loadFailures: 145 raise TestError( 146 "Unit test suite failed!", 147 ) 148 149 150 class functest(Command): 151 """Run functional tests for package""" 152 153 description = "run functional tests for package" 154 155 user_options = [ 156 ('testcase=', None, 157 "testcase to run [default: run all]"), 158 ('antlr-version=', None, 159 "ANTLR version to use [default: HEAD (in ../../build)]"), 160 ('antlr-jar=', None, 161 "Explicit path to an antlr jar (overrides --antlr-version)"), 162 ('xml-output=', None, 163 "Directory for JUnit compatible XML files."), 164 ] 165 166 boolean_options = [] 167 168 def initialize_options(self): 169 self.testcase = None 170 self.antlr_version = 'HEAD' 171 self.antlr_jar = None 172 self.xml_output = None 173 174 def finalize_options(self): 175 pass 176 177 def run(self): 178 import glob 179 import imp 180 import unittest 181 import traceback 182 import StringIO 183 184 testDir = os.path.join(os.path.dirname(__file__), 'tests') 185 if not os.path.isdir(testDir): 186 raise DistutilsFileError( 187 "There is not 'tests' directory. Did you fetch the " 188 "development version?", 189 ) 190 191 # make sure, relative imports from testcases work 192 sys.path.insert(0, testDir) 193 194 rootDir = os.path.abspath( 195 os.path.join(os.path.dirname(__file__), '..', '..')) 196 197 if self.antlr_jar is not None: 198 classpath = [self.antlr_jar] 199 elif self.antlr_version == 'HEAD': 200 classpath = [ 201 os.path.join(rootDir, 'tool', 'target', 'classes'), 202 os.path.join(rootDir, 'runtime', 'Java', 'target', 'classes') 203 ] 204 else: 205 classpath = [ 206 os.path.join(rootDir, 'archive', 207 'antlr-%s.jar' % self.antlr_version) 208 ] 209 210 classpath.extend([ 211 os.path.join(rootDir, 'lib', 'antlr-2.7.7.jar'), 212 os.path.join(rootDir, 'lib', 'stringtemplate-3.2.1.jar'), 213 os.path.join(rootDir, 'lib', 'ST-4.0.2.jar'), 214 os.path.join(rootDir, 'lib', 'junit-4.2.jar') 215 ]) 216 os.environ['CLASSPATH'] = ':'.join(classpath) 217 218 os.environ['ANTLRVERSION'] = self.antlr_version 219 220 suite = unittest.TestSuite() 221 loadFailures = [] 222 223 # collect tests from all tests/t*.py files 224 testFiles = [] 225 test_glob = 't[0-9][0-9][0-9]*.py' 226 for testPath in glob.glob(os.path.join(testDir, test_glob)): 227 if testPath.endswith('Lexer.py') or testPath.endswith('Parser.py'): 228 continue 229 230 # if a single testcase has been selected, filter out all other 231 # tests 232 if (self.testcase is not None 233 and not os.path.basename(testPath)[:-3].startswith(self.testcase)): 234 continue 235 236 testFiles.append(testPath) 237 238 testFiles.sort() 239 for testPath in testFiles: 240 testID = os.path.basename(testPath)[:-3] 241 242 try: 243 modFile, modPathname, modDescription \ 244 = imp.find_module(testID, [testDir]) 245 246 testMod = imp.load_module( 247 testID, modFile, modPathname, modDescription) 248 249 suite.addTests( 250 unittest.defaultTestLoader.loadTestsFromModule(testMod)) 251 252 except Exception: 253 buf = StringIO.StringIO() 254 traceback.print_exc(file=buf) 255 256 loadFailures.append( 257 (os.path.basename(testPath), buf.getvalue())) 258 259 if self.xml_output: 260 import xmlrunner 261 runner = xmlrunner.XMLTestRunner( 262 stream=open(os.path.join(self.xml_output, 'functest.xml'), 'w')) 263 else: 264 runner = unittest.TextTestRunner(verbosity=2) 265 266 result = runner.run(suite) 267 268 for testName, error in loadFailures: 269 sys.stderr.write('\n' + '='*70 + '\n') 270 sys.stderr.write( 271 "Failed to load test module %s\n" % testName 272 ) 273 sys.stderr.write(error) 274 sys.stderr.write('\n') 275 276 if not result.wasSuccessful() or loadFailures: 277 raise TestError( 278 "Functional test suite failed!", 279 ) 280 281 282 setup(name='antlr_python_runtime', 283 version='3.4', 284 packages=['antlr3'], 285 286 author="Benjamin Niemann", 287 author_email="pink (at] odahoda.de", 288 url="http://www.antlr.org/", 289 download_url="http://www.antlr.org/download.html", 290 license="BSD", 291 description="Runtime package for ANTLR3", 292 long_description=textwrap.dedent('''\ 293 This is the runtime package for ANTLR3, which is required to use parsers 294 generated by ANTLR3. 295 '''), 296 cmdclass={'unittest': unittest, 297 'functest': functest, 298 'clean': clean 299 }, 300 ) 301