Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow the use of *-stubs packages #221

Merged
merged 4 commits into from
Nov 10, 2023

Conversation

romain-intel
Copy link
Contributor

Small change to look for X-stubs first when looking for the X module. This better respects PEP 561.

Incidental fix to properly recognize a stubs only package as a package (and not a namespace package).

Please let me know if this is the correct approach (it works for my use case). I can also try to add tests if this is something that is mergeable. I tried to keep my changes to a minimal (being totally unfamiliar with the code).

Small change to look for X-stubs first when looking for the X module.
This better respects PEP 561.

Incidental fix to properly recognize a stubs only package as a package
(and not a namespace package).
@pawamoy
Copy link
Member

pawamoy commented Oct 25, 2023

Hello, thanks for the PR! Could you describe your use-case?

A few questions regarding stubs-only packages:

  • Can you document objects exposed in __init__ modules with a stubs-only package?
  • Can you document instance-only attributes (defined in __init__ methods) with a stubs-only package?

It's true that stubs packages take precedence over regular packages, but this is for type checkers, and Griffe is not a type checker.

A few other remarks:

  • The code in this PR does not seem to handle stubs namespace packages.
  • The added try/except block will double (or likely much more) the time it takes to find a regular package (which is ~99% of the cases).

Based on this, I wonder if we shouldn't add a load_stubs_package parameter somewhere, to find, load and merge the stubs-only package data into the regular package data.

@romain-intel
Copy link
Contributor Author

Hey @pawamoy -- thanks for your quick response.

My use case is that I help develop Metaflow (see https://github.com/Netflix/metaflow) and we are considering releasing a stubs package for Metaflow because, for various reasons, Metaflow creates "dynamic" functions of sorts (I can get into details if you want them but here is the PR Netflix/metaflow#1557 and the README (here: https://github.com/Netflix/metaflow/pull/1557/files#diff-5405972c6b3d9df037790c75db2dc8fb7c1987c8707ae4ad84c39adcb8da00a0) should kind of explain what it is trying to do (PR is not yet fully ready so still has a few rough edges).

We then have a docsite that uses Griffe and I wanted to do the following:

  • install the stubs only package (let's call it metaflow-stubs) in the Griffe environment (or wherever we are rendering our doc website)
  • use ::: metaflow.batch for example. This is not an actual method that exists in the package but it does exist in that generated stubs package.

Note that one workaround is I could do ::: metaflow-stubs.batch (with that tiny change to consider __init__.pyi as a proper file (else it finds the package but skips the __init__.pyi which is, in my case, the most relevant file :).

I am not sure I understand your two questions but I believe you can document anything you want in stubs packages. The only thing I could think of that would probably not make sense are types of variables inside methods/functions for example. In terms of documenting classes and their methods (including init), yes, you can definitely do that. Basically, the stubs only package contains just the .pyi files which all contain methods that are all ... but all other annotations and docstrings can be kept.

Yes, I didn't test it for stubs namespace packages. I also didn't handle partial stub packages (https://peps.python.org/pep-0561/#partial-stub-packages). I believe those two cases would probably be a little more complicated because technically they are incomplete so I suppose (not 100% sure) that the information from the stubs packages would have to be "merged" with that of the actual package. With stubs packages (a complete one), you don't need to look "further down" so to speak and you can stop at the stubs package.

It's true that there is a cost to look for the uncommon case (not a fan of that). I didn't think it would be so significant but I don't know the code as well. It will check a few locations and if the package does not exist, it should just return out pretty quickly (hopefully). I thought what took time was actually traversing the packages but there there shouldn't be much to traverse. A flag might make sense though (an option that could be passed by the user to say: "please look for a stubs package".

Let me know if this makes sense and/or if you have more questions. Happy to help. I would say, as well, that for my use case, I think I could do away with just the small change of considering init.pyi the same as init.py and I could just rename everything X-stubs. I haven't tried it out but I suspect it would work. If I am the only weird one in this situation, it may be the easiest :).

@pawamoy
Copy link
Member

pawamoy commented Oct 26, 2023

Thanks for the detailed explanation!

What I meant by

Can you document objects exposed in init modules with a stubs-only package?

is that if you mirror your package structure in the stubs, you can't document object imported from submodules and exposed in __init__ modules. But I guess that you don't mirror the entire structure, and document every public object in the top-level __init__ module. Or you mirror just the public facing modules.

And by

Can you document instance-only attributes (defined in init methods) with a stubs-only package?

I meant, how do you document instance_var below in a stubs-only package?

class A:
    class_var: int = 0

    def __init__(self):
        self.instance_var: int = 0

I think it's not possible 🤔 Unless you document it as a class variable, which wouldn't be so bad.


As tempting as ::: metaflow-stubs.batch looks, I won't let you do that, because your inventory would then wrongly use the stubs package name in the object paths/identifiers, preventing anyone from cross-linking your docs 😅

Anyway. I'm not opposed to the idea of allowing users to load data only from stubs packages. I'd just prefer that we avoid always looking for a stubs package before the regular package. Or maybe we could always try to find both: find package, then find stubs, if package not found return stubs, if package found return package+stubs (will be merged). Do you plan on installing only the stubs package in the Griffe environment, or the actual package as well?

@romain-intel
Copy link
Contributor Author

To answer the questions:

  • you can document whatever you want in __init__.pyi. In my case for example, if something is imported, I choose to document it (based on the way I did the stubs generation) but you could also not have it documented there and just document it in the submodule. So for example, if in your mypackage init.py you had:
from .foo import bar

where bar is a function, you could technically add a:

def bar(...):
  ...

in __init__.pyi and that would work but you could also choose to document bar directly in foo.py and that would also work.

  • you are correct that you don't document any variables that are set in init.pyi (at least I haven't seen that use case but I am not a huge expert either).
  • In terms of installing stubs and regular package. I can do both. I think I technically only need the stubs in terms of what I am thinking of documenting but I can see a case where you may need both.

I get your concern about looking for two packages. One option, which you suggested earlier, is to also have a flag that users can set that instructs griffe to look for stubs packages so that if users don't need that functionality, they don't pay for it at all.

We could definitely do the merging too. I think you already have a function that merges .pyi and .py files from within the same package so this would be somewhat identical just that the files would be the "same files" with different root directories (ie: be in different packages). I can attempt that if that is something you think would be worthwhile. In short, happy to put in the work to make this PR more "production ready" and better (although I may need help on things like "add a configuration option" which I haven't looked for too much yet).

@pawamoy
Copy link
Member

pawamoy commented Oct 27, 2023

I've pushed changes to your branch, I hope you don't mind!

With these changes I think we now also support namespace packages for stubs. I added tests for the finder, and we need more tests for the loader, to check that regular/namespace package+stubs combo are correctly loaded and merged together.

@romain-intel
Copy link
Contributor Author

I don't mind at all!!! Thanks for taking the time. Much appreciated. I'll try to add tests to cover those other use cases.

@pawamoy
Copy link
Member

pawamoy commented Oct 27, 2023

I should be able to add these tests tomorrow, don't worry about it :)

@romain-intel
Copy link
Contributor Author

You make "contributing" (generous characterization) to your repo very nice!

@pawamoy
Copy link
Member

pawamoy commented Oct 28, 2023

Added some tests, that helped discover an oversight and bug in the stubs merger. I also added a CLI option. Do you use Griffe directly or through mkdocstrings?

@pawamoy pawamoy changed the title fix: Allow the use of *-stubs packages feat: Allow the use of *-stubs packages Oct 28, 2023
@romain-intel
Copy link
Contributor Author

Awesome. Let me try it out this weekend. I use it through mkdocstrings.

@romain-intel
Copy link
Contributor Author

I apologize for the delay -- it's been a busy past few days. I plan on trying this out tomorrow (ie: this branch in my setup). Apologies again.

@pawamoy
Copy link
Member

pawamoy commented Nov 1, 2023

No need for apologies! We're all busy 🙂 Thank you for following up and testing out the branch!

@romain-intel
Copy link
Contributor Author

I tested with -B and it seems to work fine. One comment though is that, in some cases, the merge of the .py and .pyi fails because of a type mismatch. I have several cases of this but one is TYPE_CHECKING which is an attribute in the pyi file but an alias in the .py file. In this case, I think the merge should "favor" the .pyi file.

Next step for me is getting it to work with mkdocstrings but that shouldn't be too bad hopefully.

@pawamoy pawamoy self-assigned this Nov 4, 2023
@pawamoy
Copy link
Member

pawamoy commented Nov 8, 2023

Thanks for reporting back. Do you mean that you get debug log messages when the objects have different kinds, or does Griffe actually crash somehow? Do you have other examples of objects not being merged because they have different kinds? TYPE_CHECKING is probably not important at all for API docs.

@pawamoy
Copy link
Member

pawamoy commented Nov 10, 2023

The type mismatch you mention should only happen when one of the two objects is an alias and cannot be resolved. If it cannot be resolved, it probably means that it is imported from another package (like TYPE_CHECKING coming from typing). In that case, this other package should be pre-loaded. But I can imagine that in some cases we'd want to favor the stubs over the regular member when there's a type mismatch. I'd need some examples though, to make sure 🙂 Anyway, this can and should be done in another PR! I'm going to merge this so we can release it in the next version.

@pawamoy pawamoy merged commit 6e55f3b into mkdocstrings:main Nov 10, 2023
16 checks passed
romain-intel added a commit to romain-intel/mkdocstrings-python that referenced this pull request Feb 1, 2024
This allows using the feature in griffe that searches for stubs packages

Related: mkdocstrings/griffe#221
pawamoy pushed a commit to mkdocstrings/python that referenced this pull request Feb 3, 2024
This allows using the feature in Griffe that searches for stubs packages.

PR #128: #128
PR griffe#221: : mkdocstrings/griffe#221
AlexWaygood referenced this pull request in AlexWaygood/typeshed-stats Mar 16, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change | Age | Adoption | Passing |
Confidence |
|---|---|---|---|---|---|---|---|
|
[astral-sh/ruff-pre-commit](https://togithub.com/astral-sh/ruff-pre-commit)
| repository | minor | `v0.2.1` -> `v0.3.3` |
[![age](https://developer.mend.io/api/mc/badges/age/github-tags/astral-sh%2fruff-pre-commit/v0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/github-tags/astral-sh%2fruff-pre-commit/v0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/github-tags/astral-sh%2fruff-pre-commit/v0.2.1/v0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/astral-sh%2fruff-pre-commit/v0.2.1/v0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [docs/MarkDown](https://togithub.com/Python-Markdown/markdown)
([changelog](https://python-markdown.github.io/changelog/)) |
project.optional-dependencies | minor | `==3.5.2` -> `==3.6` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/docs%2fMarkDown/3.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/docs%2fMarkDown/3.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/docs%2fMarkDown/3.5.2/3.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/docs%2fMarkDown/3.5.2/3.6?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [docs/mkdocs-material](https://togithub.com/squidfunk/mkdocs-material)
| project.optional-dependencies | patch | `==9.5.8` -> `==9.5.13` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/docs%2fmkdocs-material/9.5.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/docs%2fmkdocs-material/9.5.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/docs%2fmkdocs-material/9.5.8/9.5.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/docs%2fmkdocs-material/9.5.8/9.5.13?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [docs/mkdocstrings](https://togithub.com/mkdocstrings/mkdocstrings)
([changelog](https://mkdocstrings.github.io/changelog)) |
project.optional-dependencies | patch | `==0.24.0` -> `==0.24.1` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/docs%2fmkdocstrings/0.24.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/docs%2fmkdocstrings/0.24.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/docs%2fmkdocstrings/0.24.0/0.24.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/docs%2fmkdocstrings/0.24.0/0.24.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [docs/mkdocstrings-python](https://togithub.com/mkdocstrings/python)
([changelog](https://mkdocstrings.github.io/python/changelog)) |
project.optional-dependencies | minor | `==1.8.0` -> `==1.9.0` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/docs%2fmkdocstrings-python/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/docs%2fmkdocstrings-python/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/docs%2fmkdocstrings-python/1.8.0/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/docs%2fmkdocstrings-python/1.8.0/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [misc-lint/ruff](https://docs.astral.sh/ruff)
([source](https://togithub.com/astral-sh/ruff),
[changelog](https://togithub.com/astral-sh/ruff/blob/main/CHANGELOG.md))
| project.optional-dependencies | minor | `==0.2.1` -> `==0.3.3` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/misc-lint%2fruff/0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/misc-lint%2fruff/0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/misc-lint%2fruff/0.2.1/0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/misc-lint%2fruff/0.2.1/0.3.3?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pytest/coverage](https://togithub.com/nedbat/coveragepy) |
project.optional-dependencies | patch | `==7.4.1` -> `==7.4.4` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pytest%2fcoverage/7.4.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pytest%2fcoverage/7.4.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pytest%2fcoverage/7.4.1/7.4.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pytest%2fcoverage/7.4.1/7.4.4?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [pytest/pytest](https://togithub.com/pytest-dev/pytest)
([changelog](https://docs.pytest.org/en/stable/changelog.html)) |
project.optional-dependencies | minor | `==8.0.0` -> `==8.1.1` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pytest%2fpytest/8.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pytest%2fpytest/8.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pytest%2fpytest/8.0.0/8.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pytest%2fpytest/8.0.0/8.1.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[pytest/pytest-asyncio](https://togithub.com/pytest-dev/pytest-asyncio)
([changelog](https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html))
| project.optional-dependencies | patch | `==0.23.5` -> `==0.23.5.post1`
|
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pytest%2fpytest-asyncio/0.23.5.post1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pytest%2fpytest-asyncio/0.23.5.post1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pytest%2fpytest-asyncio/0.23.5/0.23.5.post1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pytest%2fpytest-asyncio/0.23.5/0.23.5.post1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[pytest/pytest-subtests](https://togithub.com/pytest-dev/pytest-subtests)
| project.optional-dependencies | minor | `==0.11.0` -> `==0.12.1` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/pytest%2fpytest-subtests/0.12.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/pytest%2fpytest-subtests/0.12.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/pytest%2fpytest-subtests/0.11.0/0.12.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/pytest%2fpytest-subtests/0.11.0/0.12.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [typecheck/mypy](https://www.mypy-lang.org/)
([source](https://togithub.com/python/mypy),
[changelog](https://mypy-lang.blogspot.com/)) |
project.optional-dependencies | minor | `==1.8.0` -> `==1.9.0` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/typecheck%2fmypy/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/typecheck%2fmypy/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/typecheck%2fmypy/1.8.0/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/typecheck%2fmypy/1.8.0/1.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [typecheck/types-Markdown](https://togithub.com/python/typeshed)
([changelog](https://togithub.com/typeshed-internal/stub_uploader/blob/main/data/changelogs/Markdown.md))
| project.optional-dependencies | minor | `==3.5.0.20240129` ->
`==3.6.0.20240316` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/typecheck%2ftypes-Markdown/3.6.0.20240316?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/typecheck%2ftypes-Markdown/3.6.0.20240316?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/typecheck%2ftypes-Markdown/3.5.0.20240129/3.6.0.20240316?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/typecheck%2ftypes-Markdown/3.5.0.20240129/3.6.0.20240316?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [typecheck/types-beautifulsoup4](https://togithub.com/python/typeshed)
([changelog](https://togithub.com/typeshed-internal/stub_uploader/blob/main/data/changelogs/beautifulsoup4.md))
| project.optional-dependencies | patch | `==4.12.0.20240106` ->
`==4.12.0.20240229` |
[![age](https://developer.mend.io/api/mc/badges/age/pypi/typecheck%2ftypes-beautifulsoup4/4.12.0.20240229?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/typecheck%2ftypes-beautifulsoup4/4.12.0.20240229?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/typecheck%2ftypes-beautifulsoup4/4.12.0.20240106/4.12.0.20240229?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/typecheck%2ftypes-beautifulsoup4/4.12.0.20240106/4.12.0.20240229?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://togithub.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>astral-sh/ruff-pre-commit (astral-sh/ruff-pre-commit)</summary>

###
[`v0.3.3`](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.3.2...v0.3.3)

[Compare
Source](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.3.2...v0.3.3)

###
[`v0.3.2`](https://togithub.com/astral-sh/ruff-pre-commit/releases/tag/v0.3.2)

[Compare
Source](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.3.1...v0.3.2)

See: https://github.com/astral-sh/ruff/releases/tag/v0.3.2

###
[`v0.3.1`](https://togithub.com/astral-sh/ruff-pre-commit/releases/tag/v0.3.1)

[Compare
Source](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.3.0...v0.3.1)

See: https://github.com/astral-sh/ruff/releases/tag/v0.3.1

###
[`v0.3.0`](https://togithub.com/astral-sh/ruff-pre-commit/releases/tag/v0.3.0)

[Compare
Source](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.2.2...v0.3.0)

See: https://github.com/astral-sh/ruff/releases/tag/v0.3.0

###
[`v0.2.2`](https://togithub.com/astral-sh/ruff-pre-commit/releases/tag/v0.2.2)

[Compare
Source](https://togithub.com/astral-sh/ruff-pre-commit/compare/v0.2.1...v0.2.2)

See: https://github.com/astral-sh/ruff/releases/tag/v0.2.2

</details>

<details>
<summary>Python-Markdown/markdown (docs/MarkDown)</summary>

###
[`v3.6`](https://togithub.com/Python-Markdown/markdown/compare/3.5.2...3.6)

[Compare
Source](https://togithub.com/Python-Markdown/markdown/compare/3.5.2...3.6)

</details>

<details>
<summary>squidfunk/mkdocs-material (docs/mkdocs-material)</summary>

###
[`v9.5.13`](https://togithub.com/squidfunk/mkdocs-material/releases/tag/9.5.13):
mkdocs-material-9.5.13

[Compare
Source](https://togithub.com/squidfunk/mkdocs-material/compare/9.5.12...9.5.13)

-   Updated Slovak translations
-   Improved info plugin interop with projects plugin
-   Improved info plugin inclusion/exclusion logic
-   Fixed info plugin not gathering files recursively
- Fixed
[#&#8203;6750](https://togithub.com/squidfunk/mkdocs-material/issues/6750):
Ensure info plugin packs up all necessary files

Thanks to [@&#8203;kamilkrzyskow](https://togithub.com/kamilkrzyskow)
and [@&#8203;scepka](https://togithub.com/scepka) for their
contributions

###
[`v9.5.12`](https://togithub.com/squidfunk/mkdocs-material/releases/tag/9.5.12):
mkdocs-material-9.5.12

[Compare
Source](https://togithub.com/squidfunk/mkdocs-material/compare/9.5.11...9.5.12)

- Fixed
[#&#8203;6846](https://togithub.com/squidfunk/mkdocs-material/issues/6846):
Some meta tags removed on instant navigation (9.4.2 regression)
- Fixed
[#&#8203;6823](https://togithub.com/squidfunk/mkdocs-material/issues/6823):
KaTex not rendering on instant navigation (9.5.5 regression)
- Fixed
[#&#8203;6821](https://togithub.com/squidfunk/mkdocs-material/issues/6821):
Privacy plugin doesn't handle URLs with encoded characters

###
[`v9.5.11`](https://togithub.com/squidfunk/mkdocs-material/releases/tag/9.5.11):
mkdocs-material-9.5.11

[Compare
Source](https://togithub.com/squidfunk/mkdocs-material/compare/9.5.10...9.5.11)

-   Updated Finnish translation

###
[`v9.5.10`](https://togithub.com/squidfunk/mkdocs-material/releases/tag/9.5.10):
mkdocs-material-9.5.10

[Compare
Source](https://togithub.com/squidfunk/mkdocs-material/compare/9.5.9...9.5.10)

-   Updated Bahasa Malaysia translations
- Fixed
[#&#8203;6783](https://togithub.com/squidfunk/mkdocs-material/issues/6783):
Hide continue reading link for blog posts without separators
- Fixed
[#&#8203;6779](https://togithub.com/squidfunk/mkdocs-material/issues/6779):
Incorrect positioning of integrated table of contents

###
[`v9.5.9`](https://togithub.com/squidfunk/mkdocs-material/releases/tag/9.5.9):
mkdocs-material-9.5.9

[Compare
Source](https://togithub.com/squidfunk/mkdocs-material/compare/9.5.8...9.5.9)

-   Fixed navigation pruning with tabs and sections enabled

</details>

<details>
<summary>mkdocstrings/mkdocstrings (docs/mkdocstrings)</summary>

###
[`v0.24.1`](https://togithub.com/mkdocstrings/mkdocstrings/blob/HEAD/CHANGELOG.md#0241---2024-02-27)

[Compare
Source](https://togithub.com/mkdocstrings/mkdocstrings/compare/0.24.0...0.24.1)

<small>[Compare with
0.24.0](https://togithub.com/mkdocstrings/mkdocstrings/compare/0.24.0...0.24.1)</small>

##### Code Refactoring

- Support new pymdownx-highlight options
([a7a2907](https://togithub.com/mkdocstrings/mkdocstrings/commit/a7a29079aebcd79be84ac38ce275797920e4c75e)
by Timothée Mazzucotelli).
- Backup anchors with id and no href, for compatibility with autorefs'
Markdown anchors
([b5236b4](https://togithub.com/mkdocstrings/mkdocstrings/commit/b5236b4333ebde9648c84f6e4b0f4c2b10f3ecd4)
by Timothée Mazzucotelli).
[PR-#&#8203;651](https://togithub.com/mkdocstrings/mkdocstrings/pull/651),
[Related-to-mkdocs-autorefs#39](https://togithub.com/mkdocstrings/autorefs/pull/39),
Co-authored-by: Oleh Prypin <oleh@pryp.in>

</details>

<details>
<summary>mkdocstrings/python (docs/mkdocstrings-python)</summary>

###
[`v1.9.0`](https://togithub.com/mkdocstrings/python/blob/HEAD/CHANGELOG.md#190---2024-03-13)

[Compare
Source](https://togithub.com/mkdocstrings/python/compare/1.8.0...1.9.0)

<small>[Compare with
1.8.0](https://togithub.com/mkdocstrings/python/compare/1.8.0...1.9.0)</small>

##### Dependencies

- Add upper bound on Python-Markdown 3.6 to temporarily prevent breaking
changes
([cd93ee3](https://togithub.com/mkdocstrings/python/commit/cd93ee31418a2752667d43bb5a05d22284522c24)
by Timothée Mazzucotelli).

##### Features

- Add `show_labels` option to show/hide labels
([eaf9b82](https://togithub.com/mkdocstrings/python/commit/eaf9b8240069f7369f401fe048892043c8b173d3)
by Viicos). [Issue
#&#8203;120](https://togithub.com/mkdocstrings/python/issues/120), [PR
#&#8203;130](https://togithub.com/mkdocstrings/python/pull/130)
- Add option to search for stubs packages
([0c6aa32](https://togithub.com/mkdocstrings/python/commit/0c6aa323c9e57b8348765a5daa11c79d0c5edb07)
by Romain). [PR
#&#8203;128](https://togithub.com/mkdocstrings/python/pull/128), PR
[griffe#221](https://togithub.com/griffe/python/issues/221): :
[https://github.com/mkdocstrings/griffe/pull/221](https://togithub.com/mkdocstrings/griffe/pull/221)

##### Code Refactoring

- Mark all Jinja blocks as scoped
([548bdad](https://togithub.com/mkdocstrings/python/commit/548bdaddd66ffc99b3b9a5a62228a2ff4ff0dd00)
by Timothée Mazzucotelli).

</details>

<details>
<summary>astral-sh/ruff (misc-lint/ruff)</summary>

###
[`v0.3.3`](https://togithub.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#033)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.3.2...v0.3.3)

##### Preview features

- \[`flake8-bandit`]: Implement `S610` rule
([#&#8203;10316](https://togithub.com/astral-sh/ruff/pull/10316))
- \[`pycodestyle`] Implement `blank-line-at-end-of-file` (`W391`)
([#&#8203;10243](https://togithub.com/astral-sh/ruff/pull/10243))
- \[`pycodestyle`] Implement `redundant-backslash` (`E502`)
([#&#8203;10292](https://togithub.com/astral-sh/ruff/pull/10292))
- \[`pylint`] - implement `redeclared-assigned-name` (`W0128`)
([#&#8203;9268](https://togithub.com/astral-sh/ruff/pull/9268))

##### Rule changes

- \[`flake8_comprehensions`] Handled special case for `C400` which also
matches `C416`
([#&#8203;10419](https://togithub.com/astral-sh/ruff/pull/10419))
- \[`flake8-bandit`] Implement upstream updates for `S311`, `S324` and
`S605` ([#&#8203;10313](https://togithub.com/astral-sh/ruff/pull/10313))
- \[`pyflakes`] Remove `F401` fix for `__init__` imports by default and
allow opt-in to unsafe fix
([#&#8203;10365](https://togithub.com/astral-sh/ruff/pull/10365))
- \[`pylint`] Implement `invalid-bool-return-type` (`E304`)
([#&#8203;10377](https://togithub.com/astral-sh/ruff/pull/10377))
- \[`pylint`] Include builtin warnings in useless-exception-statement
(`PLW0133`)
([#&#8203;10394](https://togithub.com/astral-sh/ruff/pull/10394))

##### CLI

- Add message on success to `ruff check`
([#&#8203;8631](https://togithub.com/astral-sh/ruff/pull/8631))

##### Bug fixes

- \[`PIE970`] Allow trailing ellipsis in `typing.TYPE_CHECKING`
([#&#8203;10413](https://togithub.com/astral-sh/ruff/pull/10413))
- Avoid `TRIO115` if the argument is a variable
([#&#8203;10376](https://togithub.com/astral-sh/ruff/pull/10376))
- \[`F811`] Avoid removing shadowed imports that point to different
symbols
([#&#8203;10387](https://togithub.com/astral-sh/ruff/pull/10387))
- Fix `F821` and `F822` false positives in `.pyi` files
([#&#8203;10341](https://togithub.com/astral-sh/ruff/pull/10341))
- Fix `F821` false negatives in `.py` files when `from __future__ import
annotations` is active
([#&#8203;10362](https://togithub.com/astral-sh/ruff/pull/10362))
- Fix case where `Indexer` fails to identify continuation preceded by
newline
[#&#8203;10351](https://togithub.com/astral-sh/ruff/issues/10351)
([#&#8203;10354](https://togithub.com/astral-sh/ruff/pull/10354))
- Sort hash maps in `Settings` display
([#&#8203;10370](https://togithub.com/astral-sh/ruff/pull/10370))
- Track conditional deletions in the semantic model
([#&#8203;10415](https://togithub.com/astral-sh/ruff/pull/10415))
- \[`C413`] Wrap expressions in parentheses when negating
([#&#8203;10346](https://togithub.com/astral-sh/ruff/pull/10346))
- \[`pycodestyle`] Do not ignore lines before the first logical line in
blank lines rules.
([#&#8203;10382](https://togithub.com/astral-sh/ruff/pull/10382))
- \[`pycodestyle`] Do not trigger `E225` and `E275` when the next token
is a ')'
([#&#8203;10315](https://togithub.com/astral-sh/ruff/pull/10315))
- \[`pylint`] Avoid false-positive slot non-assignment for `__dict__`
(`PLE0237`)
([#&#8203;10348](https://togithub.com/astral-sh/ruff/pull/10348))
- Gate f-string struct size test for Rustc < 1.76
([#&#8203;10371](https://togithub.com/astral-sh/ruff/pull/10371))

##### Documentation

- Use `ruff.toml` format in README
([#&#8203;10393](https://togithub.com/astral-sh/ruff/pull/10393))
- \[`RUF008`] Make it clearer that a mutable default in a dataclass is
only valid if it is typed as a ClassVar
([#&#8203;10395](https://togithub.com/astral-sh/ruff/pull/10395))
- \[`pylint`] Extend docs and test in `invalid-str-return-type` (`E307`)
([#&#8203;10400](https://togithub.com/astral-sh/ruff/pull/10400))
- Remove `.` from `check` and `format` commands
([#&#8203;10217](https://togithub.com/astral-sh/ruff/pull/10217))

###
[`v0.3.2`](https://togithub.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#032)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.3.1...v0.3.2)

##### Preview features

- Improve single-`with` item formatting for Python 3.8 or older
([#&#8203;10276](https://togithub.com/astral-sh/ruff/pull/10276))

##### Rule changes

- \[`pyupgrade`] Allow fixes for f-string rule regardless of line length
(`UP032`)
([#&#8203;10263](https://togithub.com/astral-sh/ruff/pull/10263))
- \[`pycodestyle`] Include actual conditions in E712 diagnostics
([#&#8203;10254](https://togithub.com/astral-sh/ruff/pull/10254))

##### Bug fixes

- Fix trailing kwargs end of line comment after slash
([#&#8203;10297](https://togithub.com/astral-sh/ruff/pull/10297))
- Fix unstable `with` items formatting
([#&#8203;10274](https://togithub.com/astral-sh/ruff/pull/10274))
- Avoid repeating function calls in f-string conversions
([#&#8203;10265](https://togithub.com/astral-sh/ruff/pull/10265))
- Fix E203 false positive for slices in format strings
([#&#8203;10280](https://togithub.com/astral-sh/ruff/pull/10280))
- Fix incorrect `Parameter` range for `*args` and `**kwargs`
([#&#8203;10283](https://togithub.com/astral-sh/ruff/pull/10283))
- Treat `typing.Annotated` subscripts as type definitions
([#&#8203;10285](https://togithub.com/astral-sh/ruff/pull/10285))

###
[`v0.3.1`](https://togithub.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#031)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.3.0...v0.3.1)

##### Preview features

- \[`pycodestyle`] Fix E301 not triggering on decorated methods.
([#&#8203;10117](https://togithub.com/astral-sh/ruff/pull/10117))
- \[`pycodestyle`] Respect `isort` settings in blank line rules (`E3*`)
([#&#8203;10096](https://togithub.com/astral-sh/ruff/pull/10096))
- \[`pycodestyle`] Make blank lines in typing stub files optional
(`E3*`)
([#&#8203;10098](https://togithub.com/astral-sh/ruff/pull/10098))
- \[`pylint`] Implement `singledispatch-method` (`E1519`)
([#&#8203;10140](https://togithub.com/astral-sh/ruff/pull/10140))
- \[`pylint`] Implement `useless-exception-statement` (`W0133`)
([#&#8203;10176](https://togithub.com/astral-sh/ruff/pull/10176))

##### Rule changes

- \[`flake8-debugger`] Check for use of `debugpy` and `ptvsd` debug
modules
([#&#8203;10177](https://togithub.com/astral-sh/ruff/issues/10177))
([#&#8203;10194](https://togithub.com/astral-sh/ruff/pull/10194))
- \[`pyupgrade`] Generate diagnostic for all valid f-string conversions
regardless of line length (`UP032`)
([#&#8203;10238](https://togithub.com/astral-sh/ruff/pull/10238))
- \[`pep8_naming`] Add fixes for `N804` and `N805`
([#&#8203;10215](https://togithub.com/astral-sh/ruff/pull/10215))

##### CLI

- Colorize the output of `ruff format --diff`
([#&#8203;10110](https://togithub.com/astral-sh/ruff/pull/10110))
- Make `--config` and `--isolated` global flags
([#&#8203;10150](https://togithub.com/astral-sh/ruff/pull/10150))
- Correctly expand tildes and environment variables in paths passed to
`--config`
([#&#8203;10219](https://togithub.com/astral-sh/ruff/pull/10219))

##### Configuration

- Accept a PEP 440 version specifier for `required-version`
([#&#8203;10216](https://togithub.com/astral-sh/ruff/pull/10216))
- Implement isort's `default-section` setting
([#&#8203;10149](https://togithub.com/astral-sh/ruff/pull/10149))

##### Bug fixes

- Remove trailing space from `CapWords` message
([#&#8203;10220](https://togithub.com/astral-sh/ruff/pull/10220))
- Respect external codes in file-level exemptions
([#&#8203;10203](https://togithub.com/astral-sh/ruff/pull/10203))
- \[`flake8-raise`] Avoid false-positives for parens-on-raise with
`future.exception()` (`RSE102`)
([#&#8203;10206](https://togithub.com/astral-sh/ruff/pull/10206))
- \[`pylint`] Add fix for unary expressions in `PLC2801`
([#&#8203;9587](https://togithub.com/astral-sh/ruff/pull/9587))
- \[`ruff`] Fix RUF028 not allowing `# fmt: skip` on match cases
([#&#8203;10178](https://togithub.com/astral-sh/ruff/pull/10178))

###
[`v0.3.0`](https://togithub.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#030)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.2.2...v0.3.0)

This release introduces the new Ruff formatter 2024.2 style and adds a
new lint rule to
detect invalid formatter suppression comments.

##### Preview features

- \[`flake8-bandit`] Remove suspicious-lxml-import (`S410`)
([#&#8203;10154](https://togithub.com/astral-sh/ruff/pull/10154))
- \[`pycodestyle`] Allow `os.environ` modifications between imports
(`E402`)
([#&#8203;10066](https://togithub.com/astral-sh/ruff/pull/10066))
- \[`pycodestyle`] Don't warn about a single whitespace character before
a comma in a tuple (`E203`)
([#&#8203;10094](https://togithub.com/astral-sh/ruff/pull/10094))

##### Rule changes

- \[`eradicate`] Detect commented out `case` statements (`ERA001`)
([#&#8203;10055](https://togithub.com/astral-sh/ruff/pull/10055))
- \[`eradicate`] Detect single-line code for `try:`, `except:`, etc.
(`ERA001`)
([#&#8203;10057](https://togithub.com/astral-sh/ruff/pull/10057))
- \[`flake8-boolean-trap`] Allow boolean positionals in `__post_init__`
([#&#8203;10027](https://togithub.com/astral-sh/ruff/pull/10027))
- \[`flake8-copyright`] Allow © in copyright notices
([#&#8203;10065](https://togithub.com/astral-sh/ruff/pull/10065))
- \[`isort`]: Use one blank line after imports in typing stub files
([#&#8203;9971](https://togithub.com/astral-sh/ruff/pull/9971))
- \[`pylint`] New Rule `dict-iter-missing-items` (`PLE1141`)
([#&#8203;9845](https://togithub.com/astral-sh/ruff/pull/9845))
- \[`pylint`] Ignore `sys.version` and `sys.platform` (`PLR1714`)
([#&#8203;10054](https://togithub.com/astral-sh/ruff/pull/10054))
- \[`pyupgrade`] Detect literals with unary operators (`UP018`)
([#&#8203;10060](https://togithub.com/astral-sh/ruff/pull/10060))
- \[`ruff`] Expand rule for `list(iterable).pop(0)` idiom (`RUF015`)
([#&#8203;10148](https://togithub.com/astral-sh/ruff/pull/10148))

##### Formatter

This release introduces the Ruff 2024.2 style, stabilizing the following
changes:

- Prefer splitting the assignment's value over the target or type
annotation
([#&#8203;8943](https://togithub.com/astral-sh/ruff/pull/8943))
- Remove blank lines before class docstrings
([#&#8203;9154](https://togithub.com/astral-sh/ruff/pull/9154))
- Wrap multiple context managers in `with` parentheses when targeting
Python 3.9 or newer
([#&#8203;9222](https://togithub.com/astral-sh/ruff/pull/9222))
- Add a blank line after nested classes with a dummy body (`...`) in
typing stub files
([#&#8203;9155](https://togithub.com/astral-sh/ruff/pull/9155))
- Reduce vertical spacing for classes and functions with a dummy (`...`)
body ([#&#8203;7440](https://togithub.com/astral-sh/ruff/issues/7440),
[#&#8203;9240](https://togithub.com/astral-sh/ruff/pull/9240))
- Add a blank line after the module docstring
([#&#8203;8283](https://togithub.com/astral-sh/ruff/pull/8283))
- Parenthesize long type hints in assignments
([#&#8203;9210](https://togithub.com/astral-sh/ruff/pull/9210))
- Preserve indent for single multiline-string call-expressions
([#&#8203;9673](https://togithub.com/astral-sh/ruff/pull/9637))
- Normalize hex escape and unicode escape sequences
([#&#8203;9280](https://togithub.com/astral-sh/ruff/pull/9280))
- Format module docstrings
([#&#8203;9725](https://togithub.com/astral-sh/ruff/pull/9725))

##### CLI

- Explicitly disallow `extend` as part of a `--config` flag
([#&#8203;10135](https://togithub.com/astral-sh/ruff/pull/10135))
- Remove `build` from the default exclusion list
([#&#8203;10093](https://togithub.com/astral-sh/ruff/pull/10093))
- Deprecate `ruff <path>`, `ruff --explain`, `ruff --clean`, and `ruff
--generate-shell-completion` in favor of `ruff check <path>`, `ruff
rule`, `ruff clean`, and `ruff generate-shell-completion`
([#&#8203;10169](https://togithub.com/astral-sh/ruff/pull/10169))
- Remove the deprecated CLI option `--format` from `ruff rule` and `ruff
linter`
([#&#8203;10170](https://togithub.com/astral-sh/ruff/pull/10170))

##### Bug fixes

- \[`flake8-bugbear`] Avoid adding default initializers to stubs
(`B006`)
([#&#8203;10152](https://togithub.com/astral-sh/ruff/pull/10152))
- \[`flake8-type-checking`] Respect runtime-required decorators for
function signatures
([#&#8203;10091](https://togithub.com/astral-sh/ruff/pull/10091))
- \[`pycodestyle`] Mark fixes overlapping with a multiline string as
unsafe (`W293`)
([#&#8203;10049](https://togithub.com/astral-sh/ruff/pull/10049))
- \[`pydocstyle`] Trim whitespace when removing blank lines after
section (`D413`)
([#&#8203;10162](https://togithub.com/astral-sh/ruff/pull/10162))
- \[`pylint`] Delete entire statement, including semicolons (`PLR0203`)
([#&#8203;10074](https://togithub.com/astral-sh/ruff/pull/10074))
- \[`ruff`] Avoid f-string false positives in `gettext` calls (`RUF027`)
([#&#8203;10118](https://togithub.com/astral-sh/ruff/pull/10118))
- Fix `ruff` crashing on PowerPC systems because of too small page size
([#&#8203;10080](https://togithub.com/astral-sh/ruff/pull/10080))

##### Performance

- Add cold attribute to less likely printer queue branches in the
formatter
([#&#8203;10121](https://togithub.com/astral-sh/ruff/pull/10121))
- Skip unnecessary string normalization in the formatter
([#&#8203;10116](https://togithub.com/astral-sh/ruff/pull/10116))

##### Documentation

- Remove "Beta" Label from formatter documentation
([#&#8203;10144](https://togithub.com/astral-sh/ruff/pull/10144))
- `line-length` option: fix link to `pycodestyle.max-line-length`
([#&#8203;10136](https://togithub.com/astral-sh/ruff/pull/10136))

###
[`v0.2.2`](https://togithub.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#022)

[Compare
Source](https://togithub.com/astral-sh/ruff/compare/v0.2.1...v0.2.2)

Highlights include:

-   Initial support formatting f-strings (in `--preview`).
- Support for overriding arbitrary configuration options via the CLI
through an expanded `--config`
    argument (e.g., `--config "lint.isort.combine-as-imports=false"`).
- Significant performance improvements in Ruff's lexer, parser, and lint
rules.

##### Preview features

- Implement minimal f-string formatting
([#&#8203;9642](https://togithub.com/astral-sh/ruff/pull/9642))
- \[`pycodestyle`] Add blank line(s) rules (`E301`, `E302`, `E303`,
`E304`, `E305`, `E306`)
([#&#8203;9266](https://togithub.com/astral-sh/ruff/pull/9266))
- \[`refurb`] Implement `readlines_in_for` (`FURB129`)
([#&#8203;9880](https://togithub.com/astral-sh/ruff/pull/9880))

##### Rule changes

- \[`ruff`] Ensure closing parentheses for multiline sequences are
always on their own line (`RUF022`, `RUF023`)
([#&#8203;9793](https://togithub.com/astral-sh/ruff/pull/9793))
- \[`numpy`] Add missing deprecation violations (`NPY002`)
([#&#8203;9862](https://togithub.com/astral-sh/ruff/pull/9862))
- \[`flake8-bandit`] Detect `mark_safe` usages in decorators
([#&#8203;9887](https://togithub.com/astral-sh/ruff/pull/9887))
- \[`ruff`] Expand `asyncio-dangling-task` (`RUF006`) to include
`new_event_loop`
([#&#8203;9976](https://togithub.com/astral-sh/ruff/pull/9976))
- \[`flake8-pyi`] Ignore 'unused' private type dicts in class scopes
([#&#8203;9952](https://togithub.com/astral-sh/ruff/pull/9952))

##### Formatter

- Docstring formatting: Preserve tab indentation when using
`indent-style=tabs`
([#&#8203;9915](https://togithub.com/astral-sh/ruff/pull/9915))
- Disable top-level docstring formatting for notebooks
([#&#8203;9957](https://togithub.com/astral-sh/ruff/pull/9957))
- Stabilize quote-style's `preserve` mode
([#&#8203;9922](https://togithub.com/astral-sh/ruff/pull/9922))

##### CLI

- Allow arbitrary configuration options to be overridden via the CLI
([#&#8203;9599](https://togithub.com/astral-sh/ruff/pull/9599))

##### Bug fixes

- Make `show-settings` filters directory-agnostic
([#&#8203;9866](https://togithub.com/astral-sh/ruff/pull/9866))
- Respect duplicates when rewriting type aliases
([#&#8203;9905](https://togithub.com/astral-sh/ruff/pull/9905))
- Respect tuple assignments in typing analyzer
([#&#8203;9969](https://togithub.com/astral-sh/ruff/pull/9969))
- Use atomic write when persisting cache
([#&#8203;9981](https://togithub.com/astral-sh/ruff/pull/9981))
- Use non-parenthesized range for `DebugText`
([#&#8203;9953](https://togithub.com/astral-sh/ruff/pull/9953))
- \[`flake8-simplify`] Avoid false positive with `async` for loops
(`SIM113`)
([#&#8203;9996](https://togithub.com/astral-sh/ruff/pull/9996))
- \[`flake8-trio`] Respect `async with` in `timeout-without-await`
([#&#8203;9859](https://togithub.com/astral-sh/ruff/pull/9859))
- \[`perflint`] Catch a wider range of mutations in `PERF101`
([#&#8203;9955](https://togithub.com/astral-sh/ruff/pull/9955))
- \[`pycodestyle`] Fix `E30X` panics on blank lines with trailing white
spaces ([#&#8203;9907](https://togithub.com/astral-sh/ruff/pull/9907))
- \[`pydocstyle`] Allow using `parameters` as a subsection header
(`D405`) ([#&#8203;9894](https://togithub.com/astral-sh/ruff/pull/9894))
- \[`pydocstyle`] Fix blank-line docstring rules for module-level
docstrings
([#&#8203;9878](https://togithub.com/astral-sh/ruff/pull/9878))
- \[`pylint`] Accept 0.0 and 1.0 as common magic values (`PLR2004`)
([#&#8203;9964](https://togithub.com/astral-sh/ruff/pull/9964))
- \[`pylint`] Avoid suggesting set rewrites for non-hashable types
([#&#8203;9956](https://togithub.com/astral-sh/ruff/pull/9956))
- \[`ruff`] Avoid false negatives with string literals inside of method
calls (`RUF027`)
([#&#8203;9865](https://togithub.com/astral-sh/ruff/pull/9865))
- \[`ruff`] Fix panic on with f-string detection (`RUF027`)
([#&#8203;9990](https://togithub.com/astral-sh/ruff/pull/9990))
- \[`ruff`] Ignore builtins when detecting missing f-strings
([#&#8203;9849](https://togithub.com/astral-sh/ruff/pull/9849))

##### Performance

- Use `memchr` for string lexing
([#&#8203;9888](https://togithub.com/astral-sh/ruff/pull/9888))
- Use `memchr` for tab-indentation detection
([#&#8203;9853](https://togithub.com/astral-sh/ruff/pull/9853))
- Reduce `Result<Tok, LexicalError>` size by using `Box<str>` instead of
`String` ([#&#8203;9885](https://togithub.com/astral-sh/ruff/pull/9885))
- Reduce size of `Expr` from 80 to 64 bytes
([#&#8203;9900](https://togithub.com/astral-sh/ruff/pull/9900))
- Improve trailing comma rule performance
([#&#8203;9867](https://togithub.com/astral-sh/ruff/pull/9867))
- Remove unnecessary string cloning from the parser
([#&#8203;9884](https://togithub.com/astral-sh/ruff/pull/9884))

</details>

<details>
<summary>nedbat/coveragepy (pytest/coverage)</summary>

###
[`v7.4.4`](https://togithub.com/nedbat/coveragepy/blob/HEAD/CHANGES.rst#Version-744--2024-03-14)

[Compare
Source](https://togithub.com/nedbat/coveragepy/compare/7.4.3...7.4.4)

- Fix: in some cases, even with `[run] relative_files=True`, a data file
could be created with absolute path names. When combined with other
relative
data files, it was random whether the absolute file names would be made
relative or not. If they weren't, then a file would be listed twice in
reports, as detailed in `issue 1752`\_. This is now fixed: absolute file
names are always made relative when combining. Thanks to Bruno Rodrigues
dos
    Santos for support.

- Fix: the last case of a match/case statement had an incorrect message
if the
branch was missed. It said the pattern never matched, when actually the
    branch is missed if the last case always matched.

- Fix: clicking a line number in the HTML report now positions more
accurately.

- Fix: the `report:format` setting was defined as a boolean, but should
be a
string. Thanks, `Tanaydin Sirin <pull 1754_>`\_. It is also now
documented
    on the :ref:`configuration page <config_report_format>`.

.. \_issue
1752:[https://github.com/nedbat/coveragepy/issues/1752](https://togithub.com/nedbat/coveragepy/issues/1752)2
.. \_pull
1754[https://github.com/nedbat/coveragepy/pull/1754](https://togithub.com/nedbat/coveragepy/pull/1754)54

.. \_changes\_7-4-3:

###
[`v7.4.3`](https://togithub.com/nedbat/coveragepy/blob/HEAD/CHANGES.rst#Version-743--2024-02-23)

[Compare
Source](https://togithub.com/nedbat/coveragepy/compare/7.4.2...7.4.3)

- Fix: in some cases, coverage could fail with a RuntimeError: "Set
changed
    size during iteration." This is now fixed, closing `issue 1733`\_.

.. \_issue
1733:[https://github.com/nedbat/coveragepy/issues/1733](https://togithub.com/nedbat/coveragepy/issues/1733)3

.. \_changes\_7-4-2:

###
[`v7.4.2`](https://togithub.com/nedbat/coveragepy/blob/HEAD/CHANGES.rst#Version-742--2024-02-20)

[Compare
Source](https://togithub.com/nedbat/coveragepy/compare/7.4.1...7.4.2)

- Fix: setting `COVERAGE_CORE=sysmon` no longer errors on 3.11 and
lower,
thanks `Hugo van Kemenade <pull 1747_>`\_. It now issues a warning that
sys.monitoring is not available and falls back to the default core
instead.

.. \_pull
1747:[https://github.com/nedbat/coveragepy/pull/1747](https://togithub.com/nedbat/coveragepy/pull/1747)7

.. \_changes\_7-4-1:

</details>

<details>
<summary>pytest-dev/pytest (pytest/pytest)</summary>

###
[`v8.1.1`](https://togithub.com/pytest-dev/pytest/releases/tag/8.1.1)

[Compare
Source](https://togithub.com/pytest-dev/pytest/compare/8.1.0...8.1.1)

# pytest 8.1.1 (2024-03-08)

::: {.note}
::: {.title}
Note
:::

This release is not a usual bug fix release -- it contains features and
improvements, being a follow up
to `8.1.0`, which has been yanked from PyPI.
:::

## Features

- [#&#8203;11475](https://togithub.com/pytest-dev/pytest/issues/11475):
Added the new `consider_namespace_packages`{.interpreted-text
role="confval"} configuration option, defaulting to `False`.

If set to `True`, pytest will attempt to identify modules that are part
of [namespace
packages](https://packaging.python.org/en/latest/guides/packaging-namespace-packages)
when importing modules.

- [#&#8203;11653](https://togithub.com/pytest-dev/pytest/issues/11653):
Added the new `verbosity_test_cases`{.interpreted-text role="confval"}
configuration option for fine-grained control of test execution
verbosity.
See `Fine-grained verbosity
<pytest.fine_grained_verbosity>`{.interpreted-text role="ref"} for more
details.

## Improvements

- [#&#8203;10865](https://togithub.com/pytest-dev/pytest/issues/10865):
`pytest.warns`{.interpreted-text role="func"} now validates that
`warnings.warn`{.interpreted-text role="func"} was called with a
\[str]{.title-ref} or a \[Warning]{.title-ref}.
Currently in Python it is possible to use other types, however this
causes an exception when `warnings.filterwarnings`{.interpreted-text
role="func"} is used to filter those warnings (see [CPython
#&#8203;103577](https://togithub.com/python/cpython/issues/103577) for a
discussion).
While this can be considered a bug in CPython, we decided to put guards
in pytest as the error message produced without this check in place is
confusing.

- [#&#8203;11311](https://togithub.com/pytest-dev/pytest/issues/11311):
When using `--override-ini` for paths in invocations without a
configuration file defined, the current working directory is used
    as the relative directory.

Previoulsy this would raise an `AssertionError`{.interpreted-text
role="class"}.

- [#&#8203;11475](https://togithub.com/pytest-dev/pytest/issues/11475):
`--import-mode=importlib <import-mode-importlib>`{.interpreted-text
role="ref"} now tries to import modules using the standard import
mechanism (but still without changing :py`sys.path`{.interpreted-text
role="data"}), falling back to importing modules directly only if that
fails.

This means that installed packages will be imported under their
canonical name if possible first, for example `app.core.models`, instead
of having the module name always be derived from their path (for example
`.env310.lib.site_packages.app.core.models`).

- [#&#8203;11801](https://togithub.com/pytest-dev/pytest/issues/11801):
Added the `iter_parents()
<_pytest.nodes.Node.iter_parents>`{.interpreted-text role="func"} helper
method on nodes.
It is similar to `listchain
<_pytest.nodes.Node.listchain>`{.interpreted-text role="func"}, but goes
from bottom to top, and returns an iterator, not a list.

- [#&#8203;11850](https://togithub.com/pytest-dev/pytest/issues/11850):
Added support for `sys.last_exc`{.interpreted-text role="data"} for
post-mortem debugging on Python>=3.12.

- [#&#8203;11962](https://togithub.com/pytest-dev/pytest/issues/11962):
In case no other suitable candidates for configuration file are found, a
`pyproject.toml` (even without a `[tool.pytest.ini_options]` table) will
be considered as the configuration file and define the `rootdir`.

- [#&#8203;11978](https://togithub.com/pytest-dev/pytest/issues/11978):
Add `--log-file-mode` option to the logging plugin, enabling appending
to log-files. This option accepts either `"w"` or `"a"` and defaults to
`"w"`.

Previously, the mode was hard-coded to be `"w"` which truncates the file
before logging.

- [#&#8203;12047](https://togithub.com/pytest-dev/pytest/issues/12047):
When multiple finalizers of a fixture raise an exception, now all
exceptions are reported as an exception group.
    Previously, only the first exception was reported.

## Bug Fixes

- [#&#8203;11475](https://togithub.com/pytest-dev/pytest/issues/11475):
Fixed regression where `--importmode=importlib` would import non-test
modules more than once.

- [#&#8203;11904](https://togithub.com/pytest-dev/pytest/issues/11904):
Fixed a regression in pytest 8.0.0 that would cause test collection to
fail due to permission errors when using `--pyargs`.

This change improves the collection tree for tests specified using
`--pyargs`, see `12043`{.interpreted-text role="pull"} for a comparison
with pytest 8.0 and <8.

- [#&#8203;12011](https://togithub.com/pytest-dev/pytest/issues/12011):
Fixed a regression in 8.0.1 whereby `setup_module` xunit-style fixtures
are not executed when `--doctest-modules` is passed.

- [#&#8203;12014](https://togithub.com/pytest-dev/pytest/issues/12014):
Fix the `stacklevel` used when warning about marks used on fixtures.

- [#&#8203;12039](https://togithub.com/pytest-dev/pytest/issues/12039):
Fixed a regression in `8.0.2` where tests created using
`tmp_path`{.interpreted-text role="fixture"} have been collected
multiple times in CI under Windows.

## Improved Documentation

- [#&#8203;11790](https://togithub.com/pytest-dev/pytest/issues/11790):
Documented the retention of temporary directories created using the
`tmp_path` fixture in more detail.

## Trivial/Internal Changes

- [#&#8203;11785](https://togithub.com/pytest-dev/pytest/issues/11785):
Some changes were made to private functions which may affect plugins
which access them:

- `FixtureManager._getautousenames()` now takes a `Node` itself instead
of the nodeid.
- `FixtureManager.getfixturedefs()` now takes the `Node` itself instead
of the nodeid.
- The `_pytest.nodes.iterparentnodeids()` function is removed without
replacement.
        Prefer to traverse the node hierarchy itself instead.
If you really need to, copy the function from the previous pytest
release.

- [#&#8203;12069](https://togithub.com/pytest-dev/pytest/issues/12069):
Delayed the deprecation of the following features to `9.0.0`:

    -   `node-ctor-fspath-deprecation`{.interpreted-text role="ref"}.
    -   `legacy-path-hooks-deprecated`{.interpreted-text role="ref"}.

It was discovered after `8.1.0` was released that the warnings about the
impeding removal were not being displayed, so the team decided to revert
the removal.

    This is the reason for `8.1.0` being yanked.

# pytest 8.1.0 (YANKED)

::: {.note}
::: {.title}
Note
:::

This release has been **yanked**: it broke some plugins without the
proper warning period, due to
some warnings not showing up as expected.

See
[#&#8203;12069](https://togithub.com/pytest-dev/pytest/issues/12069).
:::

###
[`v8.1.0`](https://togithub.com/pytest-dev/pytest/releases/tag/8.1.0)

[Compare
Source](https://togithub.com/pytest-dev/pytest/compare/8.0.2...8.1.0)

# pytest 8.1.0 (YANKED)

> \[!IMPORTANT]\
> This release has been **yanked**: it broke some plugins without the
proper warning period, due to some warnings not showing up as expected.
See
[#&#8203;12069](https://togithub.com/pytest-dev/pytest/issues/12069).

## Features

- [#&#8203;11475](https://togithub.com/pytest-dev/pytest/issues/11475):
Added the new `consider_namespace_packages`{.interpreted-text
role="confval"} configuration option, defaulting to `False`.

If set to `True`, pytest will attempt to identify modules that are part
of [namespace
packages](https://packaging.python.org/en/latest/guides/packaging-namespace-packages)
when importing modules.

- [#&#8203;11653](https://togithub.com/pytest-dev/pytest/issues/11653):
Added the new `verbosity_test_cases`{.interpreted-text role="confval"}
configuration option for fine-grained control of test execution
verbosity.
See `Fine-grained verbosity
<pytest.fine_grained_verbosity>`{.interpreted-text role="ref"} for more
details.

## Improvements

- [#&#8203;10865](https://togithub.com/pytest-dev/pytest/issues/10865):
`pytest.warns`{.interpreted-text role="func"} now validates that
`warnings.warn`{.interpreted-text role="func"} was called with a
\[str]{.title-ref} or a \[Warning]{.title-ref}.
Currently in Python it is possible to use other types, however this
causes an exception when `warnings.filterwarnings`{.interpreted-text
role="func"} is used to filter those warnings (see [CPython
#&#8203;103577](https://togithub.com/python/cpython/issues/103577) for a
discussion).
While this can be considered a bug in CPython, we decided to put guards
in pytest as the error message produced without this check in place is
confusing.

- [#&#8203;11311](https://togithub.com/pytest-dev/pytest/issues/11311):
When using `--override-ini` for paths in invocations without a
configuration file defined, the current working directory is used
    as the relative directory.

Previoulsy this would raise an `AssertionError`{.interpreted-text
role="class"}.

- [#&#8203;11475](https://togithub.com/pytest-dev/pytest/issues/11475):
`--import-mode=importlib <import-mode-importlib>`{.interpreted-text
role="ref"} now tries to import modules using the standard import
mechanism (but still without changing :py`sys.path`{.interpreted-text
role="data"}), falling back to importing modules directly only if that
fails.

This means that installed packages will be imported under their
canonical name if possible first, for example `app.core.models`, instead
of having the module name always be derived from their path (for example
`.env310.lib.site_packages.app.core.models`).

- [#&#8203;11801](https://togithub.com/pytest-dev/pytest/issues/11801):
Added the `iter_parents()
<_pytest.nodes.Node.iter_parents>`{.interpreted-text role="func"} helper
method on nodes.
It is similar to `listchain
<_pytest.nodes.Node.listchain>`{.interpreted-text role="func"}, but goes
from bottom to top, and returns an iterator, not a list.

- [#&#8203;11850](https://togithub.com/pytest-dev/pytest/issues/11850):
Added support for `sys.last_exc`{.interpreted-text role="data"} for
post-mortem debugging on Python>=3.12.

- [#&#8203;11962](https://togithub.com/pytest-dev/pytest/issues/11962):
In case no other suitable candidates for configuration file are found, a
`pyproject.toml` (even without a `[tool.pytest.ini_options]` table) will
be considered as the configuration file and define the `rootdir`.

- [#&#8203;11978](https://togithub.com/pytest-dev/pytest/issues/11978):
Add `--log-file-mode` option to the logging plugin, enabling appending
to log-files. This option accepts either `"w"` or `"a"` and defaults to
`"w"`.

Previously, the mode was hard-coded to be `"w"` which truncates the file
before logging.

- [#&#8203;12047](https://togithub.com/pytest-dev/pytest/issues/12047):
When multiple finalizers of a fixture raise an exception, now all
exceptions are reported as an exception group.
    Previously, only the first exception was reported.

## Bug Fixes

- [#&#8203;11904](https://togithub.com/pytest-dev/pytest/issues/11904):
Fixed a regression in pytest 8.0.0 that would cause test collection to
fail due to permission errors when using `--pyargs`.

This change improves the collection tree for tests specified using
`--pyargs`, see `12043`{.interpreted-text role="pull"} for a comparison
with pytest 8.0 and <8.

- [#&#8203;12011](https://togithub.com/pytest-dev/pytest/issues/12011):
Fixed a regression in 8.0.1 whereby `setup_module` xunit-style fixtures
are not executed when `--doctest-modules` is passed.

- [#&#8203;12014](https://togithub.com/pytest-dev/pytest/issues/12014):
Fix the `stacklevel` used when warning about marks used on fixtures.

- [#&#8203;12039](https://togithub.com/pytest-dev/pytest/issues/12039):
Fixed a regression in `8.0.2` where tests created using
`tmp_path`{.interpreted-text role="fixture"} have been collected
multiple times in CI under Windows.

## Improved Documentation

- [#&#8203;11790](https://togithub.com/pytest-dev/pytest/issues/11790):
Documented the retention of temporary directories created using the
`tmp_path` fixture in more detail.

## Trivial/Internal Changes

- [#&#8203;11785](https://togithub.com/pytest-dev/pytest/issues/11785):
Some changes were made to private functions which may affect plugins
which access them:
- `FixtureManager._getautousenames()` now takes a `Node` itself instead
of the nodeid.
- `FixtureManager.getfixturedefs()` now takes the `Node` itself instead
of the nodeid.
- The `_pytest.nodes.iterparentnodeids()` function is removed without
replacement.
        Prefer to traverse the node hierarchy itself instead.
If you really need to, copy the function from the previous pytest
release.

###
[`v8.0.2`](https://togithub.com/pytest-dev/pytest/releases/tag/8.0.2)

[Compare
Source](https://togithub.com/pytest-dev/pytest/compare/8.0.1...8.0.2)

# pytest 8.0.2 (2024-02-24)

## Bug Fixes

- [#&#8203;11895](https://togithub.com/pytest-dev/pytest/issues/11895):
Fix collection on Windows where initial paths contain the short version
of a path (for example `c:\PROGRA~1\tests`).
- [#&#8203;11953](https://togithub.com/pytest-dev/pytest/issues/11953):
Fix an `IndexError` crash raising from `getstatementrange_ast`.
- [#&#8203;12021](https://togithub.com/pytest-dev/pytest/issues/12021):
Reverted a fix to \[--maxfail]{.title-ref} handling in pytest 8.0.0
because it caused a regression in pytest-xdist whereby session fixture
teardowns may get executed multiple times when the max-fails is reached.

###
[`v8.0.1`](https://togithub.com/pytest-dev/pytest/releases/tag/8.0.1)

[Compare
Source](https://togithub.com/pytest-dev/pytest/compare/8.0.0...8.0.1)

# pytest 8.0.1 (2024-02-16)

## Bug Fixes

- [#&#8203;11875](https://togithub.com/pytest-dev/pytest/issues/11875):
Correctly handle errors from `getpass.getuser`{.interpreted-text
role="func"} in Python 3.13.
- [#&#8203;11879](https://togithub.com/pytest-dev/pytest/issues/11879):
Fix an edge case where `ExceptionInfo._stringify_exception` could crash
`pytest.raises`{.interpreted-text role="func"}.
- [#&#8203;11906](https://togithub.com/pytest-dev/pytest/issues/11906):
Fix regression with `pytest.warns`{.interpreted-text role="func"} using
custom warning subclasses which have more than one parameter in their
\[\__init\_\_]{.title-ref}.
- [#&#8203;11907](https://togithub.com/pytest-dev/pytest/issues/11907):
Fix a regression in pytest 8.0.0 whereby calling
`pytest.skip`{.interpreted-text role="func"} and similar control-flow
exceptions within a `pytest.warns()`{.interpreted-text role="func"}
block would get suppressed instead of propagating.
- [#&#8203;11929](https://togithub.com/pytest-dev/pytest/issues/11929):
Fix a regression in pytest 8.0.0 whereby autouse fixtures defined in a
module get ignored by the doctests in the module.
- [#&#8203;11937](https://togithub.com/pytest-dev/pytest/issues/11937):
Fix a regression in pytest 8.0.0 whereby items would be collected in
reverse order in some circumstances.

</details>

<details>
<summary>pytest-dev/pytest-asyncio (pytest/pytest-asyncio)</summary>

###
[`v0.23.5.post1`](https://togithub.com/pytest-dev/pytest-asyncio/releases/tag/v0.23.5.post1):
pytest-asyncio 0.23.5.post1

[Compare
Source](https://togithub.com/pytest-dev/pytest-asyncio/compare/v0.23.5...v0.23.5.post1)

### 0.23.5 (2024-02-09)

- Declare compatibility with pytest 8
[#&#8203;737](https://togithub.com/pytest-dev/pytest-asyncio/issues/737)
- Fix typing errors with recent versions of mypy
[#&#8203;769](https://togithub.com/pytest-dev/pytest-asyncio/issues/769)
- Prevent DeprecationWarning about internal use of
`asyncio.get_event_loop()` from affecting test cases
[#&#8203;757](https://togithub.com/pytest-dev/pytest-asyncio/issues/757)

#### Known issues

As of v0.23, pytest-asyncio attaches an asyncio event loop to each item
of the test suite (i.e. session, packages, modules, classes, functions)
and allows tests to be run in those loops when marked accordingly.
Pytest-asyncio currently assumes that async fixture scope is correlated
with the new event loop scope. This prevents fixtures from being
evaluated independently from the event loop scope and breaks some
existing test suites (see
[#&#8203;706](https://togithub.com/pytest-dev/pytest-asyncio/issues/706)).
For example, a test suite may require all fixtures and tests to run in
the same event loop, but have async fixtures that are set up and torn
down for each module. If you're affected by this issue, please continue
using the v0.21 release, until it is resolved.

</details>

<details>
<summary>pytest-dev/pytest-subtests (pytest/pytest-subtests)</summary>

###
[`v0.12.1`](https://togithub.com/pytest-dev/pytest-subtests/blob/HEAD/CHANGELOG.rst#0121-2024-03-07)

[Compare
Source](https://togithub.com/pytest-dev/pytest-subtests/compare/v0.12.0...v0.12.1)

-   Fixed compatibility with upcoming pytest `8.1.x`.  (`#125`\_).

..
\_#125:[https://github.com/pytest-dev/pytest-subtests/issues/125](https://togithub.com/pytest-dev/pytest-subtests/issues/125)5

###
[`v0.12.0`](https://togithub.com/pytest-dev/pytest-subtests/blob/HEAD/CHANGELOG.rst#0120-2024-03-06)

[Compare
Source](https://togithub.com/pytest-dev/pytest-subtests/compare/v0.11.0...v0.12.0)

-   Python 3.12 is now officially supported (`#113`\_).
-   Added typing support (`#115`\_).
- `SubTests` can be imported from `pytest_subtests` to type-annotate the
`subtests` fixture.

..
\_#113:[https://github.com/pytest-dev/pytest-subtests/pull/113](https://togithub.com/pytest-dev/pytest-subtests/pull/113)3
..
\_#115[https://github.com/pytest-dev/pytest-subtests/pull/115](https://togithub.com/pytest-dev/pytest-subtests/pull/115)15

</details>

<details>
<summary>python/mypy (typecheck/mypy)</summary>

### [`v1.9.0`](https://togithub.com/python/mypy/compare/v1.8.0...1.9.0)

[Compare
Source](https://togithub.com/python/mypy/compare/v1.8.0...1.9.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "every 3 months on the first day of
the month" (UTC), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/AlexWaygood/typeshed-stats).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNDUuMCIsInVwZGF0ZWRJblZlciI6IjM3LjI0NS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
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.

2 participants