ยปCore Development>Code coverage>Lib/distutils/command/check.py

Python code coverage for Lib/distutils/command/check.py

#countcontent
1n/a"""distutils.command.check
2n/a
3n/aImplements the Distutils 'check' command.
4n/a"""
5n/afrom distutils.core import Command
6n/afrom distutils.errors import DistutilsSetupError
7n/a
8n/atry:
9n/a # docutils is installed
10n/a from docutils.utils import Reporter
11n/a from docutils.parsers.rst import Parser
12n/a from docutils import frontend
13n/a from docutils import nodes
14n/a from io import StringIO
15n/a
16n/a class SilentReporter(Reporter):
17n/a
18n/a def __init__(self, source, report_level, halt_level, stream=None,
19n/a debug=0, encoding='ascii', error_handler='replace'):
20n/a self.messages = []
21n/a Reporter.__init__(self, source, report_level, halt_level, stream,
22n/a debug, encoding, error_handler)
23n/a
24n/a def system_message(self, level, message, *children, **kwargs):
25n/a self.messages.append((level, message, children, kwargs))
26n/a return nodes.system_message(message, level=level,
27n/a type=self.levels[level],
28n/a *children, **kwargs)
29n/a
30n/a HAS_DOCUTILS = True
31n/aexcept Exception:
32n/a # Catch all exceptions because exceptions besides ImportError probably
33n/a # indicate that docutils is not ported to Py3k.
34n/a HAS_DOCUTILS = False
35n/a
36n/aclass check(Command):
37n/a """This command checks the meta-data of the package.
38n/a """
39n/a description = ("perform some checks on the package")
40n/a user_options = [('metadata', 'm', 'Verify meta-data'),
41n/a ('restructuredtext', 'r',
42n/a ('Checks if long string meta-data syntax '
43n/a 'are reStructuredText-compliant')),
44n/a ('strict', 's',
45n/a 'Will exit with an error if a check fails')]
46n/a
47n/a boolean_options = ['metadata', 'restructuredtext', 'strict']
48n/a
49n/a def initialize_options(self):
50n/a """Sets default values for options."""
51n/a self.restructuredtext = 0
52n/a self.metadata = 1
53n/a self.strict = 0
54n/a self._warnings = 0
55n/a
56n/a def finalize_options(self):
57n/a pass
58n/a
59n/a def warn(self, msg):
60n/a """Counts the number of warnings that occurs."""
61n/a self._warnings += 1
62n/a return Command.warn(self, msg)
63n/a
64n/a def run(self):
65n/a """Runs the command."""
66n/a # perform the various tests
67n/a if self.metadata:
68n/a self.check_metadata()
69n/a if self.restructuredtext:
70n/a if HAS_DOCUTILS:
71n/a self.check_restructuredtext()
72n/a elif self.strict:
73n/a raise DistutilsSetupError('The docutils package is needed.')
74n/a
75n/a # let's raise an error in strict mode, if we have at least
76n/a # one warning
77n/a if self.strict and self._warnings > 0:
78n/a raise DistutilsSetupError('Please correct your package.')
79n/a
80n/a def check_metadata(self):
81n/a """Ensures that all required elements of meta-data are supplied.
82n/a
83n/a name, version, URL, (author and author_email) or
84n/a (maintainer and maintainer_email)).
85n/a
86n/a Warns if any are missing.
87n/a """
88n/a metadata = self.distribution.metadata
89n/a
90n/a missing = []
91n/a for attr in ('name', 'version', 'url'):
92n/a if not (hasattr(metadata, attr) and getattr(metadata, attr)):
93n/a missing.append(attr)
94n/a
95n/a if missing:
96n/a self.warn("missing required meta-data: %s" % ', '.join(missing))
97n/a if metadata.author:
98n/a if not metadata.author_email:
99n/a self.warn("missing meta-data: if 'author' supplied, " +
100n/a "'author_email' must be supplied too")
101n/a elif metadata.maintainer:
102n/a if not metadata.maintainer_email:
103n/a self.warn("missing meta-data: if 'maintainer' supplied, " +
104n/a "'maintainer_email' must be supplied too")
105n/a else:
106n/a self.warn("missing meta-data: either (author and author_email) " +
107n/a "or (maintainer and maintainer_email) " +
108n/a "must be supplied")
109n/a
110n/a def check_restructuredtext(self):
111n/a """Checks if the long string fields are reST-compliant."""
112n/a data = self.distribution.get_long_description()
113n/a for warning in self._check_rst_data(data):
114n/a line = warning[-1].get('line')
115n/a if line is None:
116n/a warning = warning[1]
117n/a else:
118n/a warning = '%s (line %s)' % (warning[1], line)
119n/a self.warn(warning)
120n/a
121n/a def _check_rst_data(self, data):
122n/a """Returns warnings when the provided data doesn't compile."""
123n/a source_path = StringIO()
124n/a parser = Parser()
125n/a settings = frontend.OptionParser(components=(Parser,)).get_default_values()
126n/a settings.tab_width = 4
127n/a settings.pep_references = None
128n/a settings.rfc_references = None
129n/a reporter = SilentReporter(source_path,
130n/a settings.report_level,
131n/a settings.halt_level,
132n/a stream=settings.warning_stream,
133n/a debug=settings.debug,
134n/a encoding=settings.error_encoding,
135n/a error_handler=settings.error_encoding_error_handler)
136n/a
137n/a document = nodes.document(settings, reporter, source=source_path)
138n/a document.note_source(source_path, -1)
139n/a try:
140n/a parser.parse(data, document)
141n/a except AttributeError as e:
142n/a reporter.messages.append(
143n/a (-1, 'Could not finish the parsing: %s.' % e, '', {}))
144n/a
145n/a return reporter.messages