1a5f9918aSopenharmony_ci
2a5f9918aSopenharmony_ciNAME = 'PyYAML'
3a5f9918aSopenharmony_ciVERSION = '6.0'
4a5f9918aSopenharmony_ciDESCRIPTION = "YAML parser and emitter for Python"
5a5f9918aSopenharmony_ciLONG_DESCRIPTION = """\
6a5f9918aSopenharmony_ciYAML is a data serialization format designed for human readability
7a5f9918aSopenharmony_ciand interaction with scripting languages.  PyYAML is a YAML parser
8a5f9918aSopenharmony_ciand emitter for Python.
9a5f9918aSopenharmony_ci
10a5f9918aSopenharmony_ciPyYAML features a complete YAML 1.1 parser, Unicode support, pickle
11a5f9918aSopenharmony_cisupport, capable extension API, and sensible error messages.  PyYAML
12a5f9918aSopenharmony_cisupports standard YAML tags and provides Python-specific tags that
13a5f9918aSopenharmony_ciallow to represent an arbitrary Python object.
14a5f9918aSopenharmony_ci
15a5f9918aSopenharmony_ciPyYAML is applicable for a broad range of tasks from complex
16a5f9918aSopenharmony_ciconfiguration files to object serialization and persistence."""
17a5f9918aSopenharmony_ciAUTHOR = "Kirill Simonov"
18a5f9918aSopenharmony_ciAUTHOR_EMAIL = 'xi@resolvent.net'
19a5f9918aSopenharmony_ciLICENSE = "MIT"
20a5f9918aSopenharmony_ciPLATFORMS = "Any"
21a5f9918aSopenharmony_ciURL = "https://pyyaml.org/"
22a5f9918aSopenharmony_ciDOWNLOAD_URL = "https://pypi.org/project/PyYAML/"
23a5f9918aSopenharmony_ciCLASSIFIERS = [
24a5f9918aSopenharmony_ci    "Development Status :: 5 - Production/Stable",
25a5f9918aSopenharmony_ci    "Intended Audience :: Developers",
26a5f9918aSopenharmony_ci    "License :: OSI Approved :: MIT License",
27a5f9918aSopenharmony_ci    "Operating System :: OS Independent",
28a5f9918aSopenharmony_ci    "Programming Language :: Cython",
29a5f9918aSopenharmony_ci    "Programming Language :: Python",
30a5f9918aSopenharmony_ci    "Programming Language :: Python :: 3",
31a5f9918aSopenharmony_ci    "Programming Language :: Python :: 3.6",
32a5f9918aSopenharmony_ci    "Programming Language :: Python :: 3.7",
33a5f9918aSopenharmony_ci    "Programming Language :: Python :: 3.8",
34a5f9918aSopenharmony_ci    "Programming Language :: Python :: 3.9",
35a5f9918aSopenharmony_ci    "Programming Language :: Python :: 3.10",
36a5f9918aSopenharmony_ci    "Programming Language :: Python :: Implementation :: CPython",
37a5f9918aSopenharmony_ci    "Programming Language :: Python :: Implementation :: PyPy",
38a5f9918aSopenharmony_ci    "Topic :: Software Development :: Libraries :: Python Modules",
39a5f9918aSopenharmony_ci    "Topic :: Text Processing :: Markup",
40a5f9918aSopenharmony_ci]
41a5f9918aSopenharmony_ciPROJECT_URLS = {
42a5f9918aSopenharmony_ci   'Bug Tracker': 'https://github.com/yaml/pyyaml/issues',
43a5f9918aSopenharmony_ci   'CI': 'https://github.com/yaml/pyyaml/actions',
44a5f9918aSopenharmony_ci   'Documentation': 'https://pyyaml.org/wiki/PyYAMLDocumentation',
45a5f9918aSopenharmony_ci   'Mailing lists': 'http://lists.sourceforge.net/lists/listinfo/yaml-core',
46a5f9918aSopenharmony_ci   'Source Code': 'https://github.com/yaml/pyyaml',
47a5f9918aSopenharmony_ci}
48a5f9918aSopenharmony_ci
49a5f9918aSopenharmony_ciLIBYAML_CHECK = """
50a5f9918aSopenharmony_ci#include <yaml.h>
51a5f9918aSopenharmony_ci
52a5f9918aSopenharmony_ciint main(void) {
53a5f9918aSopenharmony_ci    yaml_parser_t parser;
54a5f9918aSopenharmony_ci    yaml_emitter_t emitter;
55a5f9918aSopenharmony_ci
56a5f9918aSopenharmony_ci    yaml_parser_initialize(&parser);
57a5f9918aSopenharmony_ci    yaml_parser_delete(&parser);
58a5f9918aSopenharmony_ci
59a5f9918aSopenharmony_ci    yaml_emitter_initialize(&emitter);
60a5f9918aSopenharmony_ci    yaml_emitter_delete(&emitter);
61a5f9918aSopenharmony_ci
62a5f9918aSopenharmony_ci    return 0;
63a5f9918aSopenharmony_ci}
64a5f9918aSopenharmony_ci"""
65a5f9918aSopenharmony_ci
66a5f9918aSopenharmony_ci
67a5f9918aSopenharmony_ciimport sys, os, os.path, pathlib, platform, shutil, tempfile, warnings
68a5f9918aSopenharmony_ci
69a5f9918aSopenharmony_ci# for newer setuptools, enable the embedded distutils before importing setuptools/distutils to avoid warnings
70a5f9918aSopenharmony_cios.environ['SETUPTOOLS_USE_DISTUTILS'] = 'local'
71a5f9918aSopenharmony_ci
72a5f9918aSopenharmony_cifrom setuptools import setup, Command, Distribution as _Distribution, Extension as _Extension
73a5f9918aSopenharmony_cifrom setuptools.command.build_ext import build_ext as _build_ext
74a5f9918aSopenharmony_ci# NB: distutils imports must remain below setuptools to ensure we use the embedded version
75a5f9918aSopenharmony_cifrom distutils import log
76a5f9918aSopenharmony_cifrom distutils.errors import DistutilsError, CompileError, LinkError, DistutilsPlatformError
77a5f9918aSopenharmony_ci
78a5f9918aSopenharmony_ciwith_cython = False
79a5f9918aSopenharmony_ciif 'sdist' in sys.argv or os.environ.get('PYYAML_FORCE_CYTHON') == '1':
80a5f9918aSopenharmony_ci    # we need cython here
81a5f9918aSopenharmony_ci    with_cython = True
82a5f9918aSopenharmony_citry:
83a5f9918aSopenharmony_ci    from Cython.Distutils.extension import Extension as _Extension
84a5f9918aSopenharmony_ci    from Cython.Distutils import build_ext as _build_ext
85a5f9918aSopenharmony_ci    with_cython = True
86a5f9918aSopenharmony_ciexcept ImportError:
87a5f9918aSopenharmony_ci    if with_cython:
88a5f9918aSopenharmony_ci        raise
89a5f9918aSopenharmony_ci
90a5f9918aSopenharmony_citry:
91a5f9918aSopenharmony_ci    from wheel.bdist_wheel import bdist_wheel
92a5f9918aSopenharmony_ciexcept ImportError:
93a5f9918aSopenharmony_ci    bdist_wheel = None
94a5f9918aSopenharmony_ci
95a5f9918aSopenharmony_ci
96a5f9918aSopenharmony_ci# on Windows, disable wheel generation warning noise
97a5f9918aSopenharmony_ciwindows_ignore_warnings = [
98a5f9918aSopenharmony_ci"Unknown distribution option: 'python_requires'",
99a5f9918aSopenharmony_ci"Config variable 'Py_DEBUG' is unset",
100a5f9918aSopenharmony_ci"Config variable 'WITH_PYMALLOC' is unset",
101a5f9918aSopenharmony_ci"Config variable 'Py_UNICODE_SIZE' is unset",
102a5f9918aSopenharmony_ci"Cython directive 'language_level' not set"
103a5f9918aSopenharmony_ci]
104a5f9918aSopenharmony_ci
105a5f9918aSopenharmony_ciif platform.system() == 'Windows':
106a5f9918aSopenharmony_ci    for w in windows_ignore_warnings:
107a5f9918aSopenharmony_ci        warnings.filterwarnings('ignore', w)
108a5f9918aSopenharmony_ci
109a5f9918aSopenharmony_ci
110a5f9918aSopenharmony_ciclass Distribution(_Distribution):
111a5f9918aSopenharmony_ci    def __init__(self, attrs=None):
112a5f9918aSopenharmony_ci        _Distribution.__init__(self, attrs)
113a5f9918aSopenharmony_ci        if not self.ext_modules:
114a5f9918aSopenharmony_ci            return
115a5f9918aSopenharmony_ci        for idx in range(len(self.ext_modules)-1, -1, -1):
116a5f9918aSopenharmony_ci            ext = self.ext_modules[idx]
117a5f9918aSopenharmony_ci            if not isinstance(ext, Extension):
118a5f9918aSopenharmony_ci                continue
119a5f9918aSopenharmony_ci            setattr(self, ext.attr_name, None)
120a5f9918aSopenharmony_ci            self.global_options = [
121a5f9918aSopenharmony_ci                    (ext.option_name, None,
122a5f9918aSopenharmony_ci                        "include %s (default if %s is available)"
123a5f9918aSopenharmony_ci                        % (ext.feature_description, ext.feature_name)),
124a5f9918aSopenharmony_ci                    (ext.neg_option_name, None,
125a5f9918aSopenharmony_ci                        "exclude %s" % ext.feature_description),
126a5f9918aSopenharmony_ci            ] + self.global_options
127a5f9918aSopenharmony_ci            self.negative_opt = self.negative_opt.copy()
128a5f9918aSopenharmony_ci            self.negative_opt[ext.neg_option_name] = ext.option_name
129a5f9918aSopenharmony_ci
130a5f9918aSopenharmony_ci    def has_ext_modules(self):
131a5f9918aSopenharmony_ci        if not self.ext_modules:
132a5f9918aSopenharmony_ci            return False
133a5f9918aSopenharmony_ci        for ext in self.ext_modules:
134a5f9918aSopenharmony_ci            with_ext = self.ext_status(ext)
135a5f9918aSopenharmony_ci            if with_ext is None or with_ext:
136a5f9918aSopenharmony_ci                return True
137a5f9918aSopenharmony_ci        return False
138a5f9918aSopenharmony_ci
139a5f9918aSopenharmony_ci    def ext_status(self, ext):
140a5f9918aSopenharmony_ci        implementation = platform.python_implementation()
141a5f9918aSopenharmony_ci        if implementation not in ['CPython', 'PyPy']:
142a5f9918aSopenharmony_ci            return False
143a5f9918aSopenharmony_ci        if isinstance(ext, Extension):
144a5f9918aSopenharmony_ci            # the "build by default" behavior is implemented by this returning None
145a5f9918aSopenharmony_ci            with_ext = getattr(self, ext.attr_name) or os.environ.get('PYYAML_FORCE_{0}'.format(ext.feature_name.upper()))
146a5f9918aSopenharmony_ci            try:
147a5f9918aSopenharmony_ci                with_ext = int(with_ext)  # attempt coerce envvar to int
148a5f9918aSopenharmony_ci            except TypeError:
149a5f9918aSopenharmony_ci                pass
150a5f9918aSopenharmony_ci            return with_ext
151a5f9918aSopenharmony_ci        else:
152a5f9918aSopenharmony_ci            return True
153a5f9918aSopenharmony_ci
154a5f9918aSopenharmony_ci
155a5f9918aSopenharmony_ciclass Extension(_Extension):
156a5f9918aSopenharmony_ci
157a5f9918aSopenharmony_ci    def __init__(self, name, sources, feature_name, feature_description,
158a5f9918aSopenharmony_ci            feature_check, **kwds):
159a5f9918aSopenharmony_ci        if not with_cython:
160a5f9918aSopenharmony_ci            for filename in sources[:]:
161a5f9918aSopenharmony_ci                base, ext = os.path.splitext(filename)
162a5f9918aSopenharmony_ci                if ext == '.pyx':
163a5f9918aSopenharmony_ci                    sources.remove(filename)
164a5f9918aSopenharmony_ci                    sources.append('%s.c' % base)
165a5f9918aSopenharmony_ci        _Extension.__init__(self, name, sources, **kwds)
166a5f9918aSopenharmony_ci        self.feature_name = feature_name
167a5f9918aSopenharmony_ci        self.feature_description = feature_description
168a5f9918aSopenharmony_ci        self.feature_check = feature_check
169a5f9918aSopenharmony_ci        self.attr_name = 'with_' + feature_name.replace('-', '_')
170a5f9918aSopenharmony_ci        self.option_name = 'with-' + feature_name
171a5f9918aSopenharmony_ci        self.neg_option_name = 'without-' + feature_name
172a5f9918aSopenharmony_ci
173a5f9918aSopenharmony_ci
174a5f9918aSopenharmony_ciclass build_ext(_build_ext):
175a5f9918aSopenharmony_ci
176a5f9918aSopenharmony_ci    def run(self):
177a5f9918aSopenharmony_ci        optional = True
178a5f9918aSopenharmony_ci        disabled = True
179a5f9918aSopenharmony_ci        for ext in self.extensions:
180a5f9918aSopenharmony_ci            with_ext = self.distribution.ext_status(ext)
181a5f9918aSopenharmony_ci            if with_ext is None:
182a5f9918aSopenharmony_ci                disabled = False
183a5f9918aSopenharmony_ci            elif with_ext:
184a5f9918aSopenharmony_ci                optional = False
185a5f9918aSopenharmony_ci                disabled = False
186a5f9918aSopenharmony_ci                break
187a5f9918aSopenharmony_ci        if disabled:
188a5f9918aSopenharmony_ci            return
189a5f9918aSopenharmony_ci        try:
190a5f9918aSopenharmony_ci            _build_ext.run(self)
191a5f9918aSopenharmony_ci        except DistutilsPlatformError:
192a5f9918aSopenharmony_ci            exc = sys.exc_info()[1]
193a5f9918aSopenharmony_ci            if optional:
194a5f9918aSopenharmony_ci                log.warn(str(exc))
195a5f9918aSopenharmony_ci                log.warn("skipping build_ext")
196a5f9918aSopenharmony_ci            else:
197a5f9918aSopenharmony_ci                raise
198a5f9918aSopenharmony_ci
199a5f9918aSopenharmony_ci    def get_source_files(self):
200a5f9918aSopenharmony_ci        self.check_extensions_list(self.extensions)
201a5f9918aSopenharmony_ci        filenames = []
202a5f9918aSopenharmony_ci        for ext in self.extensions:
203a5f9918aSopenharmony_ci            if with_cython:
204a5f9918aSopenharmony_ci                self.cython_sources(ext.sources, ext)
205a5f9918aSopenharmony_ci            for filename in ext.sources:
206a5f9918aSopenharmony_ci                filenames.append(filename)
207a5f9918aSopenharmony_ci                base = os.path.splitext(filename)[0]
208a5f9918aSopenharmony_ci                for ext in ['c', 'h', 'pyx', 'pxd']:
209a5f9918aSopenharmony_ci                    filename = '%s.%s' % (base, ext)
210a5f9918aSopenharmony_ci                    if filename not in filenames and os.path.isfile(filename):
211a5f9918aSopenharmony_ci                        filenames.append(filename)
212a5f9918aSopenharmony_ci        return filenames
213a5f9918aSopenharmony_ci
214a5f9918aSopenharmony_ci    def get_outputs(self):
215a5f9918aSopenharmony_ci        self.check_extensions_list(self.extensions)
216a5f9918aSopenharmony_ci        outputs = []
217a5f9918aSopenharmony_ci        for ext in self.extensions:
218a5f9918aSopenharmony_ci            fullname = self.get_ext_fullname(ext.name)
219a5f9918aSopenharmony_ci            filename = os.path.join(self.build_lib,
220a5f9918aSopenharmony_ci                                    self.get_ext_filename(fullname))
221a5f9918aSopenharmony_ci            if os.path.isfile(filename):
222a5f9918aSopenharmony_ci                outputs.append(filename)
223a5f9918aSopenharmony_ci        return outputs
224a5f9918aSopenharmony_ci
225a5f9918aSopenharmony_ci    def build_extensions(self):
226a5f9918aSopenharmony_ci        self.check_extensions_list(self.extensions)
227a5f9918aSopenharmony_ci        for ext in self.extensions:
228a5f9918aSopenharmony_ci            with_ext = self.distribution.ext_status(ext)
229a5f9918aSopenharmony_ci            if with_ext is not None and not with_ext:
230a5f9918aSopenharmony_ci                continue
231a5f9918aSopenharmony_ci            if with_cython:
232a5f9918aSopenharmony_ci                ext.sources = self.cython_sources(ext.sources, ext)
233a5f9918aSopenharmony_ci            try:
234a5f9918aSopenharmony_ci                self.build_extension(ext)
235a5f9918aSopenharmony_ci            except (CompileError, LinkError):
236a5f9918aSopenharmony_ci                if with_ext is not None:
237a5f9918aSopenharmony_ci                    raise
238a5f9918aSopenharmony_ci                log.warn("Error compiling module, falling back to pure Python")
239a5f9918aSopenharmony_ci
240a5f9918aSopenharmony_ci
241a5f9918aSopenharmony_ciclass test(Command):
242a5f9918aSopenharmony_ci
243a5f9918aSopenharmony_ci    user_options = []
244a5f9918aSopenharmony_ci
245a5f9918aSopenharmony_ci    def initialize_options(self):
246a5f9918aSopenharmony_ci        pass
247a5f9918aSopenharmony_ci
248a5f9918aSopenharmony_ci    def finalize_options(self):
249a5f9918aSopenharmony_ci        pass
250a5f9918aSopenharmony_ci
251a5f9918aSopenharmony_ci    def run(self):
252a5f9918aSopenharmony_ci        build_cmd = self.get_finalized_command('build')
253a5f9918aSopenharmony_ci        build_cmd.run()
254a5f9918aSopenharmony_ci
255a5f9918aSopenharmony_ci        # running the tests this way can pollute the post-MANIFEST build sources
256a5f9918aSopenharmony_ci        # (see https://github.com/yaml/pyyaml/issues/527#issuecomment-921058344)
257a5f9918aSopenharmony_ci        # until we remove the test command, run tests from an ephemeral copy of the intermediate build sources
258a5f9918aSopenharmony_ci        tempdir = tempfile.TemporaryDirectory(prefix='test_pyyaml')
259a5f9918aSopenharmony_ci
260a5f9918aSopenharmony_ci        try:
261a5f9918aSopenharmony_ci            # have to create a subdir since we don't get dir_exists_ok on copytree until 3.8
262a5f9918aSopenharmony_ci            temp_test_path = pathlib.Path(tempdir.name) / 'pyyaml'
263a5f9918aSopenharmony_ci            shutil.copytree(build_cmd.build_lib, temp_test_path)
264a5f9918aSopenharmony_ci            sys.path.insert(0, str(temp_test_path))
265a5f9918aSopenharmony_ci            sys.path.insert(0, 'tests/lib')
266a5f9918aSopenharmony_ci
267a5f9918aSopenharmony_ci            import test_all
268a5f9918aSopenharmony_ci            if not test_all.main([]):
269a5f9918aSopenharmony_ci                raise DistutilsError("Tests failed")
270a5f9918aSopenharmony_ci        finally:
271a5f9918aSopenharmony_ci            try:
272a5f9918aSopenharmony_ci                # this can fail under Windows; best-effort cleanup
273a5f9918aSopenharmony_ci                tempdir.cleanup()
274a5f9918aSopenharmony_ci            except Exception:
275a5f9918aSopenharmony_ci                pass
276a5f9918aSopenharmony_ci
277a5f9918aSopenharmony_ci
278a5f9918aSopenharmony_cicmdclass = {
279a5f9918aSopenharmony_ci    'build_ext': build_ext,
280a5f9918aSopenharmony_ci    'test': test,
281a5f9918aSopenharmony_ci}
282a5f9918aSopenharmony_ciif bdist_wheel:
283a5f9918aSopenharmony_ci    cmdclass['bdist_wheel'] = bdist_wheel
284a5f9918aSopenharmony_ci
285a5f9918aSopenharmony_ci
286a5f9918aSopenharmony_ciif __name__ == '__main__':
287a5f9918aSopenharmony_ci
288a5f9918aSopenharmony_ci    setup(
289a5f9918aSopenharmony_ci        name=NAME,
290a5f9918aSopenharmony_ci        version=VERSION,
291a5f9918aSopenharmony_ci        description=DESCRIPTION,
292a5f9918aSopenharmony_ci        long_description=LONG_DESCRIPTION,
293a5f9918aSopenharmony_ci        author=AUTHOR,
294a5f9918aSopenharmony_ci        author_email=AUTHOR_EMAIL,
295a5f9918aSopenharmony_ci        license=LICENSE,
296a5f9918aSopenharmony_ci        platforms=PLATFORMS,
297a5f9918aSopenharmony_ci        url=URL,
298a5f9918aSopenharmony_ci        download_url=DOWNLOAD_URL,
299a5f9918aSopenharmony_ci        classifiers=CLASSIFIERS,
300a5f9918aSopenharmony_ci        project_urls=PROJECT_URLS,
301a5f9918aSopenharmony_ci
302a5f9918aSopenharmony_ci        package_dir={'': 'lib'},
303a5f9918aSopenharmony_ci        packages=['yaml', '_yaml'],
304a5f9918aSopenharmony_ci        ext_modules=[
305a5f9918aSopenharmony_ci            Extension('yaml._yaml', ['yaml/_yaml.pyx'],
306a5f9918aSopenharmony_ci                'libyaml', "LibYAML bindings", LIBYAML_CHECK,
307a5f9918aSopenharmony_ci                libraries=['yaml']),
308a5f9918aSopenharmony_ci        ],
309a5f9918aSopenharmony_ci
310a5f9918aSopenharmony_ci        distclass=Distribution,
311a5f9918aSopenharmony_ci        cmdclass=cmdclass,
312a5f9918aSopenharmony_ci        python_requires='>=3.6',
313a5f9918aSopenharmony_ci    )
314