Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-tweepy for openSUSE:Factory 
checked in at 2025-01-28 14:59:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tweepy (Old)
 and      /work/SRC/openSUSE:Factory/.python-tweepy.new.2316 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tweepy"

Tue Jan 28 14:59:49 2025 rev:17 rq:1240755 version:4.15.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tweepy/python-tweepy.changes      
2024-12-17 19:23:31.969849375 +0100
+++ /work/SRC/openSUSE:Factory/.python-tweepy.new.2316/python-tweepy.changes    
2025-01-28 15:00:46.482017086 +0100
@@ -1,0 +2,13 @@
+Tue Jan 28 09:08:40 UTC 2025 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 4.15.0
+  * Fix error "No module named 'imghdr'" due to removed
+    package in Python 3.13+
+  * Bump requests-oauthlib to allow v2
+  * Drop support for Python 3.7 and 3.8
+- Cherry-pick upstream patch to fix package version
+  * fix-package-version.patch
+- Drop loosen-requests-oauthlib.patch, merged upstream
+- Drop support-python-313.patch, merged upstream
+
+-------------------------------------------------------------------

Old:
----
  loosen-requests-oauthlib.patch
  support-python-313.patch
  v4.14.0.tar.gz

New:
----
  fix-package-version.patch
  v4.15.0.tar.gz

BETA DEBUG BEGIN:
  Old:  * fix-package-version.patch
- Drop loosen-requests-oauthlib.patch, merged upstream
- Drop support-python-313.patch, merged upstream
  Old:- Drop loosen-requests-oauthlib.patch, merged upstream
- Drop support-python-313.patch, merged upstream
BETA DEBUG END:

BETA DEBUG BEGIN:
  New:- Cherry-pick upstream patch to fix package version
  * fix-package-version.patch
- Drop loosen-requests-oauthlib.patch, merged upstream
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tweepy.spec ++++++
--- /var/tmp/diff_new_pack.n67NFZ/_old  2025-01-28 15:00:47.198046687 +0100
+++ /var/tmp/diff_new_pack.n67NFZ/_new  2025-01-28 15:00:47.198046687 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-tweepy
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,16 +17,14 @@
 
 
 Name:           python-tweepy
-Version:        4.14.0
+Version:        4.15.0
 Release:        0
 Summary:        Twitter library for python
 License:        MIT
 URL:            https://github.com/tweepy/tweepy
 Source:         https://github.com/tweepy/tweepy/archive/v%{version}.tar.gz
-# PATCH-FIX-UPSTREAM Based on gh#tweepy/tweepy#2205
-Patch0:         support-python-313.patch
-# PATCH-FIX-UPSTREAM gh#tweepy/tweepy#2179
-Patch1:         loosen-requests-oauthlib.patch
+# PATCH-FIX-UPSTREAM: Bump version number to 4.15.0
+Patch:          
https://github.com/tweepy/tweepy/commit/c1eb4f3f7bfaf5a54db73ae28f7395e8cbf01752.patch#/fix-package-version.patch
 BuildRequires:  %{python_module aiohttp}
 BuildRequires:  %{python_module async-lru}
 BuildRequires:  %{python_module pip}

++++++ fix-package-version.patch ++++++
>From c1eb4f3f7bfaf5a54db73ae28f7395e8cbf01752 Mon Sep 17 00:00:00 2001
From: Josh Roesslein <[email protected]>
Date: Wed, 15 Jan 2025 15:24:21 -0600
Subject: [PATCH] Bump version number to 4.15.0

---
 tweepy/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tweepy/__init__.py b/tweepy/__init__.py
index efe98645b..105189c08 100644
--- a/tweepy/__init__.py
+++ b/tweepy/__init__.py
@@ -5,7 +5,7 @@
 """
 Tweepy Twitter API library
 """
-__version__ = '4.14.0'
+__version__ = '4.15.0'
 __author__ = 'Joshua Roesslein'
 __license__ = 'MIT'
 

++++++ v4.14.0.tar.gz -> v4.15.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tweepy-4.14.0/.github/DISCUSSION_TEMPLATE/questions.yml 
new/tweepy-4.15.0/.github/DISCUSSION_TEMPLATE/questions.yml
--- old/tweepy-4.14.0/.github/DISCUSSION_TEMPLATE/questions.yml 1970-01-01 
01:00:00.000000000 +0100
+++ new/tweepy-4.15.0/.github/DISCUSSION_TEMPLATE/questions.yml 2025-01-15 
22:05:34.000000000 +0100
@@ -0,0 +1,44 @@
+labels: "Question"
+body:
+  - type: markdown
+    attributes:
+      value: There's also an [official Discord 
server](https://discord.gg/bJvqnhg) where you can ask for help with using the 
library.
+  - type: textarea
+    attributes:
+      label: Question
+      description: What's your question?
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: Relevant Code
+      description: If applicable, this should be code, preferably in the form 
of a [minimal reproducible 
example](https://en.wikipedia.org/wiki/Minimal_reproducible_example), that 
demonstrates your question.
+      render: python
+  - type: textarea
+    attributes:
+      label: Traceback
+      description: If applicable, this should be the full traceback for the 
error you're encountering.
+      render: python-traceback
+  - type: input
+    attributes:
+      label: Twitter API Access Plan
+      description: |
+        What Twitter API access level / plan / tier do you have?
+        You can find this information in the Developer Portal.
+      placeholder: This is probably Free, Basic, Pro, or Enterprise.
+  - type: input
+    attributes:
+      label: Tweepy Version
+      description: |
+        What version of Tweepy are you using?
+        If you installed Tweepy using pip, you can use `pip show tweepy` to 
find this information.
+  - type: checkboxes
+    attributes:
+      label: Checklist
+      options:
+        - label: I have searched for duplicate questions.
+        - label: If applicable, I have removed any visible credentials from my 
code and/or screenshots.
+  - type: textarea
+    attributes:
+      label: Additional Context
+      description: If you have anything else to add, please do so here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/.github/ISSUE_TEMPLATE/bug_report.yml 
new/tweepy-4.15.0/.github/ISSUE_TEMPLATE/bug_report.yml
--- old/tweepy-4.14.0/.github/ISSUE_TEMPLATE/bug_report.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/tweepy-4.15.0/.github/ISSUE_TEMPLATE/bug_report.yml     2025-01-15 
22:05:34.000000000 +0100
@@ -0,0 +1,68 @@
+name: Bug Report
+description: Report broken or incorrect behavior.
+labels: "Unconfirmed Bug"
+body:
+  - type: markdown
+    attributes:
+      value: |
+        Thanks for taking the time to fill out a bug report.
+        Please note that this is only for reporting issues with the library.
+        If you need help using the library, start a 
[discussion](https://github.com/tweepy/tweepy/discussions) or join the 
[official Discord server](https://discord.gg/bJvqnhg) instead.
+  - type: input
+    attributes:
+      label: Summary
+      description: Provide a simple summary of your bug report.
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: Reproduction Steps
+      description: Explain what you did for the bug to happen.
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: Minimal Reproducible Example
+      description: This should be code, in the form of a 
[MRE](https://en.wikipedia.org/wiki/Minimal_reproducible_example), that 
demonstrates the bug.
+      render: python
+  - type: textarea
+    attributes:
+      label: Expected Results
+      description: What did you expect to happen?
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: Actual Results
+      description: What actually happened?
+    validations:
+      required: true
+  - type: input
+    attributes:
+      label: Twitter API Access Plan
+      description: |
+        What Twitter API access level / plan / tier do you have?
+        You can find this information in the Developer Portal.
+      placeholder: This is probably Free, Basic, Pro, or Enterprise.
+    validations:
+      required: true
+  - type: input
+    attributes:
+      label: Tweepy Version
+      description: |
+        What version of Tweepy are you using?
+        If you installed Tweepy using pip, you can use `pip show tweepy` to 
find this information.
+    validations:
+      required: true
+  - type: checkboxes
+    attributes:
+      label: Checklist
+      options:
+        - label: I have searched for duplicate issues.
+          required: true
+        - label: If applicable, I have shown the entire traceback.
+        - label: If applicable, I have removed any visible credentials from my 
code and/or screenshots.
+  - type: textarea
+    attributes:
+      label: Additional Context
+      description: If you have anything else to add, please do so here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/.github/ISSUE_TEMPLATE/config.yml 
new/tweepy-4.15.0/.github/ISSUE_TEMPLATE/config.yml
--- old/tweepy-4.14.0/.github/ISSUE_TEMPLATE/config.yml 1970-01-01 
01:00:00.000000000 +0100
+++ new/tweepy-4.15.0/.github/ISSUE_TEMPLATE/config.yml 2025-01-15 
22:05:34.000000000 +0100
@@ -0,0 +1,8 @@
+blank_issues_enabled: true
+contact_links:
+  - name: Ask a question
+    url: https://github.com/tweepy/tweepy/discussions
+    about: Ask questions and discuss with other users of the library.
+  - name: Discord Server
+    url: https://discord.gg/bJvqnhg
+    about: Use the official Discord server to ask for help as well.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tweepy-4.14.0/.github/ISSUE_TEMPLATE/feature_request.yml 
new/tweepy-4.15.0/.github/ISSUE_TEMPLATE/feature_request.yml
--- old/tweepy-4.14.0/.github/ISSUE_TEMPLATE/feature_request.yml        
1970-01-01 01:00:00.000000000 +0100
+++ new/tweepy-4.15.0/.github/ISSUE_TEMPLATE/feature_request.yml        
2025-01-15 22:05:34.000000000 +0100
@@ -0,0 +1,34 @@
+name: Feature Request
+description: Suggest a feature for the library.
+labels: Feature Request
+body:
+  - type: input
+    attributes:
+      label: Summary
+      description: Provide a short summary of your feature request.
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: The Problem
+      description: |
+        What problem is your feature request trying to solve?
+        What becomes easier or possible if this feature is implemented?
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: The Ideal Solution
+      description: |
+        What is your ideal solution to the problem?
+        What would you like this feature to do?
+    validations:
+      required: true
+  - type: textarea
+    attributes:
+      label: The Current Solution
+      description: What is the current solution to the problem, if any?
+  - type: textarea
+    attributes:
+      label: Additional Context
+      description: If you have anything else to add, please do so here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/.github/workflows/deploy.yml 
new/tweepy-4.15.0/.github/workflows/deploy.yml
--- old/tweepy-4.14.0/.github/workflows/deploy.yml      2023-04-25 
00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/.github/workflows/deploy.yml      2025-01-15 
22:05:34.000000000 +0100
@@ -9,9 +9,9 @@
   deploy:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
       - name: Setup Python
-        uses: actions/setup-python@v4
+        uses: actions/setup-python@v5
         with:
           python-version: '3.x'
       - name: Install dependencies
@@ -23,6 +23,6 @@
           TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
           TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
         run: |
-          python setup.py sdist bdist_wheel
+          python -m build
           twine upload dist/*
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/.github/workflows/test.yml 
new/tweepy-4.15.0/.github/workflows/test.yml
--- old/tweepy-4.14.0/.github/workflows/test.yml        2023-04-25 
00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/.github/workflows/test.yml        2025-01-15 
22:05:34.000000000 +0100
@@ -7,14 +7,15 @@
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
+        python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
       - name: Setup Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v4
+        uses: actions/setup-python@v5
         with:
           python-version: ${{ matrix.python-version }}
+          allow-prereleases: true
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/CITATION.cff 
new/tweepy-4.15.0/CITATION.cff
--- old/tweepy-4.14.0/CITATION.cff      2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/CITATION.cff      2025-01-15 22:05:34.000000000 +0100
@@ -23,6 +23,9 @@
   - description: "The versioned DOI for version 4.13.0 of Tweepy"
     type: doi
     value: 10.5281/zenodo.7713369
+  - description: "The versioned DOI for version 4.14.0 of Tweepy"
+    type: doi
+    value: 10.5281/zenodo.7860636
 keywords:
   - Python
   - Twitter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/README.md new/tweepy-4.15.0/README.md
--- old/tweepy-4.14.0/README.md 2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/README.md 2025-01-15 22:05:34.000000000 +0100
@@ -35,7 +35,7 @@
 
     pip install git+https://github.com/tweepy/tweepy.git
 
-Python 3.7 - 3.11 are supported.
+Latest version of Python and older versions not end of life (bugfix and 
security) are supported.
 
 Links
 -----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
"old/tweepy-4.14.0/cassettes/test_asyncclient_block_and_get_blocked_and 
unblock.yaml" 
"new/tweepy-4.15.0/cassettes/test_asyncclient_block_and_get_blocked_and 
unblock.yaml"
--- "old/tweepy-4.14.0/cassettes/test_asyncclient_block_and_get_blocked_and 
unblock.yaml"       2023-04-25 00:11:27.000000000 +0200
+++ "new/tweepy-4.15.0/cassettes/test_asyncclient_block_and_get_blocked_and 
unblock.yaml"       1970-01-01 01:00:00.000000000 +0100
@@ -1,185 +0,0 @@
-interactions:
-- request:
-    body:
-      target_user_id: '17874544'
-    headers:
-      Content-Type:
-      - application/json
-      User-Agent:
-      - Python/3.10.0 aiohttp/3.7.4.post0 Tweepy/4.9.0
-    method: POST
-    uri: https://api.twitter.com/2/users/1072250532645998596/blocking
-  response:
-    body:
-      string: '{"data":{"blocking":true}}'
-    headers:
-      api-version:
-      - '2.42'
-      cache-control:
-      - no-cache, no-store, max-age=0
-      content-disposition:
-      - attachment; filename=json.json
-      content-encoding:
-      - gzip
-      content-length:
-      - '52'
-      content-type:
-      - application/json; charset=utf-8
-      date:
-      - Sat, 07 May 2022 13:20:50 UTC
-      server:
-      - tsa_b
-      set-cookie:
-      - guest_id_marketing=v1%3A165192965087916447; Max-Age=63072000; 
Expires=Mon,
-        06 May 2024 13:20:50 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id_ads=v1%3A165192965087916447; Max-Age=63072000; Expires=Mon, 
06 May
-        2024 13:20:50 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      - personalization_id="v1_d6raK5hbnCFRKnII2kd5hQ=="; Max-Age=63072000; 
Expires=Mon,
-        06 May 2024 13:20:50 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id=v1%3A165192965087916447; Max-Age=63072000; Expires=Mon, 06 
May 2024
-        13:20:50 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      strict-transport-security:
-      - max-age=631138519
-      x-access-level:
-      - read-write-directmessages
-      x-connection-hash:
-      - c9ce8c94ed937e66ed27655cc9cb540351079e5c38b952f0fe5622664320d42e
-      x-content-type-options:
-      - nosniff
-      x-frame-options:
-      - SAMEORIGIN
-      x-rate-limit-limit:
-      - '50'
-      x-rate-limit-remaining:
-      - '49'
-      x-rate-limit-reset:
-      - '1651930550'
-      x-response-time:
-      - '41'
-      x-xss-protection:
-      - '0'
-    status:
-      code: 200
-      message: OK
-    url: https://api.twitter.com/2/users/1072250532645998596/blocking
-- request:
-    body: null
-    headers:
-      User-Agent:
-      - Python/3.10.0 aiohttp/3.7.4.post0 Tweepy/4.9.0
-    method: GET
-    uri: https://api.twitter.com/2/users/1072250532645998596/blocking
-  response:
-    body:
-      string: '{"data":[{"id":"17874544","name":"Twitter 
Support","username":"TwitterSupport"}],"meta":{"result_count":1}}'
-    headers:
-      api-version:
-      - '2.42'
-      cache-control:
-      - no-cache, no-store, max-age=0
-      content-disposition:
-      - attachment; filename=json.json
-      content-encoding:
-      - gzip
-      content-length:
-      - '111'
-      content-type:
-      - application/json; charset=utf-8
-      date:
-      - Sat, 07 May 2022 13:20:51 UTC
-      server:
-      - tsa_b
-      set-cookie:
-      - guest_id_marketing=v1%3A165192965103954945; Max-Age=63072000; 
Expires=Mon,
-        06 May 2024 13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id_ads=v1%3A165192965103954945; Max-Age=63072000; Expires=Mon, 
06 May
-        2024 13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      - personalization_id="v1_i17sy7cUDAjsGIpFEiP82w=="; Max-Age=63072000; 
Expires=Mon,
-        06 May 2024 13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id=v1%3A165192965103954945; Max-Age=63072000; Expires=Mon, 06 
May 2024
-        13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      strict-transport-security:
-      - max-age=631138519
-      x-access-level:
-      - read-write-directmessages
-      x-connection-hash:
-      - 6518b1ea1eedc55716aea9d3c3a7c13005142dd0edca34f50821728bda86965a
-      x-content-type-options:
-      - nosniff
-      x-frame-options:
-      - SAMEORIGIN
-      x-rate-limit-limit:
-      - '15'
-      x-rate-limit-remaining:
-      - '14'
-      x-rate-limit-reset:
-      - '1651930551'
-      x-response-time:
-      - '42'
-      x-xss-protection:
-      - '0'
-    status:
-      code: 200
-      message: OK
-    url: https://api.twitter.com/2/users/1072250532645998596/blocking
-- request:
-    body: null
-    headers:
-      User-Agent:
-      - Python/3.10.0 aiohttp/3.7.4.post0 Tweepy/4.9.0
-    method: DELETE
-    uri: https://api.twitter.com/2/users/1072250532645998596/blocking/17874544
-  response:
-    body:
-      string: '{"data":{"blocking":false}}'
-    headers:
-      api-version:
-      - '2.42'
-      cache-control:
-      - no-cache, no-store, max-age=0
-      content-disposition:
-      - attachment; filename=json.json
-      content-encoding:
-      - gzip
-      content-length:
-      - '53'
-      content-type:
-      - application/json; charset=utf-8
-      date:
-      - Sat, 07 May 2022 13:20:51 UTC
-      server:
-      - tsa_b
-      set-cookie:
-      - guest_id_marketing=v1%3A165192965123045517; Max-Age=63072000; 
Expires=Mon,
-        06 May 2024 13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id_ads=v1%3A165192965123045517; Max-Age=63072000; Expires=Mon, 
06 May
-        2024 13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      - personalization_id="v1_VeY7KCW087dRYotZqyA/ig=="; Max-Age=63072000; 
Expires=Mon,
-        06 May 2024 13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id=v1%3A165192965123045517; Max-Age=63072000; Expires=Mon, 06 
May 2024
-        13:20:51 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      strict-transport-security:
-      - max-age=631138519
-      x-access-level:
-      - read-write-directmessages
-      x-connection-hash:
-      - 4e0af34f12925ee64848c60af7be02d98e38b2ee16eb71e16465cab2c32def2a
-      x-content-type-options:
-      - nosniff
-      x-frame-options:
-      - SAMEORIGIN
-      x-rate-limit-limit:
-      - '50'
-      x-rate-limit-remaining:
-      - '49'
-      x-rate-limit-reset:
-      - '1651930551'
-      x-response-time:
-      - '38'
-      x-xss-protection:
-      - '0'
-    status:
-      code: 200
-      message: OK
-    url: https://api.twitter.com/2/users/1072250532645998596/blocking/17874544
-version: 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
"old/tweepy-4.14.0/cassettes/test_client_block_and_get_blocked_and 
unblock.yaml" 
"new/tweepy-4.15.0/cassettes/test_client_block_and_get_blocked_and unblock.yaml"
--- "old/tweepy-4.14.0/cassettes/test_client_block_and_get_blocked_and 
unblock.yaml"    2023-04-25 00:11:27.000000000 +0200
+++ "new/tweepy-4.15.0/cassettes/test_client_block_and_get_blocked_and 
unblock.yaml"    1970-01-01 01:00:00.000000000 +0100
@@ -1,183 +0,0 @@
-interactions:
-- request:
-    body: '{"target_user_id": "17874544"}'
-    headers:
-      Accept:
-      - '*/*'
-      Accept-Encoding:
-      - gzip, deflate
-      Connection:
-      - keep-alive
-      Content-Length:
-      - '30'
-      Content-Type:
-      - application/json
-      User-Agent:
-      - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha
-    method: POST
-    uri: https://api.twitter.com/2/users/1072250532645998596/blocking
-  response:
-    body:
-      string: !!binary |
-        
H4sIAAAAAAAAAKpWSkksSVSyqlZKyslPzs7MS1eyKikqTa2tBQAAAP//AwBcCHSuGgAAAA==
-    headers:
-      api-version:
-      - '2.24'
-      cache-control:
-      - no-cache, no-store, max-age=0
-      content-disposition:
-      - attachment; filename=json.json
-      content-encoding:
-      - gzip
-      content-length:
-      - '52'
-      content-type:
-      - application/json; charset=utf-8
-      date:
-      - Mon, 20 Sep 2021 18:12:41 UTC
-      server:
-      - tsa_b
-      set-cookie:
-      - personalization_id="v1_YP58GZ7KULovj9I0BZd+tA=="; Max-Age=63072000; 
Expires=Wed,
-        20 Sep 2023 18:12:41 GMT; Path=/; Domain=.twitter.com; Secure; 
SameSite=None
-      - guest_id=v1%3A163216156123071343; Max-Age=63072000; Expires=Wed, 20 
Sep 2023
-        18:12:41 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
-      strict-transport-security:
-      - max-age=631138519
-      x-access-level:
-      - read-write-directmessages
-      x-connection-hash:
-      - 74daf3f6996e83c2a3a1336df68a70c9ffe266db5ca7f75f44b223f3b021bc79
-      x-content-type-options:
-      - nosniff
-      x-frame-options:
-      - SAMEORIGIN
-      x-rate-limit-limit:
-      - '50'
-      x-rate-limit-remaining:
-      - '49'
-      x-rate-limit-reset:
-      - '1632162461'
-      x-xss-protection:
-      - '0'
-    status:
-      code: 200
-      message: OK
-- request:
-    body: null
-    headers:
-      Accept:
-      - '*/*'
-      Accept-Encoding:
-      - gzip, deflate
-      Connection:
-      - keep-alive
-      Cookie:
-      - guest_id=v1%3A163216156123071343; 
personalization_id="v1_YP58GZ7KULovj9I0BZd+tA=="
-      User-Agent:
-      - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha
-    method: GET
-    uri: https://api.twitter.com/2/users/1072250532645998596/blocking
-  response:
-    body:
-      string: !!binary |
-        
H4sIAAAAAAAAAKpWSkksSVSyiq5WykxRslIyNLcwNzE1MVHSUcpLzE0FioSUZ5aUpBYpBJcWFOQX
-        
lQAlSotTi1AlYXK1sTpKuakg86qVilKLS3NK4pPzS/NKlKwMa2sBAAAA//8DAMW+VFVrAAAA
-    headers:
-      api-version:
-      - '2.24'
-      cache-control:
-      - no-cache, no-store, max-age=0
-      content-disposition:
-      - attachment; filename=json.json
-      content-encoding:
-      - gzip
-      content-length:
-      - '111'
-      content-type:
-      - application/json; charset=utf-8
-      date:
-      - Mon, 20 Sep 2021 18:12:41 UTC
-      server:
-      - tsa_b
-      strict-transport-security:
-      - max-age=631138519
-      x-access-level:
-      - read-write-directmessages
-      x-connection-hash:
-      - 74daf3f6996e83c2a3a1336df68a70c9ffe266db5ca7f75f44b223f3b021bc79
-      x-content-type-options:
-      - nosniff
-      x-frame-options:
-      - SAMEORIGIN
-      x-rate-limit-limit:
-      - '15'
-      x-rate-limit-remaining:
-      - '14'
-      x-rate-limit-reset:
-      - '1632162461'
-      x-xss-protection:
-      - '0'
-    status:
-      code: 200
-      message: OK
-- request:
-    body: null
-    headers:
-      Accept:
-      - '*/*'
-      Accept-Encoding:
-      - gzip, deflate
-      Connection:
-      - keep-alive
-      Content-Length:
-      - '0'
-      Cookie:
-      - guest_id=v1%3A163216156123071343; 
personalization_id="v1_YP58GZ7KULovj9I0BZd+tA=="
-      User-Agent:
-      - Python/3.9.6 Requests/2.25.1 Tweepy/4.0.0-alpha
-    method: DELETE
-    uri: https://api.twitter.com/2/users/1072250532645998596/blocking/17874544
-  response:
-    body:
-      string: !!binary |
-        
H4sIAAAAAAAAAKpWSkksSVSyqlZKyslPzs7MS1eySkvMKU6trQUAAAD//wMAcXlx4RsAAAA=
-    headers:
-      api-version:
-      - '2.24'
-      cache-control:
-      - no-cache, no-store, max-age=0
-      content-disposition:
-      - attachment; filename=json.json
-      content-encoding:
-      - gzip
-      content-length:
-      - '53'
-      content-type:
-      - application/json; charset=utf-8
-      date:
-      - Mon, 20 Sep 2021 18:12:41 UTC
-      server:
-      - tsa_b
-      strict-transport-security:
-      - max-age=631138519
-      x-access-level:
-      - read-write-directmessages
-      x-connection-hash:
-      - 74daf3f6996e83c2a3a1336df68a70c9ffe266db5ca7f75f44b223f3b021bc79
-      x-content-type-options:
-      - nosniff
-      x-frame-options:
-      - SAMEORIGIN
-      x-rate-limit-limit:
-      - '50'
-      x-rate-limit-remaining:
-      - '49'
-      x-rate-limit-reset:
-      - '1632162461'
-      x-xss-protection:
-      - '0'
-    status:
-      code: 200
-      message: OK
-version: 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/docs/asyncclient.rst 
new/tweepy-4.15.0/docs/asyncclient.rst
--- old/tweepy-4.14.0/docs/asyncclient.rst      2023-04-25 00:11:27.000000000 
+0200
+++ new/tweepy-4.15.0/docs/asyncclient.rst      2025-01-15 22:05:34.000000000 
+0100
@@ -88,12 +88,8 @@
     
+--------------------------------------------------------------+--------------------------------------------------------+
     | .. centered:: |Blocks|_                                                  
                                             |
     
+--------------------------------------------------------------+--------------------------------------------------------+
-    | `DELETE /2/users/:source_user_id/blocking/:target_user_id`_  | 
:meth:`AsyncClient.unblock`                            |
-    
+--------------------------------------------------------------+--------------------------------------------------------+
     | `GET /2/users/:id/blocking`_                                 | 
:meth:`AsyncClient.get_blocked`                        |
     
+--------------------------------------------------------------+--------------------------------------------------------+
-    | `POST /2/users/:id/blocking`_                                | 
:meth:`AsyncClient.block`                              |
-    
+--------------------------------------------------------------+--------------------------------------------------------+
     | .. centered:: |Follows|_                                                 
                                             |
     
+--------------------------------------------------------------+--------------------------------------------------------+
     | `DELETE /2/users/:source_user_id/following/:target_user_id`_ | 
:meth:`AsyncClient.unfollow_user`                      |
@@ -253,9 +249,7 @@
 .. _GET /2/tweets/:id: 
https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id
 .. _GET /2/tweets: 
https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets
 .. |Blocks| replace:: *Blocks*
-.. _DELETE /2/users/:source_user_id/blocking/:target_user_id: 
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking
 .. _GET /2/users/:id/blocking: 
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking
-.. _POST /2/users/:id/blocking: 
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking
 .. |Follows| replace:: *Follows*
 .. _DELETE /2/users/:source_user_id/following/:target_user_id: 
https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following
 .. _GET /2/users/:id/followers: 
https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers
@@ -402,12 +396,8 @@
 Blocks
 ------
 
-.. automethod:: AsyncClient.unblock
-
 .. automethod:: AsyncClient.get_blocked
 
-.. automethod:: AsyncClient.block
-
 Follows
 -------
 
@@ -537,3 +527,8 @@
 .. automethod:: AsyncClient.get_compliance_job
 
 .. automethod:: AsyncClient.create_compliance_job
+
+
+.. rubric:: Footnotes
+
+.. [#changelog] https://developer.twitter.com/en/updates/changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/docs/authentication.rst 
new/tweepy-4.15.0/docs/authentication.rst
--- old/tweepy-4.14.0/docs/authentication.rst   2023-04-25 00:11:27.000000000 
+0200
+++ new/tweepy-4.15.0/docs/authentication.rst   2025-01-15 22:05:34.000000000 
+0100
@@ -149,9 +149,10 @@
 they'll be redirected to the Callback / Redirect URI / URL you provided. You'll
 need to pass that authorization response URL to fetch the access token::
 
-    access_token = oauth2_user_handler.fetch_token(
+    response = oauth2_user_handler.fetch_token(
         "Authorization Response URL here"
     )
+    access_token = response["access_token"]
 
 You can then pass the access token to :class:`Client` when initializing it::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/docs/changelog.md 
new/tweepy-4.15.0/docs/changelog.md
--- old/tweepy-4.14.0/docs/changelog.md 2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/docs/changelog.md 2025-01-15 22:05:34.000000000 +0100
@@ -3,6 +3,12 @@
 
 These changelogs are also at <https://github.com/tweepy/tweepy/releases> as 
release notes.
 
+Version 4.15.0 (2025-01-15)
+---------------------------
+- Fix error "No module named 'imghdr'" due to removed package in Python 3.13+
+- Bump requests-oauthlib to allow v2 
+- Drop support for Python 3.7 and 3.8
+
 Version 4.14.0 (2023-04-24)
 ---------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/docs/client.rst 
new/tweepy-4.15.0/docs/client.rst
--- old/tweepy-4.14.0/docs/client.rst   2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/docs/client.rst   2025-01-15 22:05:34.000000000 +0100
@@ -88,12 +88,8 @@
     
+------------------------------------------------------------------------------------------------------------------+
     | .. centered:: |Blocks|_                                                  
                                        |
     
+--------------------------------------------------------------+---------------------------------------------------+
-    | `DELETE /2/users/:source_user_id/blocking/:target_user_id`_  | 
:meth:`Client.unblock`                            |
-    
+--------------------------------------------------------------+---------------------------------------------------+
     | `GET /2/users/:id/blocking`_                                 | 
:meth:`Client.get_blocked`                        |
     
+--------------------------------------------------------------+---------------------------------------------------+
-    | `POST /2/users/:id/blocking`_                                | 
:meth:`Client.block`                              |
-    
+--------------------------------------------------------------+---------------------------------------------------+
     | .. centered:: |Follows|_                                                 
                                        |
     
+--------------------------------------------------------------+---------------------------------------------------+
     | `DELETE /2/users/:source_user_id/following/:target_user_id`_ | 
:meth:`Client.unfollow_user`                      |
@@ -253,9 +249,7 @@
 .. _GET /2/tweets/:id: 
https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id
 .. _GET /2/tweets: 
https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets
 .. |Blocks| replace:: *Blocks*
-.. _DELETE /2/users/:source_user_id/blocking/:target_user_id: 
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking
 .. _GET /2/users/:id/blocking: 
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking
-.. _POST /2/users/:id/blocking: 
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking
 .. |Follows| replace:: *Follows*
 .. _DELETE /2/users/:source_user_id/following/:target_user_id: 
https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following
 .. _GET /2/users/:id/followers: 
https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers
@@ -402,12 +396,8 @@
 Blocks
 ------
 
-.. automethod:: Client.unblock
-
 .. automethod:: Client.get_blocked
 
-.. automethod:: Client.block
-
 Follows
 -------
 
@@ -541,3 +531,8 @@
 .. automethod:: Client.get_compliance_job
 
 .. automethod:: Client.create_compliance_job
+
+
+.. rubric:: Footnotes
+
+.. [#changelog] https://developer.twitter.com/en/updates/changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/pyproject.toml 
new/tweepy-4.15.0/pyproject.toml
--- old/tweepy-4.14.0/pyproject.toml    1970-01-01 01:00:00.000000000 +0100
+++ new/tweepy-4.15.0/pyproject.toml    2025-01-15 22:05:34.000000000 +0100
@@ -0,0 +1,4 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/setup.cfg new/tweepy-4.15.0/setup.cfg
--- old/tweepy-4.14.0/setup.cfg 2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/setup.cfg 2025-01-15 22:05:34.000000000 +0100
@@ -7,7 +7,7 @@
     */site-packages/*
 
 [tox:tox]
-envlist = py37, py38, py39, py310, py311
+envlist = py39, py310, py311, py312, py313
 
 [testenv]
 commands = python -m unittest discover tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/setup.py new/tweepy-4.15.0/setup.py
--- old/tweepy-4.14.0/setup.py  2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/setup.py  2025-01-15 22:05:34.000000000 +0100
@@ -36,7 +36,7 @@
     install_requires=[
         "oauthlib>=3.2.0,<4",
         "requests>=2.27.0,<3",
-        "requests-oauthlib>=1.2.0,<2",
+        "requests-oauthlib>=1.2.0,<3",
     ],
     extras_require={
         "async": [
@@ -57,11 +57,14 @@
             "tox>=3.21.0",
          ],
         "socks": ["requests[socks]>=2.27.0,<3"],
-        "test": ["vcrpy>=1.10.3"],
+        "test": [
+            "urllib3<2",  # https://github.com/kevin1024/vcrpy/issues/719
+            "vcrpy>=1.10.3",
+        ],
     },
     test_suite="tests",
     keywords="twitter library",
-    python_requires=">=3.7",
+    python_requires=">=3.9",
     classifiers=[
         "Development Status :: 5 - Production/Stable",
         "Topic :: Software Development :: Libraries",
@@ -69,11 +72,11 @@
         "Operating System :: OS Independent",
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.7",
-        "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
         "Programming Language :: Python :: 3.11",
+        "Programming Language :: Python :: 3.12",
+        "Programming Language :: Python :: 3.13",
         "Programming Language :: Python :: 3 :: Only",
     ],
     zip_safe=True,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/tests/test_asyncclient.py 
new/tweepy-4.15.0/tests/test_asyncclient.py
--- old/tweepy-4.14.0/tests/test_asyncclient.py 2023-04-25 00:11:27.000000000 
+0200
+++ new/tweepy-4.15.0/tests/test_asyncclient.py 2025-01-15 22:05:34.000000000 
+0100
@@ -114,14 +114,7 @@
         # @TwitterDev and @TwitterAPI Tweets announcing API v2
         await self.client.get_tweets(tweet_ids)
 
-    @tape.use_cassette(
-        "test_asyncclient_block_and_get_blocked_and unblock.yaml"
-    )
-    async def test_block_and_get_blocked_and_unblock(self):
-        user_id = 17874544  # User ID for @TwitterSupport
-        await self.client.block(user_id)
-        await self.client.get_blocked()
-        await self.client.unblock(user_id)
+    # TODO: Test AsyncClient.get_blocked
 
     @tape.use_cassette("test_asyncclient_follow_and_unfollow_user.yaml")
     async def test_follow_and_unfollow_user(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/tests/test_client.py 
new/tweepy-4.15.0/tests/test_client.py
--- old/tweepy-4.14.0/tests/test_client.py      2023-04-25 00:11:27.000000000 
+0200
+++ new/tweepy-4.15.0/tests/test_client.py      2025-01-15 22:05:34.000000000 
+0100
@@ -110,12 +110,7 @@
         # @TwitterDev and @TwitterAPI Tweets announcing API v2
         self.client.get_tweets(tweet_ids)
 
-    @tape.use_cassette("test_client_block_and_get_blocked_and unblock.yaml")
-    def test_block_and_get_blocked_and_unblock(self):
-        user_id = 17874544  # User ID for @TwitterSupport
-        self.client.block(user_id)
-        self.client.get_blocked()
-        self.client.unblock(user_id)
+    # TODO: Test Client.get_blocked
 
     @tape.use_cassette("test_client_follow_and_unfollow_user.yaml")
     def test_follow_and_unfollow_user(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/tweepy/api.py 
new/tweepy-4.15.0/tweepy/api.py
--- old/tweepy-4.14.0/tweepy/api.py     2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/tweepy/api.py     2025-01-15 22:05:34.000000000 +0100
@@ -4,7 +4,6 @@
 
 import contextlib
 import functools
-import imghdr
 import logging
 import mimetypes
 from platform import python_version
@@ -470,6 +469,12 @@
         Returns full Tweet objects for up to 100 Tweets per request, specified
         by the ``id`` parameter.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 statuses/lookup endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.`_ The Twitter API v2 replacement is
+            :meth:`Client.get_tweets`.
+
         .. versionchanged:: 4.0
             Renamed from ``API.statuses_lookup``
 
@@ -496,6 +501,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-lookup
+
+        .. _The Twitter API v1.1 statuses/lookup endpoint that this method uses
+            has been deprecated and has a retirement date of November 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'GET', 'statuses/lookup', endpoint_parameters=(
@@ -710,6 +719,11 @@
 
         Returns a single status specified by the ID parameter.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 statuses/show endpoint that this method uses
+            has been deprecated and has a retirement date of November 20,
+            2023.`_ The Twitter API v2 replacement is :meth:`Client.get_tweet`.
+
         Parameters
         ----------
         id:
@@ -735,6 +749,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-show-id
+
+        .. _The Twitter API v1.1 statuses/show endpoint that this method uses
+            has been deprecated and has a retirement date of November 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'GET', 'statuses/show', endpoint_parameters=(
@@ -806,6 +824,12 @@
         Destroy the status specified by the ``id`` parameter. The authenticated
         user must be the author of the status to destroy.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 statuses/destroy endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.`_ The Twitter API v2 replacement is
+            :meth:`Client.delete_tweet`.
+
         Parameters
         ----------
         id
@@ -820,6 +844,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id
+
+        .. _The Twitter API v1.1 statuses/destroy endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'POST', f'statuses/destroy/{id}', endpoint_parameters=(
@@ -833,6 +861,11 @@
 
         Retweets a Tweet. Requires the ID of the Tweet you are retweeting.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 statuses/retweet endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.`_ The Twitter API v2 replacement is :meth:`Client.retweet`.
+
         Parameters
         ----------
         id
@@ -847,6 +880,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-retweet-id
+
+        .. _The Twitter API v1.1 statuses/retweet endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'POST', f'statuses/retweet/{id}', endpoint_parameters=(
@@ -861,6 +898,12 @@
         Untweets a retweeted status. Requires the ID of the retweet to
         unretweet.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 statuses/unretweet endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.`_ The Twitter API v2 replacement is
+            :meth:`Client.unretweet`.
+
         Parameters
         ----------
         id
@@ -875,6 +918,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-unretweet-id
+
+        .. _The Twitter API v1.1 statuses/unretweet endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'POST', f'statuses/unretweet/{id}', endpoint_parameters=(
@@ -904,6 +951,12 @@
         the user reaches the current allowed limit this method will return an
         HTTP 403 error.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 statuses/update endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.`_ The Twitter API v2 replacement is
+            :meth:`Client.create_tweet`.
+
         Parameters
         ----------
         status
@@ -972,6 +1025,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update
+
+        .. _The Twitter API v1.1 statuses/update endpoint that this method
+            uses has been deprecated and has a retirement date of November 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         if 'media_ids' in kwargs:
             kwargs['media_ids'] = list_to_csv(kwargs['media_ids'])
@@ -998,7 +1055,10 @@
         too long will be silently ignored.
 
         .. deprecated:: 3.7.0
-            Use :func:`API.media_upload` instead.
+            `The Twitter API v1.1 statuses/update_with_media endpoint that this
+            method uses has been deprecated and has a retirement date of
+            November 20, 2023.`_ :meth:`API.media_upload` and
+            :meth:`Client.create_tweet` can be used instead.
 
         .. versionchanged:: 4.0
             Renamed from ``API.update_with_media``
@@ -1034,6 +1094,11 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update_with_media
+
+        .. _The Twitter API v1.1 statuses/update_with_media endpoint that this
+            method uses has been deprecated and has a retirement date of
+            November 20, 2023.:
+            https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         with contextlib.ExitStack() as stack:
             if file is not None:
@@ -1082,6 +1147,12 @@
             authenticating user) are not currently supported on this endpoint.
             [#]_\ [#]_
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 search/tweets endpoint that this method uses
+            has been deprecated and has a retirement date of September 20,
+            2023.`_ The Twitter API v2 replacement is
+            :meth:`Client.search_recent_tweets`.
+
         .. versionchanged:: 4.0
             Renamed from ``API.search``
 
@@ -1141,7 +1212,11 @@
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/search/api-reference/get-search-tweets
 
-        .. _Twitter's documentation on the standard search API: 
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/search/overview
+        .. _Twitter's documentation on the standard search API:
+            
https://developer.twitter.com/en/docs/twitter-api/v1/tweets/search/overview
+        .. _The Twitter API v1.1 search/tweets endpoint that this method uses
+            has been deprecated and has a retirement date of September 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'GET', 'search/tweets', endpoint_parameters=(
@@ -2294,6 +2369,11 @@
         returned by using this API (about being listed in the People Search).
         It is only possible to retrieve the first 1000 matches from this API.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 users/search endpoint that this method uses
+            has been deprecated and has a retirement date of September 20,
+            2023.`_
+
         Parameters
         ----------
         q
@@ -2312,6 +2392,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-search
+
+        .. _The Twitter API v1.1 users/search endpoint that this method uses
+            has been deprecated and has a retirement date of September 20,
+            2023.: https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'GET', 'users/search', endpoint_parameters=(
@@ -2624,7 +2708,8 @@
         
https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/api-reference/post-account-settings
 
         .. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601
-        .. _Rails TimeZone: 
https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
+        .. _Rails TimeZone:
+            https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
         """
         return self.request(
             'POST', 'account/settings', endpoint_parameters=(
@@ -3355,10 +3440,10 @@
                         additional_owners)
 
         Use this to upload media to Twitter. This calls either
-        :func:`API.simple_upload` or :func:`API.chunked_upload`. Chunked media
-        upload is automatically used for videos. If ``chunked`` is set or the
-        media is a video, ``wait_for_async_finalize`` can be specified as a
-        keyword argument to be passed to :func:`API.chunked_upload`.
+        :meth:`simple_upload` or :meth:`chunked_upload`. Chunked media upload
+        is automatically used for videos. If ``chunked`` is set or the media is
+        a video, ``wait_for_async_finalize`` can be specified as a keyword
+        argument to be passed to :meth:`chunked_upload`.
 
         Parameters
         ----------
@@ -3382,15 +3467,22 @@
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/overview
         """
-        h = None
-        if file is not None:
-            location = file.tell()
-            h = file.read(32)
-            file.seek(location)
-        file_type = imghdr.what(filename, h=h)
-        if file_type is not None:
-            file_type = 'image/' + file_type
+        file_type = None
+        try:
+            import imghdr
+        except ModuleNotFoundError:
+            # imghdr was removed in Python 3.13
+            pass
         else:
+            h = None
+            if file is not None:
+                location = file.tell()
+                h = file.read(32)
+                file.seek(location)
+            file_type = imghdr.what(filename, h=h)
+            if file_type is not None:
+                file_type = 'image/' + file_type
+        if file_type is None:
             file_type = mimetypes.guess_type(filename)[0]
 
         if chunked or file_type.startswith('video/'):
@@ -3458,10 +3550,10 @@
         )
 
         Use this to upload media to Twitter. This uses the chunked upload
-        endpoints and calls :func:`API.chunked_upload_init`,
-        :func:`API.chunked_upload_append`, and
-        :func:`API.chunked_upload_finalize`. If ``wait_for_async_finalize`` is
-        set, this calls :func:`API.get_media_upload_status` as well.
+        endpoints and calls :meth:`chunked_upload_init`,
+        :meth:`chunked_upload_append`, and :meth:`chunked_upload_finalize`. If
+        ``wait_for_async_finalize`` is set, this calls
+        :meth:`get_media_upload_status` as well.
 
         Parameters
         ----------
@@ -3829,25 +3921,29 @@
         """search_geo(*, lat, long, query, ip, granularity, max_results)
 
         Search for places that can be attached to a Tweet via
-        :func:`API.update_status`. Given a latitude and a longitude pair, an IP
+        :meth:`update_status`. Given a latitude and a longitude pair, an IP
         address, or a name, this request will return a list of all the valid
         places that can be used as the ``place_id`` when updating a status.
 
         Conceptually, a query can be made from the user's location, retrieve a
         list of places, have the user validate the location they are at, and
         then send the ID of this location with a call to
-        :func:`API.update_status`.
+        :meth:`update_status`.
 
         This is the recommended method to use find places that can be attached
-        to :func:`API.update_status`. Unlike :func:`API.reverse_geocode` which
-        provides raw data access, this endpoint can potentially re-order places
-        with regards to the user who is authenticated. This approach is also
+        to :meth:`update_status`. Unlike :meth:`reverse_geocode` which provides
+        raw data access, this endpoint can potentially re-order places with
+        regards to the user who is authenticated. This approach is also
         preferred for interactive place matching with the user.
 
         Some parameters in this method are only required based on the existence
         of other parameters. For instance, ``lat`` is required if ``long`` is
         provided, and vice-versa.
 
+        .. deprecated:: 4.15.0
+            `The Twitter API v1.1 geo/search endpoint that this method uses has
+            been deprecated and has a retirement date of September 20, 2023.`_
+
         .. versionchanged:: 4.0
             Renamed from ``API.geo_search``
 
@@ -3892,6 +3988,10 @@
         References
         ----------
         
https://developer.twitter.com/en/docs/twitter-api/v1/geo/places-near-location/api-reference/get-geo-search
+
+        .. _The Twitter API v1.1 geo/search endpoint that this method uses has
+            been deprecated and has a retirement date of September 20, 2023.:
+            https://twittercommunity.com/t/x-api-v2-migration/203391
         """
         return self.request(
             'GET', 'geo/search', endpoint_parameters=(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/tweepy/asynchronous/client.py 
new/tweepy-4.15.0/tweepy/asynchronous/client.py
--- old/tweepy-4.14.0/tweepy/asynchronous/client.py     2023-04-25 
00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/tweepy/asynchronous/client.py     2025-01-15 
22:05:34.000000000 +0100
@@ -169,6 +169,10 @@
 
     .. versionadded:: 4.10
 
+    .. versionchanged:: 4.15
+        Removed ``block`` and ``unblock`` methods, as the endpoints they use
+        have been removed
+
     Parameters
     ----------
     bearer_token : str | None
@@ -1719,49 +1723,6 @@
 
     # Blocks
 
-    async def unblock(self, target_user_id, *, user_auth=True):
-        """Unblock another user.
-
-        The request succeeds with no action when the user sends a request to a
-        user they're not blocking or have already unblocked.
-
-        .. note::
-
-            When using OAuth 2.0 Authorization Code Flow with PKCE with
-            ``user_auth=False``, a request is made beforehand to Twitter's API
-            to determine the authenticating user's ID. This is cached and only
-            done once per :class:`AsyncClient` instance for each access token
-            used.
-
-        Parameters
-        ----------
-        target_user_id : int | str
-            The user ID of the user that you would like to unblock.
-        user_auth : bool
-            Whether or not to use OAuth 1.0a User Context to authenticate
-
-        Raises
-        ------
-        TypeError
-            If the access token isn't set
-
-        Returns
-        -------
-        dict | aiohttp.ClientResponse | Response
-
-        References
-        ----------
-        
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking
-        """
-        source_user_id = await self._get_authenticating_user_id(
-            oauth_1=user_auth
-        )
-        route = f"/2/users/{source_user_id}/blocking/{target_user_id}"
-
-        return await self._make_request(
-            "DELETE", route, user_auth=user_auth
-        )
-
     async def get_blocked(self, *, user_auth=True, **params):
         """get_blocked( \
             *, expansions=None, max_results=None, pagination_token=None, \
@@ -1821,45 +1782,6 @@
             ), data_type=User, user_auth=user_auth
         )
 
-    async def block(self, target_user_id, *, user_auth=True):
-        """Block another user.
-
-        .. note::
-
-            When using OAuth 2.0 Authorization Code Flow with PKCE with
-            ``user_auth=False``, a request is made beforehand to Twitter's API
-            to determine the authenticating user's ID. This is cached and only
-            done once per :class:`AsyncClient` instance for each access token
-            used.
-
-        Parameters
-        ----------
-        target_user_id : int | str
-            The user ID of the user that you would like to block.
-        user_auth : bool
-            Whether or not to use OAuth 1.0a User Context to authenticate
-
-        Raises
-        ------
-        TypeError
-            If the access token isn't set
-
-        Returns
-        -------
-        dict | aiohttp.ClientResponse | Response
-
-        References
-        ----------
-        
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking
-        """
-        id = await self._get_authenticating_user_id(oauth_1=user_auth)
-        route = f"/2/users/{id}/blocking"
-
-        return await self._make_request(
-            "POST", route, json={"target_user_id": str(target_user_id)},
-            user_auth=user_auth
-        )
-
     # Follows
 
     async def unfollow_user(self, target_user_id, *, user_auth=True):
@@ -1913,6 +1835,11 @@
 
         Returns a list of users who are followers of the specified user ID.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         Parameters
         ----------
         id : int | str
@@ -1961,6 +1888,11 @@
 
         Returns a list of users the specified user ID is following.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         Parameters
         ----------
         id : int | str
@@ -2900,6 +2832,11 @@
 
         Returns a list of users who are followers of the specified List.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         Parameters
         ----------
         id : list[str] | str
@@ -2947,6 +2884,11 @@
 
         Returns all Lists a specified user follows.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         Parameters
         ----------
         id : list[str] | str
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tweepy-4.14.0/tweepy/client.py 
new/tweepy-4.15.0/tweepy/client.py
--- old/tweepy-4.14.0/tweepy/client.py  2023-04-25 00:11:27.000000000 +0200
+++ new/tweepy-4.15.0/tweepy/client.py  2025-01-15 22:05:34.000000000 +0100
@@ -211,6 +211,10 @@
 
     .. versionadded:: 4.0
 
+    .. versionchanged:: 4.15
+        Removed ``block`` and ``unblock`` methods, as the endpoints they use
+        have been removed
+
     Parameters
     ----------
     bearer_token : str | None
@@ -1828,55 +1832,6 @@
 
     # Blocks
 
-    def unblock(self, target_user_id, *, user_auth=True):
-        """Unblock another user.
-
-        The request succeeds with no action when the user sends a request to a
-        user they're not blocking or have already unblocked.
-
-        .. note::
-
-            When using OAuth 2.0 Authorization Code Flow with PKCE with
-            ``user_auth=False``, a request is made beforehand to Twitter's API
-            to determine the authenticating user's ID. This is cached and only
-            done once per :class:`Client` instance for each access token used.
-
-        .. versionchanged:: 4.5
-            Added ``user_auth`` parameter
-
-        .. versionchanged:: 4.8
-            Added support for using OAuth 2.0 Authorization Code Flow with PKCE
-
-        .. versionchanged:: 4.8
-            Changed to raise :class:`TypeError` when the access token isn't set
-
-        Parameters
-        ----------
-        target_user_id : int | str
-            The user ID of the user that you would like to unblock.
-        user_auth : bool
-            Whether or not to use OAuth 1.0a User Context to authenticate
-
-        Raises
-        ------
-        TypeError
-            If the access token isn't set
-
-        Returns
-        -------
-        dict | requests.Response | Response
-
-        References
-        ----------
-        
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking
-        """
-        source_user_id = self._get_authenticating_user_id(oauth_1=user_auth)
-        route = f"/2/users/{source_user_id}/blocking/{target_user_id}"
-
-        return self._make_request(
-            "DELETE", route, user_auth=user_auth
-        )
-
     def get_blocked(self, *, user_auth=True, **params):
         """get_blocked( \
             *, expansions=None, max_results=None, pagination_token=None, \
@@ -1944,53 +1899,6 @@
             ), data_type=User, user_auth=user_auth
         )
 
-    def block(self, target_user_id, *, user_auth=True):
-        """Block another user.
-
-        .. note::
-
-            When using OAuth 2.0 Authorization Code Flow with PKCE with
-            ``user_auth=False``, a request is made beforehand to Twitter's API
-            to determine the authenticating user's ID. This is cached and only
-            done once per :class:`Client` instance for each access token used.
-
-        .. versionchanged:: 4.5
-            Added ``user_auth`` parameter
-
-        .. versionchanged:: 4.8
-            Added support for using OAuth 2.0 Authorization Code Flow with PKCE
-
-        .. versionchanged:: 4.8
-            Changed to raise :class:`TypeError` when the access token isn't set
-
-        Parameters
-        ----------
-        target_user_id : int | str
-            The user ID of the user that you would like to block.
-        user_auth : bool
-            Whether or not to use OAuth 1.0a User Context to authenticate
-
-        Raises
-        ------
-        TypeError
-            If the access token isn't set
-
-        Returns
-        -------
-        dict | requests.Response | Response
-
-        References
-        ----------
-        
https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking
-        """
-        id = self._get_authenticating_user_id(oauth_1=user_auth)
-        route = f"/2/users/{id}/blocking"
-
-        return self._make_request(
-            "POST", route, json={"target_user_id": str(target_user_id)},
-            user_auth=user_auth
-        )
-
     # Follows
 
     def unfollow_user(self, target_user_id, *, user_auth=True):
@@ -2065,6 +1973,11 @@
 
         Returns a list of users who are followers of the specified user ID.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         Parameters
         ----------
         id : int | str
@@ -2113,6 +2026,11 @@
 
         Returns a list of users the specified user ID is following.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         Parameters
         ----------
         id : int | str
@@ -2816,7 +2734,7 @@
             ``event_type`` are returned by default. The ``text`` value isn't
             included for ``ParticipantsJoin`` and ``ParticipantsLeave`` events.
         event_types : str
-            The type of Direct Message event to returm. If not included, all
+            The type of Direct Message event to return. If not included, all
             types are returned.
         expansions : list[str] | str | None
             :ref:`expansions_parameter`
@@ -3120,6 +3038,11 @@
 
         Returns a list of users who are followers of the specified List.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         .. versionadded:: 4.4
 
         Parameters
@@ -3169,6 +3092,11 @@
 
         Returns all Lists a specified user follows.
 
+        .. note::
+
+            The Twitter API endpoint that this method uses has been removed
+            from the Basic and Pro tiers [#changelog]_.
+
         .. versionadded:: 4.4
 
         Parameters

Reply via email to