Skip to content

fix(history_iterator): messages repeat if before & after not set#1273

Open
EmmmaTech wants to merge 4 commits into
nextcord:masterfrom
EmmmaTech:fix/async-iterators
Open

fix(history_iterator): messages repeat if before & after not set#1273
EmmmaTech wants to merge 4 commits into
nextcord:masterfrom
EmmmaTech:fix/async-iterators

Conversation

@EmmmaTech
Copy link
Copy Markdown
Collaborator

Summary

fixes #1238, an issue introduced with the async iterator rewrite in 3.0 where messages would loop every 100 messages due to the after parameter never being updated. I also updated the documentation a bit to clarify this default behavior of the iterator since the original documentation never mentions it.

This is a Code Change

  • I have tested my changes.
  • I have updated the documentation to reflect the changes.
  • I have run task pyright and fixed the relevant issues.

@EmmmaTech EmmmaTech added t: bug Type: bug - something isn't working p: medium Priority: medium - should be worked on in the near future s: awaiting review labels Oct 24, 2025
Copy link
Copy Markdown
Collaborator

@teaishealthy teaishealthy left a comment

Choose a reason for hiding this comment

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

I can't seem to get more than 100 messages

counter = 0
async for _ in channel.history(limit=200):
    counter += 1

print(counter)  # 100 (?)

in order to fix the functionality, the oldest_first parameter now defaults to True and the after parameter defaults to OLDEST_OBJECT to mimick the desired default behavior of fetching limit messages from the beginning of channel history.
@EmmmaTech
Copy link
Copy Markdown
Collaborator Author

this might be more than a fix now, it's a semi-refactor to try and more closely match the original discord.py behavior while fixing the desired result to fetch limit messages from the beginning of channel history. :p

@teaishealthy
Copy link
Copy Markdown
Collaborator

ran a few tests

master

❌ Failed for params: limit=None, before=None, after=None, around=None, oldest_first=False. Expected 150, got asyncio.TimeoutError.
✅ Passed for params: limit=50, before=None, after=None, around=None, oldest_first=False. Expected 50, got 50.
❌ Failed for params: limit=120, before=None, after=None, around=None, oldest_first=False. Expected 120, got duplicate messages found.
✅ Passed for params: limit=None, before=<message #130>, after=None, around=None, oldest_first=False. Expected 129, got 129.
✅ Passed for params: limit=150, before=<message #130>, after=None, around=None, oldest_first=False. Expected 129, got 129.
✅ Passed for params: limit=80, before=<message #130>, after=None, around=None, oldest_first=False. Expected 80, got 80.
✅ Passed for params: limit=None, before=None, after=<message #20>, around=None, oldest_first=True. Expected 130, got 130.
✅ Passed for params: limit=120, before=None, after=<message #20>, around=None, oldest_first=True. Expected 120, got 120.
✅ Passed for params: limit=50, before=None, after=<message #20>, around=None, oldest_first=True. Expected 50, got 50.
❌ Failed for params: limit=None, before=<message #130>, after=<message #20>, around=None, oldest_first=True. Expected 109, got 130.
✅ Passed for params: limit=75, before=<message #130>, after=<message #20>, around=None, oldest_first=True. Expected 75, got 75.
✅ Passed for params: limit=100, before=None, after=None, around=<message #75>, oldest_first=False. Expected around_test = lambda x: 100 <= x and x <= 101, got 100.
✅ Passed for params: limit=200, before=<message #130>, after=None, around=None, oldest_first=True. Expected 129, got 129.
✅ Passed for params: limit=200, before=None, after=<message #20>, around=None, oldest_first=False. Expected 130, got 130.
✅ Passed for params: limit=100, before=None, after=None, around=<message #75>, oldest_first=True. Expected around_test = lambda x: 100 <= x and x <= 101, got 100.
Successfully completed 12/15 tests.

EmmmaTech/fix/async-iterators

❌ Failed for params: limit=None, before=None, after=None, around=None, oldest_first=False. Expected 150, got 100.
✅ Passed for params: limit=50, before=None, after=None, around=None, oldest_first=False. Expected 50, got 50.
❌ Failed for params: limit=120, before=None, after=None, around=None, oldest_first=False. Expected 120, got 100.
✅ Passed for params: limit=None, before=<message #130>, after=None, around=None, oldest_first=False. Expected 129, got 129.
✅ Passed for params: limit=150, before=<message #130>, after=None, around=None, oldest_first=False. Expected 129, got 129.
✅ Passed for params: limit=80, before=<message #130>, after=None, around=None, oldest_first=False. Expected 80, got 80.
✅ Passed for params: limit=None, before=None, after=<message #20>, around=None, oldest_first=True. Expected 130, got 130.
✅ Passed for params: limit=120, before=None, after=<message #20>, around=None, oldest_first=True. Expected 120, got 120.
✅ Passed for params: limit=50, before=None, after=<message #20>, around=None, oldest_first=True. Expected 50, got 50.
✅ Passed for params: limit=None, before=<message #130>, after=<message #20>, around=None, oldest_first=True. Expected 109, got 109.
✅ Passed for params: limit=75, before=<message #130>, after=<message #20>, around=None, oldest_first=True. Expected 75, got 75.
✅ Passed for params: limit=100, before=None, after=None, around=<message #75>, oldest_first=False. Expected around_test = lambda x: 100 <= x and x <= 101, got 100.
✅ Passed for params: limit=200, before=<message #130>, after=None, around=None, oldest_first=True. Expected 129, got 129.
❌ Failed for params: limit=200, before=None, after=<message #20>, around=None, oldest_first=False. Expected 130, got 100.
✅ Passed for params: limit=100, before=None, after=None, around=<message #75>, oldest_first=True. Expected around_test = lambda x: 100 <= x and x <= 101, got 100.
Successfully completed 12/15 tests.

@teaishealthy
Copy link
Copy Markdown
Collaborator

teaishealthy commented Oct 24, 2025

oops accidentally closed this

@teaishealthy teaishealthy reopened this Oct 24, 2025
@EmmmaTech
Copy link
Copy Markdown
Collaborator Author

could you share the testing code you used so I can locally test with my own changes? :>

@teaishealthy
Copy link
Copy Markdown
Collaborator

@EmmmaTech
https://gist.github.com/teaishealthy/7d46b6c0dfe8bf45e43208f4489fbaaf

make sure to configure the constants at the top of the file, then just call run_history_tests with a TextChannel

Copy link
Copy Markdown
Collaborator

@teaishealthy teaishealthy left a comment

Choose a reason for hiding this comment

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

fixed the limit pagination issue.

but: defaulting oldest_first=True changes the default iteration order of channel.history(limit=10) from the newest to the oldest messages. this also creates counterintuitive behavior when using before, as it now walks forward (oldest first) instead of backward from the anchor.

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

Labels

p: medium Priority: medium - should be worked on in the near future t: bug Type: bug - something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

channel.history repeats every 100 messages

3 participants