mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Modernize packaging
Switch to pyproject.toml packaging, using hatchling. - Replace all uses of setup.py with updated equivalent - BREAKING: Change extra name `amazon_ses` to `amazon-ses`, to comply with Python packaging name normalization - Use hatch custom build hook to freeze version number in readme (previously custom setup.py code) - Move separate requirements for dev, docs, tests into their own requirements.txt files - Fix AnymailImproperlyInstalled to correctly refer to package extra name - Update testing documentation - Update docs readme rendering to match PyPI (and avoid setup.py) - In tox tests, use isolated builds and update pip - Remove AUTHORS.txt (it just referred to GitHub)
This commit is contained in:
109
docs/_readme/render.py
Normal file
109
docs/_readme/render.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python
|
||||
# Render a README file (roughly) as it would appear on PyPI
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from importlib.metadata import PackageNotFoundError, metadata
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional
|
||||
|
||||
import readme_renderer.rst
|
||||
from docutils.core import publish_string
|
||||
from docutils.utils import SystemMessage
|
||||
|
||||
# Docutils template.txt in our directory:
|
||||
DEFAULT_TEMPLATE_FILE = Path(__file__).with_name("template.txt").absolute()
|
||||
|
||||
|
||||
def get_package_readme(package: str) -> str:
|
||||
# Note: "description" was added to metadata in Python 3.10
|
||||
return metadata(package)["description"]
|
||||
|
||||
|
||||
class ReadMeHTMLWriter(readme_renderer.rst.Writer):
|
||||
translator_class = readme_renderer.rst.ReadMeHTMLTranslator
|
||||
|
||||
def interpolation_dict(self) -> Dict[str, str]:
|
||||
result = super().interpolation_dict()
|
||||
# clean the same parts as readme_renderer.rst.render:
|
||||
clean = readme_renderer.rst.clean
|
||||
result["docinfo"] = clean(result["docinfo"])
|
||||
result["body"] = result["fragment"] = clean(result["fragment"])
|
||||
return result
|
||||
|
||||
|
||||
def render(source_text: str, warning_stream=sys.stderr) -> Optional[str]:
|
||||
# Adapted from readme_renderer.rst.render
|
||||
settings = readme_renderer.rst.SETTINGS.copy()
|
||||
settings.update(
|
||||
{
|
||||
"warning_stream": warning_stream,
|
||||
"template": DEFAULT_TEMPLATE_FILE,
|
||||
# Input and output are text str (we handle decoding/encoding):
|
||||
"input_encoding": "unicode",
|
||||
"output_encoding": "unicode",
|
||||
# Exit with error on docutils warning or above.
|
||||
# (There's discussion of having readme_renderer ignore warnings;
|
||||
# this ensures they'll be treated as errors here.)
|
||||
"halt_level": 2, # (docutils.utils.Reporter.WARNING_LEVEL)
|
||||
# Report all docutils warnings or above.
|
||||
# (The readme_renderer default suppresses this output.)
|
||||
"report_level": 2, # (docutils.utils.Reporter.WARNING_LEVEL)
|
||||
}
|
||||
)
|
||||
|
||||
writer = ReadMeHTMLWriter()
|
||||
|
||||
try:
|
||||
return publish_string(
|
||||
source_text,
|
||||
writer=writer,
|
||||
settings_overrides=settings,
|
||||
)
|
||||
except SystemMessage:
|
||||
warning_stream.write("Error rendering readme source.\n")
|
||||
return None
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Render readme file as it would appear on PyPI"
|
||||
)
|
||||
input_group = parser.add_mutually_exclusive_group(required=True)
|
||||
input_group.add_argument(
|
||||
"-p", "--package", help="Source readme from package's metadata"
|
||||
)
|
||||
input_group.add_argument(
|
||||
"-i",
|
||||
"--input",
|
||||
help="Source readme.rst file ('-' for stdin)",
|
||||
type=argparse.FileType("r"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
help="Output file (default: stdout)",
|
||||
type=argparse.FileType("w"),
|
||||
default="-",
|
||||
)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
if args.package:
|
||||
try:
|
||||
source_text = get_package_readme(args.package)
|
||||
except PackageNotFoundError:
|
||||
print(f"Package not installed: {args.package!r}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
if source_text is None:
|
||||
print(f"No metadata readme for {args.package!r}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
else:
|
||||
source_text = args.input.read()
|
||||
rendered = render(source_text)
|
||||
if rendered is None:
|
||||
sys.exit(2)
|
||||
args.output.write(rendered)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user