Skip to content

Remove overlapping slots and fix broken slots inheritance - #6547

Merged
asvetlov merged 9 commits into
aio-libs:masterfrom
ariebovenberg:fix-slots
Jan 25, 2022
Merged

Remove overlapping slots and fix broken slots inheritance#6547
asvetlov merged 9 commits into
aio-libs:masterfrom
ariebovenberg:fix-slots

Conversation

@ariebovenberg

@ariebovenberg ariebovenberg commented Jan 22, 2022

Copy link
Copy Markdown
Contributor

What do these changes do?

There were a few __slots__ related mistakes:

python -m slotscheck aiohttp -v
ERROR: 'aiohttp.web_protocol:RequestHandler' defines overlapping slots.
       - _reading_paused (aiohttp.base_protocol:BaseProtocol)
ERROR: 'aiohttp.web_response:StreamResponse' has slots but superclass does not.
       - aiohttp.helpers:CookieMixin

Fixing the second error was more problematic than it seems. The straightforward solution of adding __slots__ = ('_cookies', ) was not possible, because this triggered a TypeError: multiple bases have instance lay-out conflict in HTTPException since non-emptly slots cannot be combined with an Exception case class:

>>> class CookieMixin:
...  __slots__ = ('_cookies', )
...
>>> class HTTPException(CookieMixin, Exception):
...  pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: multiple bases have instance lay-out conflict

There are several possible solutions:

  1. put empty slots in CookieMixin, since it's an abstract class. This is the currently implemented solution.
  2. leave the situation as-is. The __slots__ in StreamResponse will be mostly ineffective.
  3. remove __slots__ from StreamResponse. They aren't saving memory or preventing __dict__ from being created.

Are there changes in behavior for the user?

StreamResponse will no longer have a __dict__, so arbitrary attributes cannot be set. This is not documented, so likely not a problem

Related issue number

No issue. This is a small change.

Checklist

  • I think the code is well written
  • Unit tests for the changes exist n/a (see questions below)
  • Documentation reflects the changes n/a
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment into the CHANGES folder
    • name it <issue_id>.<type> for example (588.bugfix)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure type is one of the following:
      • .feature: Signifying a new feature.
      • .bugfix: Signifying a bug fix.
      • .doc: Signifying a documentation improvement.
      • .removal: Signifying a deprecation or removal of public API.
      • .misc: A ticket has been closed, but it is not of interest to users.
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."

Questions

@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label Jan 22, 2022
@ariebovenberg
ariebovenberg marked this pull request as ready for review January 22, 2022 11:26
@Dreamsorcerer

Copy link
Copy Markdown
Member

Would be great if you could add this test to the linter step in CI. Then we can avoid introducing new overlaps in future.

@ariebovenberg

Copy link
Copy Markdown
Contributor Author

@Dreamsorcerer You mean in workflows/ci.yaml?

    - name: Run linters
      run: |
        make mypy
        make slotscheck  # after adding slotscheck to Makefile

Alternatively I can add the hook to the .pre-commit-config.yaml. Whichever you prefer.

Comment thread aiohttp/helpers.py Outdated
@Dreamsorcerer

Dreamsorcerer commented Jan 22, 2022

Copy link
Copy Markdown
Member

@Dreamsorcerer You mean in workflows/ci.yaml?

    - name: Run linters
      run: |
        make mypy
        make slotscheck  # after adding slotscheck to Makefile

That looks fine to me. Not sure it needs to go in the Makefile. But, I'd make it a separate step (and probably rename that existing step to 'Run Mypy'). I meant lint job earlier, rather than linter step..

@ariebovenberg

Copy link
Copy Markdown
Contributor Author

That looks fine to me. Not sure it needs to go in the Makefile. But, I'd make it a separate step (and probably rename that existing step to 'Run Mypy'). I meant lint job earlier, rather than linter step.

Can do. I'm curious though: what's the reasoning behind what goes in pre-commit vs GitHub workflow?

@codecov

codecov Bot commented Jan 22, 2022

Copy link
Copy Markdown

Codecov Report

Merging #6547 (32ce395) into master (21aff1f) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #6547   +/-   ##
=======================================
  Coverage   93.36%   93.36%           
=======================================
  Files         104      104           
  Lines       30506    30509    +3     
  Branches     3068     3069    +1     
=======================================
+ Hits        28482    28485    +3     
  Misses       1850     1850           
  Partials      174      174           
Flag Coverage Δ
unit 93.29% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
aiohttp/web_protocol.py 88.31% <ø> (ø)
aiohttp/web_response.py 98.41% <ø> (ø)
aiohttp/helpers.py 96.94% <100.00%> (+<0.01%) ⬆️
tests/test_helpers.py 98.96% <100.00%> (+<0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 21aff1f...32ce395. Read the comment docs.

@Dreamsorcerer

Dreamsorcerer commented Jan 22, 2022

Copy link
Copy Markdown
Member

That looks fine to me. Not sure it needs to go in the Makefile. But, I'd make it a separate step (and probably rename that existing step to 'Run Mypy'). I meant lint job earlier, rather than linter step.

Can do. I'm curious though: what's the reasoning behind what goes in pre-commit vs GitHub workflow?

Probably a question for someone else. I'd assume that pre-commit is being run as a git hook, so it makes sense to have primarily fast checks which are likely to catch mistakes. If it only catches an error for 1 in 500 PRs or something, it's probably best not delaying a developer's commit. But, not sure if that's what has been done so far, I didn't set up anything in pre-commit and don't really mind which way it goes in.

@ariebovenberg

Copy link
Copy Markdown
Contributor Author

That looks fine to me. Not sure it needs to go in the Makefile. But, I'd make it a separate step (and probably rename that existing step to 'Run Mypy'). I meant lint job earlier, rather than linter step.

Can do. I'm curious though: what's the reasoning behind what goes in pre-commit vs GitHub workflow?

Probably a question for someone else. I'd assume that pre-commit is being run as a git hook, so it makes sense to have primarily fast checks which are likely to catch mistakes. If it only catches an error for 1 in 500 PRs or something, it's probably best not delaying a developer's commit. But, not sure if that's what has been done so far, I didn't set up anything in pre-commit and don't really mind which way it goes in.

Indeed, problems with slots probably won't occur in most PRs. I'll add it to the GH workflow for now.

@asvetlov

Copy link
Copy Markdown
Member

Thanks!

@webknjaz

Copy link
Copy Markdown
Member

@Dreamsorcerer @ariebovenberg does anybody remember why this never got backported to stable branches?

@webknjaz webknjaz added backport-3.14 Trigger automatic backporting to the 3.14 release branch by Patchback robot backport-3.15 Trigger automatic backporting to the 3.15 release branch by Patchback robot labels Aug 17, 2026
@patchback

patchback Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Backport to 3.15: 💔 cherry-picking failed — conflicts found

❌ Failed to cleanly apply 65de218 on top of patchback/backports/3.15/65de218c6297284663eeae5c07e9146ef1e4485e/pr-6547

Backporting merged PR #6547 into master

  1. Ensure you have a local repo clone of your fork. Unless you cloned it
    from the upstream, this would be your origin remote.
  2. Make sure you have an upstream repo added as a remote too. In these
    instructions you'll refer to it by the name upstream. If you don't
    have it, here's how you can add it:
    $ git remote add upstream https://github.com/aio-libs/aiohttp.git
  3. Ensure you have the latest copy of upstream and prepare a branch
    that will hold the backported code:
    $ git fetch upstream
    $ git checkout -b patchback/backports/3.15/65de218c6297284663eeae5c07e9146ef1e4485e/pr-6547 upstream/3.15
  4. Now, cherry-pick PR Remove overlapping slots and fix broken slots inheritance #6547 contents into that branch:
    $ git cherry-pick -x 65de218c6297284663eeae5c07e9146ef1e4485e
    If it'll yell at you with something like fatal: Commit 65de218c6297284663eeae5c07e9146ef1e4485e is a merge but no -m option was given., add -m 1 as follows instead:
    $ git cherry-pick -m1 -x 65de218c6297284663eeae5c07e9146ef1e4485e
  5. At this point, you'll probably encounter some merge conflicts. You must
    resolve them in to preserve the patch from PR Remove overlapping slots and fix broken slots inheritance #6547 as close to the
    original as possible.
  6. Push this branch to your fork on GitHub:
    $ git push origin patchback/backports/3.15/65de218c6297284663eeae5c07e9146ef1e4485e/pr-6547
  7. Create a PR, ensure that the CI is green. If it's not — update it so that
    the tests and any other checks pass. This is it!
    Now relax and wait for the maintainers to process your pull request
    when they have some cycles to do reviews. Don't worry — they'll tell you if
    any improvements are necessary when the time comes!

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

Comment thread .github/workflows/ci.yml
# Some extra requirements are needed to ensure all modules
# can be scanned by slotscheck.
pip install -r requirements/base.txt -c requirements/constraints.txt
slotscheck -v -m aiohttp

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Dreamsorcerer I think we need to figure this out: #13466

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

Labels

backport-3.14 Trigger automatic backporting to the 3.14 release branch by Patchback robot backport-3.15 Trigger automatic backporting to the 3.15 release branch by Patchback robot bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants