1 """distutils.command.check
3 Implements the Distutils 'check' command.
7 from ..core
import Command
8 from ..errors
import DistutilsSetupError
10 with contextlib
.suppress(ImportError):
12 import docutils
.parsers
.rst
13 import docutils
.frontend
16 class SilentReporter(docutils
.utils
.Reporter
):
25 error_handler
='replace',
29 source
, report_level
, halt_level
, stream
, debug
, encoding
, error_handler
32 def system_message(self
, level
, message
, *children
, **kwargs
):
33 self
.messages
.append((level
, message
, children
, kwargs
))
34 return docutils
.nodes
.system_message(
35 message
, level
=level
, type=self
.levels
[level
], *children
, **kwargs
40 """This command checks the meta-data of the package."""
42 description
= "perform some checks on the package"
44 ('metadata', 'm', 'Verify meta-data'),
49 'Checks if long string meta-data syntax '
50 'are reStructuredText-compliant'
53 ('strict', 's', 'Will exit with an error if a check fails'),
56 boolean_options
= ['metadata', 'restructuredtext', 'strict']
58 def initialize_options(self
):
59 """Sets default values for options."""
60 self
.restructuredtext
= 0
65 def finalize_options(self
):
69 """Counts the number of warnings that occurs."""
71 return Command
.warn(self
, msg
)
74 """Runs the command."""
75 # perform the various tests
78 if self
.restructuredtext
:
79 if 'docutils' in globals():
81 self
.check_restructuredtext()
82 except TypeError as exc
:
83 raise DistutilsSetupError(str(exc
))
85 raise DistutilsSetupError('The docutils package is needed.')
87 # let's raise an error in strict mode, if we have at least
89 if self
.strict
and self
._warnings
> 0:
90 raise DistutilsSetupError('Please correct your package.')
92 def check_metadata(self
):
93 """Ensures that all required elements of meta-data are supplied.
98 Warns if any are missing.
100 metadata
= self
.distribution
.metadata
103 for attr
in 'name', 'version':
104 if not getattr(metadata
, attr
, None):
108 self
.warn("missing required meta-data: %s" % ', '.join(missing
))
110 def check_restructuredtext(self
):
111 """Checks if the long string fields are reST-compliant."""
112 data
= self
.distribution
.get_long_description()
113 for warning
in self
._check
_rst
_data
(data
):
114 line
= warning
[-1].get('line')
118 warning
= '{} (line {})'.format(warning
[1], line
)
121 def _check_rst_data(self
, data
):
122 """Returns warnings when the provided data doesn't compile."""
123 # the include and csv_table directives need this to be a path
124 source_path
= self
.distribution
.script_name
or 'setup.py'
125 parser
= docutils
.parsers
.rst
.Parser()
126 settings
= docutils
.frontend
.OptionParser(
127 components
=(docutils
.parsers
.rst
.Parser
,)
128 ).get_default_values()
129 settings
.tab_width
= 4
130 settings
.pep_references
= None
131 settings
.rfc_references
= None
132 reporter
= SilentReporter(
134 settings
.report_level
,
136 stream
=settings
.warning_stream
,
137 debug
=settings
.debug
,
138 encoding
=settings
.error_encoding
,
139 error_handler
=settings
.error_encoding_error_handler
,
142 document
= docutils
.nodes
.document(settings
, reporter
, source
=source_path
)
143 document
.note_source(source_path
, -1)
145 parser
.parse(data
, document
)
146 except AttributeError as e
:
147 reporter
.messages
.append(
148 (-1, 'Could not finish the parsing: %s.' % e
, '', {})
151 return reporter
.messages