xref: /aosp_15_r20/external/antlr/runtime/Python3/setup.py (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1
2import sys
3if 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
10import ez_setup
11ez_setup.use_setuptools()
12
13import os
14import textwrap
15from distutils.errors import *
16from distutils.command.clean import clean as _clean
17from distutils.cmd import Command
18from setuptools import setup
19from distutils import log
20
21from distutils.core import setup
22
23class 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
62class 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...
71class 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
148class 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
271setup(name='antlr_python3_runtime',
272      version='3.4',
273      packages=['antlr3'],
274
275      author="Benjamin S Wolf",
276      author_email="[email protected]",
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