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