def test_rewrite_readme( tmp_pathplus, demo_environment, file_regression: FileRegressionFixture, filename, fixed_date, ): demo_environment.globals["version"] = "1.2.3" demo_environment.globals["enable_docs"] = True demo_environment.globals["docker_shields"] = False demo_environment.globals["docker_name"] = '' demo_environment.globals["enable_pre_commit"] = True demo_environment.globals["license"] = "MIT" demo_environment.globals["primary_conda_channel"] = "octocat" readme_file = tmp_pathplus / "README.rst" with resource(tests.test_files.test_readme_input, filename) as p: readme_file.write_clean(PathPlus(p).read_text()) managed_files = rewrite_readme(tmp_pathplus, demo_environment) assert managed_files == ["README.rst"] check_file_output(readme_file, file_regression) rendered = render(readme_file.read_text(), stream=sys.stderr) assert rendered is not None check_file_regression(rendered, file_regression, extension=".html")
def show_longdesc(): if not HAVE_README: logging.error( "To check the long description, we need the 'readme_renderer' " "package. " "(It is included if you install `zest.releaser[recommended]`)") sys.exit(1) filename = tempfile.mktemp('.html') # Note: for the setup.py call we use _execute_command() from our # utils module. This makes sure the python path is set up right. longdesc = _execute_command(utils.setup_py('--long-description')) warnings = io.StringIO() html = render(longdesc, warnings) if html is None: logging.error( 'Error generating html. Invalid ReST.') rst_filename = tempfile.mktemp('.rst') with open(rst_filename, 'wb') as rst_file: rst_file.write(longdesc.encode('utf-8')) warning_text = warnings.getvalue() warning_text = warning_text.replace('<string>', rst_filename) print(warning_text) sys.exit(1) if '<html' not in html[:20]: # Add a html declaration including utf-8 indicator html = HTML_PREFIX + html + HTML_POSTFIX with open(filename, 'wb') as fh: fh.write(html.encode('utf-8')) url = 'file://' + filename logging.info("Opening %s in your webbrowser.", url) webbrowser.open(url)
def test_rendering(self): out = io.StringIO() actual = rst.render(README_TEXT, out) if actual is None: print('Rendering error!') print(out.getvalue()) assert False
def render(text, window=ERROR_WINDOW): out = io.StringIO() rendered = rst.render(text, out) if rendered: return rendered print('.rst Rendering error!', file=sys.stderr) error = out.getvalue() try: error_line = int(error.split(':')[1]) except Exception: error_line = -1 print(error, file=sys.stderr) print('', file=sys.stderr) lines = text.splitlines() fmt = '%0{}d:'.format(len(str(1 + len(lines)))) half_win = (window + 1) // 2 for i, line in enumerate(lines): if error_line is None or not window or abs(i - error_line) <= half_win: symbol = '->' if i == error_line - 1 else ' ' print(symbol, fmt % (i + 1), line, file=sys.stderr)
def test_pypi_rendering(): # Adapted from `https://stackoverflow.com/questions/46766570/`. readme = Path(__file__).parent.parent / "README.rst" warnings = StringIO() with readme.open() as file_: html = render(file_.read(), stream=warnings) warnings.seek(0) assert html is not None, warnings.read()
def test_rst_header_only(): warnings = io.StringIO() assert render(""" Header ====== """, stream=warnings) is None assert "No content rendered from RST source." in warnings.getvalue()
def test_rst_raw(): warnings = six.StringIO() assert render(""" .. raw:: html <script>I am evil</script> """, stream=warnings) is None assert '"raw" directive disabled' in warnings.getvalue()
def test_rst_raw(): warnings = io.StringIO() assert render(""" .. raw:: html <script>I am evil</script> """, stream=warnings) is None assert '"raw" directive disabled' in warnings.getvalue()
def test_header_and_malformed_emits_docutils_warning_only(): warnings = io.StringIO() assert render(""" Header ====== ====== """, stream=warnings) is None assert len(warnings.getvalue().splitlines()) == 1 assert "No content rendered from RST source." not in warnings.getvalue()
def test_README_as_PyPi_landing_page(monkeypatch): long_desc = subprocess.check_output( "python setup.py --long-description".split(), cwd=proj_path) assert long_desc err_stream = _WarningStream() result = rst.render( long_desc, # The specific options are a selective copy of: # https://github.com/pypa/readme_renderer/blob/master/readme_renderer/rst.py stream=err_stream, halt_level=2, # 2=WARN, 1=INFO ) assert result, err_stream
def test_rst_fixtures(rst_filename, html_filename): # Get our Markup with io.open(rst_filename, encoding='utf-8') as f: rst_markup = f.read() # Get our expected with io.open(html_filename, encoding="utf-8") as f: expected = f.read() out = render(rst_markup) if "<" in expected: assert out == expected else: assert out is None
def test_README_as_PyPi_landing_page(monkeypatch): """Not executing `setup.py build-sphinx` to control log/stderr visibility with pytest""" long_desc = subprocess.check_output( "python setup.py --long-description".split(), cwd=proj_path) assert long_desc is not None, "Long_desc is null!" err_stream = _WarningStream() result = rst.render( long_desc, # The specific options are a selective copy of: # https://github.com/pypa/readme_renderer/blob/master/readme_renderer/rst.py stream=err_stream, halt_level=2, # 2=WARN, 1=INFO ) assert result, err_stream
def test_make_contributing(tmp_pathplus, demo_environment, file_regression: FileRegressionFixture): assert make_contributing(tmp_pathplus, demo_environment) == [ "CONTRIBUTING.rst", "CONTRIBUTING.md" ] assert not (tmp_pathplus / "CONTRIBUTING.md").is_file() assert (tmp_pathplus / "CONTRIBUTING.rst").is_file() check_file_output(tmp_pathplus / "CONTRIBUTING.rst", file_regression) (tmp_pathplus / "CONTRIBUTING.md").touch() assert (tmp_pathplus / "CONTRIBUTING.md").is_file() assert make_contributing(tmp_pathplus, demo_environment) == [ "CONTRIBUTING.rst", "CONTRIBUTING.md" ] assert not (tmp_pathplus / "CONTRIBUTING.md").is_file() assert (tmp_pathplus / "CONTRIBUTING.rst").is_file() rendered = render((tmp_pathplus / "CONTRIBUTING.rst").read_text(), stream=sys.stderr) check_file_regression(rendered, file_regression, extension=".html")
def _generate_rst_readme(*, creole_readme_path): with creole_readme_path.open('r') as f: creole_readme = f.read().strip() # convert creole into html html_readme = creole2html(creole_readme) # convert html to ReSt rest_readme = html2rest( html_readme, emitter_kwargs={ 'unknown_emit': raise_unknown_node # raise a error if a unknown node found }) # Check if generated ReSt is valid, see also: # https://pypi.org/help/#description-content-type rendered = render(rest_readme, stream=sys.stderr) if rendered is None: sys.exit(1) return rest_readme
def test_rst_002(): assert render('http://mymalicioussite.com/') == ( '<p><a href="http://mymalicioussite.com/" rel="nofollow">' 'http://mymalicioussite.com/</a></p>\n')
def test_rst_001(): assert render('Hello') == '<p>Hello</p>\n'
from __future__ import absolute_import, print_function import argparse from readme_renderer.rst import render import sys if __name__ == '__main__': parser = argparse.ArgumentParser( description="Renders a .rst README to HTML", ) parser.add_argument('input', help="Input README file", type=argparse.FileType('r')) parser.add_argument('-o', '--output', help="Output file (default: stdout)", type=argparse.FileType('w'), default='-') args = parser.parse_args() rendered = render(args.input.read(), stream=sys.stderr) if rendered is None: sys.exit(1) print(rendered, file=args.output)
def test_readme_format(self): with open('README.rst') as fp: assert render(fp.read())
def test_rst_empty_file(): warnings = io.StringIO() assert render("", stream=warnings) is None assert "No content rendered from RST source." in warnings.getvalue()
def inspect(obj): # (DistInfoProvider) -> dict about = obj.basic_metadata() about["dist_info"] = {} about["valid"] = True has_dist_info = True try: record = obj.get_record() except errors.WheelValidationError as e: about["valid"] = False about["validation_error"] = { "type": type(e).__name__, "str": str(e), } has_dist_info = not isinstance(e, errors.DistInfoError) else: about["dist_info"]["record"] = record.for_json() if isinstance(obj, FileProvider): try: verify_record(obj, record) except errors.WheelValidationError as e: about["valid"] = False about["validation_error"] = { "type": type(e).__name__, "str": str(e), } if has_dist_info: try: metadata = obj.get_metadata() except errors.WheelValidationError as e: metadata = {} about["valid"] = False about["validation_error"] = { "type": type(e).__name__, "str": str(e), } else: about["dist_info"]["metadata"] = metadata try: about["dist_info"]["wheel"] = obj.get_wheel_info() except errors.WheelValidationError as e: about["valid"] = False about["validation_error"] = { "type": type(e).__name__, "str": str(e), } for fname, parser, key in EXTRA_DIST_INFO_FILES: try: with obj.open_dist_info_file(fname) as binfp, io.TextIOWrapper( binfp, "utf-8") as txtfp: about["dist_info"][key] = parser(txtfp) except errors.MissingDistInfoFileError: pass if obj.has_dist_info_file("zip-safe"): about["dist_info"]["zip_safe"] = True elif obj.has_dist_info_file("not-zip-safe"): about["dist_info"]["zip_safe"] = False else: metadata = {} about["derived"] = { "description_in_body": "BODY" in metadata, "description_in_headers": "description" in metadata, } if "BODY" in metadata and "description" not in metadata: metadata["description"] = metadata["BODY"] metadata.pop("BODY", None) readme = metadata.get("description") if readme is not None: metadata["description"] = {"length": len(metadata["description"])} dct = metadata.get("description_content_type") if dct is None or split_content_type(dct)[:2] == ("text", "x-rst"): about["derived"]["readme_renders"] = render(readme) is not None else: about["derived"]["readme_renders"] = True else: about["derived"]["readme_renders"] = None if metadata.get("keywords") is not None: ( about["derived"]["keywords"], about["derived"]["keyword_separator"], ) = split_keywords(metadata["keywords"]) else: about["derived"]["keywords"], about["derived"][ "keyword_separator"] = [], None about["derived"]["keywords"] = sorted(set(about["derived"]["keywords"])) about["derived"]["dependencies"] = sorted( unique_projects(req["name"] for req in metadata.get("requires_dist", []))) about["derived"]["modules"] = extract_modules( [rec["path"] for rec in about["dist_info"].get("record", [])]) return about
def inspect(self): namebits = self.parsed_filename about = { "filename": os.path.basename(self.path), "project": namebits.project, "version": namebits.version, "buildver": namebits.build, "pyver": namebits.python_tags, "abi": namebits.abi_tags, "arch": namebits.platform_tags, } try: record = self.record except WheelValidationError as e: record = None about["valid"] = False about["validation_error"] = { "type": type(e).__name__, "str": str(e), } else: try: self.verify_record() except WheelValidationError as e: about["valid"] = False about["validation_error"] = { "type": type(e).__name__, "str": str(e), } else: about["valid"] = True about["file"] = {"size": os.path.getsize(self.path)} self.fp.seek(0) about["file"]["digests"] = digest_file(self.fp, ["md5", "sha256"]) about["dist_info"] = {} if self.metadata is not None: about["dist_info"]["metadata"] = self.metadata if record is not None: about["dist_info"]["record"] = record.for_json() if self.wheel_info is not None: about["dist_info"]["wheel"] = self.wheel_info for fname, parser, key in EXTRA_DIST_INFO_FILES: info = self._get_dist_info(fname) if info is not None: with self.zipfile.open(info) as fp: about["dist_info"][key] = parser( io.TextIOWrapper(fp, 'utf-8')) if self._get_dist_info('zip-safe') is not None: about["dist_info"]["zip_safe"] = True elif self._get_dist_info('not-zip-safe') is not None: about["dist_info"]["zip_safe"] = False md = about["dist_info"].get("metadata", {}) about["derived"] = { "description_in_body": "BODY" in md, "description_in_headers": "description" in md, } if "BODY" in md and "description" not in md: md["description"] = md["BODY"] md.pop("BODY", None) readme = md.get("description") if readme is not None: md["description"] = {"length": len(md["description"])} dct = md.get("description_content_type") if dct is None or parse_header(dct)[0] == 'text/x-rst': about["derived"]["readme_renders"] = render(readme) is not None else: about["derived"]["readme_renders"] = True else: about["derived"]["readme_renders"] = None if md.get("keywords") is not None: about["derived"]["keywords"], about["derived"]["keyword_separator"] \ = split_keywords(md["keywords"]) else: about["derived"]["keywords"], about["derived"]["keyword_separator"] \ = [], None about["derived"]["keywords"] = sorted(set( about["derived"]["keywords"])) about["derived"]["dependencies"] = sorted( unique_projects(req["name"] for req in md.get("requires_dist", []))) about["derived"]["modules"] = extract_modules( [rec["path"] for rec in about["dist_info"].get("record", [])]) return about
from setuptools import setup, find_packages from os import path from readme_renderer import rst this_directory = path.abspath(path.dirname(__file__)) with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: long_description = rst.render(f.read()) setup( name='moleculer-client', version='0.1.4', description= 'Simple Client in python to communicate with MoleculerJs Microservices using NATS', long_description=long_description, author='Caio Filus Felisbino', author_email='*****@*****.**', url='https://github.com/CaioFilus/moleculer-client', license='MIT', packages=['moleculer_client'], install_requires=[ 'nats-python==0.7.0', ], include_package_data=True, keywords=['python', 'microservices', 'NATs'], )
def test_rst_002(): assert render('http://mymalicioussite.com/') == ( '<p><a href="http://mymalicioussite.com/" rel="nofollow">' 'http://mymalicioussite.com/</a></p>\n' )