Skip to content

Commit 68e4de5

Browse files
authored
Merge branch 'master' into overlap
2 parents ef8ee57 + 8f903aa commit 68e4de5

File tree

18 files changed

+194
-55
lines changed

18 files changed

+194
-55
lines changed

.github/workflows/release.yml

Lines changed: 119 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
inputs:
66
version:
77
type: string
8-
description: "Version number to release (e.g., 1.2.3, 1.2.3-rc1, 1.2.0)"
8+
description: "Version number to release (e.g., 1.2.3, 1.2.3rc1, 1.2.0)"
99
required: true
1010

1111
permissions: write-all
@@ -41,10 +41,16 @@ jobs:
4141
env:
4242
VERSION: ${{ github.event.inputs.version }}
4343
run: |
44+
# PEP 440 version regex
45+
VALID_VERSION_REGEX='^([0-9]+\.[0-9]+\.[0-9]+((a|b|rc|\.dev|\.post)[0-9]+)?)$'
46+
if ! [[ $VERSION =~ $VALID_VERSION_REGEX ]]; then
47+
echo "::error::Invalid version string '$VERSION'. Must match PEP 440 (e.g. 1.2.0, 1.2.0rc1, 1.2.0.dev1, 1.2.0a1, 1.2.0b1, 1.2.0.post1)"
48+
exit 1
49+
fi
4450
echo "version=$VERSION" >> $GITHUB_OUTPUT
4551
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^)
4652
echo "previous_tag=${PREVIOUS_TAG}" >> $GITHUB_OUTPUT
47-
if [[ $VERSION =~ -rc ]]; then
53+
if [[ $VERSION =~ rc[0-9]+$ ]]; then
4854
MAJOR_MINOR_VERSION=$(echo $VERSION | grep -oE '^[0-9]+\.[0-9]+')
4955
echo "branch_name=v${MAJOR_MINOR_VERSION}.x" >> $GITHUB_OUTPUT
5056
echo "is_rc=true" >> $GITHUB_OUTPUT
@@ -63,7 +69,7 @@ jobs:
6369
runs-on: ubuntu-latest
6470
environment: release
6571
env:
66-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72+
GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }}
6773
steps:
6874
- name: "Checkout Repository"
6975
uses: actions/checkout@v5
@@ -75,36 +81,126 @@ jobs:
7581
shell: bash
7682
env:
7783
VERSION_BRANCH: ${{ needs.pre_config.outputs.branch_name }}
78-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+
GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }}
7985
run: |
8086
git fetch origin
8187
if ! git show-ref --verify --quiet refs/heads/$VERSION_BRANCH; then
8288
git checkout -b $VERSION_BRANCH
8389
git push origin $VERSION_BRANCH
8490
fi
8591
git checkout $VERSION_BRANCH
86-
- name: "Release Pycord"
87-
id: pycord-release
88-
uses: Aiko-IT-Systems/[email protected]
92+
- name: "Setup Python"
93+
id: python-setup
94+
uses: actions/setup-python@v5
8995
with:
90-
github-token: ${{ secrets.GITHUB_TOKEN }}
91-
pypi-token: ${{ secrets.PYPI_TOKEN }}
92-
version-branch-name: ${{ needs.pre_config.outputs.branch_name }}
93-
ref: ${{ github.ref_name }}
94-
repository: ${{ github.repository }}
9596
python-version: "3.13"
96-
release-requirements: "requirements/_release.txt"
97-
version: ${{ needs.pre_config.outputs.version }}
98-
is-rc: ${{ needs.pre_config.outputs.is_rc }}
99-
pypi-package: "py-cord"
97+
cache: "pip"
98+
cache-dependency-path: "requirements/_release.txt"
99+
- name: "Install Release Dependencies"
100+
id: python-install
101+
env:
102+
REQ_FILE: "requirements/_release.txt"
103+
shell: bash
104+
run: |
105+
python -m pip install --upgrade pip
106+
pip install setuptools setuptools_scm twine build
107+
pip install -r $REQ_FILE
108+
- name: "Prepare and Update CHANGELOG.md"
109+
id: changelog-update
110+
shell: bash
111+
env:
112+
VERSION: ${{ inputs.version }}
113+
REPOSITORY: ${{ github.repository }}
114+
GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }}
115+
BRANCH: ${{ github.ref_name }}
116+
run: |
117+
git config user.name "NyuwBot"
118+
git config user.email "[email protected]"
119+
DATE=$(date +'%Y-%m-%d')
120+
sed -i "/These changes are available on the \`.*\` branch, but have not yet been released\./{N;d;}" CHANGELOG.md
121+
sed -i "s/## \[Unreleased\]/## [$VERSION] - $DATE/" CHANGELOG.md
122+
sed -i "0,/## \[$VERSION\]/ s|## \[$VERSION\]|## [Unreleased]\n\nThese changes are available on the \`$BRANCH\` branch, but have not yet been released.\n\n### Added\n\n### Changed\n\n### Fixed\n\n### Removed\n\n&|" CHANGELOG.md
123+
sed -i "s|\[unreleased\]:.*|[unreleased]: https://github.com/$REPOSITORY/compare/v$VERSION...HEAD\n[$VERSION]: https://github.com/$REPOSITORY/compare/$(git describe --tags --abbrev=0 @^)...v$VERSION|" CHANGELOG.md
124+
git add CHANGELOG.md
125+
git commit -m "chore(release): update CHANGELOG.md for version $VERSION"
126+
- name: "Commit and Push Changelog to ${{ github.ref_name }}"
127+
id: commit-main-branch
128+
shell: bash
129+
env:
130+
VERSION: ${{ inputs.version }}
131+
GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }}
132+
BRANCH: ${{ github.ref_name }}
133+
run: |
134+
git config user.name "NyuwBot"
135+
git config user.email "[email protected]"
136+
git push origin HEAD:$BRANCH -f
137+
- name: "Push Changelog to Version Branch"
138+
id: commit-version-branch
139+
shell: bash
140+
env:
141+
GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }}
142+
VERSION_BRANCH: ${{ needs.pre_config.outputs.branch_name }}
143+
run: |
144+
git config user.name "NyuwBot"
145+
git config user.email "[email protected]"
146+
git push origin HEAD:$VERSION_BRANCH -f
147+
- name: "Create Git Tag"
148+
id: create-git-tag
149+
shell: bash
150+
env:
151+
VERSION: ${{ inputs.version }}
152+
GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }}
153+
run: |
154+
git config user.name "NyuwBot"
155+
git config user.email "[email protected]"
156+
git tag v$VERSION -m "Release version $VERSION"
157+
git push origin v$VERSION -f
158+
- name: "Verify Version"
159+
id: python-version-verify
160+
shell: bash
161+
run: python -m setuptools_scm
162+
- name: "Build Package"
163+
id: python-version-build
164+
shell: bash
165+
run: |
166+
python3 -m build --sdist
167+
python3 -m build --wheel
168+
- name: "Create GitHub Release"
169+
uses: softprops/[email protected]
170+
id: gh-release
171+
with:
172+
tag_name: "v${{ inputs.version }}"
173+
name: "v${{ inputs.version }}"
174+
generate_release_notes: true
175+
draft: false
176+
prerelease: ${{ needs.pre_config.outputs.is_rc }}
177+
files: |
178+
dist/*.whl
179+
dist/*.tar.gz
180+
token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
181+
make_latest: true
182+
repository: ${{ github.repository }}
183+
target_commitish: ${{ github.ref_name }}
184+
185+
- name: "Publish package distributions to PyPI"
186+
uses: pypa/[email protected]
187+
env:
188+
name: "pypi"
189+
url: "https://pypi.org/p/py-cord"
190+
with:
191+
password: ${{ secrets.PYPI_TOKEN }}
192+
user: __token__
193+
attestations: false
194+
verify-metadata: false
195+
100196

101197
- name: "Echo release url"
102-
run: echo "${{ steps.pycord-release.outputs.gh-release }}"
198+
run: echo "${{ steps.gh-release.outputs.url }}"
103199

104200
docs_release:
105201
runs-on: ubuntu-latest
106202
needs: [lib_release,pre_config]
107-
if: ${{ needs.pre_config.outputs.is_rc == 'false' || (needs.pre_config.outputs.is_rc == 'true' && endsWith(needs.pre_config.outputs.version, '.0-rc.1')) }}
203+
if: ${{ needs.pre_config.outputs.is_rc == 'false' || (needs.pre_config.outputs.is_rc == 'true' && endsWith(needs.pre_config.outputs.version, '0rc1')) }}
108204
environment: release
109205
steps:
110206
- name: "Sync Versions on Read the Docs"
@@ -117,7 +213,7 @@ jobs:
117213
run: |
118214
VERSION=${{ needs.pre_config.outputs.version }}
119215
MAJOR_MINOR_VERSION=$(echo $VERSION | grep -oE '^[0-9]+\.[0-9]+')
120-
if [[ $VERSION == *-rc* ]]; then
216+
if [[ $VERSION == *rc* ]]; then
121217
DOCS_VERSION="v${MAJOR_MINOR_VERSION}.x"
122218
else
123219
DOCS_VERSION="v$VERSION"
@@ -132,22 +228,22 @@ jobs:
132228
133229
inform_discord:
134230
runs-on: ubuntu-latest
135-
needs: [lib_release,docs_release,close_milestone,pre_config]
231+
needs: [lib_release,docs_release,pre_config]
136232
environment: release
137233
steps:
138234
- name: "Notify Discord"
139235
run: |
140236
VERSION=${{ needs.pre_config.outputs.version }}
141237
MAJOR_MINOR_VERSION=$(echo $VERSION | grep -oE '^[0-9]+\.[0-9]+')
142-
if [[ $VERSION == *-rc* ]]; then
238+
if [[ $VERSION == *rc* ]]; then
143239
DOCS_URL="<https://docs.pycord.dev/en/v${MAJOR_MINOR_VERSION}.x/changelog.html>"
144240
else
145241
DOCS_URL="<https://docs.pycord.dev/en/v$VERSION/changelog.html>"
146242
fi
147243
GITHUB_COMPARE_URL="<https://github.com/Pycord-Development/pycord/compare/${{ needs.pre_config.outputs.previous_tag }}...v$VERSION>"
148244
GITHUB_RELEASE_URL="<https://github.com/Pycord-Development/pycord/releases/tag/v$VERSION>"
149245
PYPI_RELEASE_URL="<https://pypi.org/project/py-cord/$VERSION/>"
150-
if [[ $VERSION == *-rc* ]]; then
246+
if [[ $VERSION == *rc* ]]; then
151247
ANNOUNCEMENT="## <:pycord:1063211537008955495> Pycord v${MAJOR_MINOR_VERSION} Release Candidate ($VERSION) is available!\n\n"
152248
ANNOUNCEMENT="${ANNOUNCEMENT}This is a pre-release (release candidate) for testing and feedback.\n\n"
153249
ANNOUNCEMENT="${ANNOUNCEMENT}You can view the changelog here: <$DOCS_URL>\n\n"
@@ -191,7 +287,7 @@ jobs:
191287
close_milestone:
192288
runs-on: ubuntu-latest
193289
needs: [determine_milestone_id,pre_config]
194-
if: ${{ !contains(needs.pre_config.outputs.version, '-') && endsWith(needs.pre_config.outputs.version, '.0') }}
290+
if: ${{ !contains(needs.pre_config.outputs.version, 'rc') && endsWith(needs.pre_config.outputs.version, '.0') }}
195291
environment: release
196292
env:
197293
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ possible (see our [Version Guarantees] for more info).
1010

1111
These changes are available on the `master` branch, but have not yet been released.
1212

13+
### Added
14+
15+
### Changed
16+
17+
### Fixed
18+
19+
### Removed
20+
21+
## [2.7.0rc1] - 2025-08-30
22+
1323
⚠️ **This version removes support for Python 3.8.** ⚠️
1424

1525
### Added
@@ -1119,7 +1129,8 @@ These changes are available on the `master` branch, but have not yet been releas
11191129
- Fix py3.10 UnionType checks issue.
11201130
([#1240](https://github.com/Pycord-Development/pycord/pull/1240))
11211131

1122-
[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.6.1...HEAD
1132+
[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.7.0rc1...HEAD
1133+
[2.7.0rc1]: https://github.com/Pycord-Development/pycord/compare/v2.6.0...v2.7.0rc1
11231134
[2.6.1]: https://github.com/Pycord-Development/pycord/compare/v2.6.0...v2.6.1
11241135
[2.6.0]: https://github.com/Pycord-Development/pycord/compare/v2.5.0...v2.6.0
11251136
[2.5.0]: https://github.com/Pycord-Development/pycord/compare/v2.4.1...v2.5.0

discord/channel.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2884,8 +2884,6 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
28842884
The position in the category list. This is a number that starts at 0. e.g. the
28852885
top category is position 0. Can be ``None`` if the channel was received in an interaction.
28862886
2887-
.. note::
2888-
28892887
flags: :class:`ChannelFlags`
28902888
Extra features of the channel.
28912889

discord/client.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
if TYPE_CHECKING:
7070
from .abc import GuildChannel, PrivateChannel, Snowflake, SnowflakeTime
7171
from .channel import DMChannel
72-
from .interaction import Interaction
72+
from .interactions import Interaction
7373
from .member import Member
7474
from .message import Message
7575
from .poll import Poll
@@ -553,6 +553,15 @@ async def on_view_error(
553553
The default view error handler provided by the client.
554554
555555
This only fires for a view if you did not define its :func:`~discord.ui.View.on_error`.
556+
557+
Parameters
558+
----------
559+
error: :class:`Exception`
560+
The exception that was raised.
561+
item: :class:`Item`
562+
The item that the user interacted with.
563+
interaction: :class:`Interaction`
564+
The interaction that was received.
556565
"""
557566

558567
print(
@@ -570,6 +579,13 @@ async def on_modal_error(self, error: Exception, interaction: Interaction) -> No
570579
The default implementation prints the traceback to stderr.
571580
572581
This only fires for a modal if you did not define its :func:`~discord.ui.Modal.on_error`.
582+
583+
Parameters
584+
----------
585+
error: :class:`Exception`
586+
The exception that was raised.
587+
interaction: :class:`Interaction`
588+
The interaction that was received.
573589
"""
574590

575591
print(f"Ignoring exception in modal {interaction.modal}:", file=sys.stderr)
@@ -1297,7 +1313,7 @@ def add_listener(self, func: Coro, name: str = MISSING) -> None:
12971313
TypeError
12981314
The ``func`` parameter is not a coroutine function.
12991315
ValueError
1300-
The ``name`` (event name) does not start with 'on_'
1316+
The ``name`` (event name) does not start with ``on_``.
13011317
13021318
Example
13031319
-------
@@ -1361,7 +1377,7 @@ def listen(self, name: str = MISSING, once: bool = False) -> Callable[[Coro], Co
13611377
TypeError
13621378
The function being listened to is not a coroutine.
13631379
ValueError
1364-
The ``name`` (event name) does not start with 'on_'
1380+
The ``name`` (event name) does not start with ``on_``.
13651381
13661382
Example
13671383
-------

discord/commands/core.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,7 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]:
806806
if option == inspect.Parameter.empty:
807807
option = str
808808

809+
option = Option._strip_none_type(option)
809810
if self._is_typing_literal(option):
810811
literal_values = get_args(option)
811812
if not all(isinstance(v, (str, int, float)) for v in literal_values):

discord/commands/options.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,17 +372,21 @@ def _strip_none_type(input_type):
372372
if input_type is type(None):
373373
raise TypeError("Option type cannot be only NoneType")
374374

375-
if isinstance(input_type, (types.UnionType, tuple)):
376-
args = (
377-
get_args(input_type)
378-
if isinstance(input_type, types.UnionType)
379-
else input_type
380-
)
375+
args = ()
376+
if isinstance(input_type, types.UnionType):
377+
args = get_args(input_type)
378+
elif getattr(input_type, "__origin__", None) is Union:
379+
args = get_args(input_type)
380+
elif isinstance(input_type, tuple):
381+
args = input_type
382+
383+
if args:
381384
filtered = tuple(t for t in args if t is not type(None))
382385
if not filtered:
383386
raise TypeError("Option type cannot be only NoneType")
384387
if len(filtered) == 1:
385388
return filtered[0]
389+
386390
return filtered
387391

388392
return input_type

discord/components.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,6 @@ def __str__(self) -> str:
743743

744744
@property
745745
def url(self) -> str:
746-
"""Returns this media item's url."""
747746
return self._url
748747

749748
@url.setter
@@ -850,7 +849,6 @@ def __init__(self, url, *, description=None, spoiler=False):
850849

851850
@property
852851
def url(self) -> str:
853-
"""Returns the URL of this gallery's underlying media item."""
854852
return self.media.url
855853

856854
def is_dispatchable(self) -> bool:

discord/ext/bridge/core.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,10 @@ def __init__(self, callback, **kwargs):
185185
@property
186186
def name_localizations(self) -> dict[str, str] | None:
187187
"""Returns name_localizations from :attr:`slash_variant`
188-
You can edit/set name_localizations directly with
188+
You can edit/set name_localizations directly with
189+
189190
.. code-block:: python3
191+
190192
bridge_command.name_localizations["en-UK"] = ... # or any other locale
191193
# or
192194
bridge_command.name_localizations = {"en-UK": ..., "fr-FR": ...}
@@ -200,8 +202,10 @@ def name_localizations(self, value):
200202
@property
201203
def description_localizations(self) -> dict[str, str] | None:
202204
"""Returns description_localizations from :attr:`slash_variant`
203-
You can edit/set description_localizations directly with
205+
You can edit/set description_localizations directly with
206+
204207
.. code-block:: python3
208+
205209
bridge_command.description_localizations["en-UK"] = ... # or any other locale
206210
# or
207211
bridge_command.description_localizations = {"en-UK": ..., "fr-FR": ...}

0 commit comments

Comments
 (0)