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