    def write_pdf(self, target=None, zoom=1, finisher=None, **options):
        """Paint the pages in a PDF file, with metadata.

        :type target:
            :class:`str`, :class:`pathlib.Path` or :term:`file object`
        :param target:
            A filename where the PDF file is generated, a file object, or
            :obj:`None`.
        :param float zoom:
            The zoom factor in PDF units per CSS units.  **Warning**:
            All CSS units are affected, including physical units like
            ``cm`` and named sizes like ``A4``.  For values other than
            1, the physical CSS units will thus be "wrong".
        :type finisher: :term:`callable`
        :param finisher:
            A finisher function or callable that accepts the document and a
            :class:`pydyf.PDF` object as parameters. Can be passed to perform
            post-processing on the PDF right before the trailer is written.
        :param options:
            The ``options`` parameter includes by default the
            :data:`weasyprint.DEFAULT_OPTIONS` values.
        :returns:
            The PDF as :obj:`bytes` if ``target`` is not provided or
            :obj:`None`, otherwise :obj:`None` (the PDF is written to
            ``target``).

        """
        new_options = DEFAULT_OPTIONS.copy()
        new_options.update(options)
        options = new_options

        # Set default PDF version for PDF variants.
        if variant := options['pdf_variant']:
            _, properties = VARIANTS[variant]
            if 'version' in properties and not options['pdf_version']:
                options['pdf_version'] = properties['version']
            if 'identifier' in properties and not options['pdf_identifier']:
                options['pdf_identifier'] = properties['identifier']

        pdf = generate_pdf(self, target, zoom, **options)

        if finisher:
            finisher(self, pdf)

        identifier = options['pdf_identifier']
        compress = not options['uncompressed_pdf']
        version = options['pdf_version']

        if target is None:
            output = io.BytesIO()
            pdf.write(output, version, identifier, compress)
            return output.getvalue()

        if hasattr(target, 'write'):
            pdf.write(target, version, identifier, compress)
        else:
            with open(target, 'wb') as fd:
                pdf.write(fd, version, identifier, compress)
Paint the pages in a PDF file, with metadata.

:type target:
:class:`str`, :class:`pathlib.Path` or :term:`file object`
:param target:
A filename where the PDF file is generated, a file object, or
:obj:`None`.
:param float zoom:
The zoom factor in PDF units per CSS units.  **Warning**:
All CSS units are affected, including physical units like
``cm`` and named sizes like ``A4``.  For values other than
1, the physical CSS units will thus be "wrong".
:type finisher: :term:`callable`
:param finisher:
A finisher function or callable that accepts the document and a
:class:`pydyf.PDF` object as parameters. Can be passed to perform
post-processing on the PDF right before the trailer is written.
:param options:
The ``options`` parameter includes by default the
:data:`weasyprint.DEFAULT_OPTIONS` values.
:returns:
The PDF as :obj:`bytes` if ``target`` is not provided or
:obj:`None`, otherwise :obj:`None` (the PDF is written to
``target``).
weasyprint/document.py