Skip to content

[weasyprint] Add stubs for WeasyPrint 69.0#15349

Draft
TuringTux wants to merge 52 commits into
python:mainfrom
TuringTux:weasyprint
Draft

[weasyprint] Add stubs for WeasyPrint 69.0#15349
TuringTux wants to merge 52 commits into
python:mainfrom
TuringTux:weasyprint

Conversation

@TuringTux

@TuringTux TuringTux commented Jan 31, 2026

Copy link
Copy Markdown

This adds a really small set of annotations for WeasyPrint 69.0.

I use WeasyPrint in one of my projects, use only a few methods, but would like to have my type checker working for these.

Is it okay if a submit this to typeshed, even though it will be only partially annotated?

@github-actions

This comment has been minimized.

@srittau

srittau commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator

Is it okay if a submit this to typeshed, even though it will be only partially annotated?

Yes, that's perfectly fine.

@TuringTux

Copy link
Copy Markdown
Author

Thanks for the quick reply! Then I will see to it that at least my use case is completely mapped (and the checks run green, I suppose), and would then change this PR to ready.

@TuringTux

Copy link
Copy Markdown
Author

Well, I haven't forgotten about this, and funnily enough, today the organisation behind WeasyPrint sort of doubled down on the fact they don't like type hints: https://www.courtbouillon.org/blog/00064-types/

Meaning this PR could become very relevant if I ever get the time to implement something, which I still hope I do soon-ish.

@liZe

liZe commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Hi!

WeasyPrint has a pretty stable, official public API. All the other functions are not supposed to be used by WeasyPrint users, and regularly break between versions.

I don’t know what the best solution is in this case, but I think that adding type hints only for this public API is probably easier and better.

@TuringTux

Copy link
Copy Markdown
Author

That would also be sufficient for me. The current state of this PR is auto-generated, by the tool provided in the Typeshed repo. Does that mean I could remove a lot of the current files, and only include those corresponding to the Python files containing the public API?

@liZe

liZe commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

That would also be sufficient for me. The current state of this PR is auto-generated, by the tool provided in the Typeshed repo. Does that mean I could remove a lot of the current files, and only include those corresponding to the Python files containing the public API?

I think so.

@TuringTux TuringTux changed the title [weasyprint] Add stubs for WeasyPrint 68.0 [weasyprint] Add stubs for WeasyPrint 69.0 Jul 13, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@srittau

srittau commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

A hint to maybe help this get over the finish line: I've just opened #16011 to add some guidance about missing dependencies. For your convenience, I've copied it here:


When a third-party stub package depends on another package, there are several
strategies available, depending on whether the other package is typed.

  1. If the other package is typed and includes a py.typed marker, add that
    package to the dependencies key in `METADATA.toml. This might fail the
    stub uploader checks, in which case you can ask the maintainers for help.

  2. Otherwise, if a type package is available, add that package to the
    dependencies key. If the type package originates from typeshed, the
    stub uploader checks should succeed.

  3. In case the dependency in untyped and no stubs are available, you may stub
    the dependency in your type stubs. For example:

    from typing import Any
    # from fruzzle import Frobnicator  # won't work
    
    _Frobnicator: TypeAlias = Any  # actually fruzzle.Frobnicator

    In more complex or advanced cases you may instead opt to add a stubs
    is a separate helper package:

    # stubs/my-stubs/my_stubs/_fruzzle.pyi
    
    # Utility stubs for the untyped "fruzzle" package.
    
    from typing import Any, Protocol
    
    Frobnicator: TypeAlias = Any
    
    class Flubberer(Protocol):
        def flubb_it(self, x: int, /) -> str: ...

moritajavier239-rgb

This comment was marked as off-topic.

@github-actions

This comment has been minimized.

Comment thread stubs/weasyprint/weasyprint/css/units.pyi Outdated
@github-actions

This comment has been minimized.

@srittau

srittau commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

@srittau Should I squash the commits once I am done with this? I guess the individual stages of my progress will later not be particularly meaningful...

Thanks for offering, but we generally prefer to keep the commits non-squashed. We will squash merge at the end anyway, and that makes it easier for us to review single steps.

@srittau

srittau commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Some of the stubtest error can be fixed by setting partial-stub to true in METADATA.toml. This should suppress all errors about failed to find stubs. It it doesn't, in addition add those to a new @tests/stubs/icalendar/@tests/stubtest_allowlist.txt file. (See other stubs in typeshed for examples.) The remaining hits should be looked at.

If you have incomplete modules (i.e. modules that don't have all items), you can use this construct (usually at the end of files):

# beginning of file
from _typeshed import Incomplete

#end of file
def __getattr__(name: str, /): ...  # incomplete module

Similarly, for incomplete classes you can use:

class Foo:
    ...
    def __getattr__(self, name: str, /): ...  # incomplete class

If you deliberately don't want to include an item that's flagged by stubtest, you can also add it to the allowlist mentioned above, with a short comment explaining why that is. (Again, see other allowlists in typeshed.)

This reverts commit 190b8a6.

# Conflicts:
#	stubs/weasyprint/weasyprint/css/counters.pyi
@TuringTux

Copy link
Copy Markdown
Author

Per the suggestion in #15349 (comment), I've just restored all the other stub files.

Does that mean that I now won't need to set partial-stub (as all stub files are now there), but of course still need to fix the errors which are now in these files?

@github-actions

This comment has been minimized.

@srittau

srittau commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Correct, you don't need the partial-stub setting.

@srittau

srittau commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

The rest of the mypy failures look very manageable. I would just suppress the untyped decorator warnings for now (using # type: ignore [untyped-decorator].

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@TuringTux

Copy link
Copy Markdown
Author

I might have reduced it to three error messages:

stubs/weasyprint/weasyprint/layout/page.pyi:20: error: Name "outer" already defined on line 17  [no-redef]
stubs/weasyprint/weasyprint/layout/page.pyi:20: error: "Callable[[OrientedBox], Any]" has no attribute "setter"  [attr-defined]
stubs/weasyprint/weasyprint/layout/page.pyi:20: error: Untyped decorator makes function "outer" untyped  [untyped-decorator]

This seems to be some problem with a @property decorator, how is this generally handled?

@github-actions

Copy link
Copy Markdown
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants