Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- venv/lib/python3.10/site-packages/git/index/__init__.py +16 -0
- venv/lib/python3.10/site-packages/git/index/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/index/__pycache__/base.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/index/__pycache__/fun.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/index/__pycache__/typ.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/index/__pycache__/util.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/index/base.py +1518 -0
- venv/lib/python3.10/site-packages/git/index/fun.py +465 -0
- venv/lib/python3.10/site-packages/git/objects/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/objects/__pycache__/blob.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/objects/__pycache__/commit.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/git/objects/__pycache__/util.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/github/CodeScanAlertInstance.py +115 -0
- venv/lib/python3.10/site-packages/github/CodeScanAlertInstanceLocation.py +95 -0
- venv/lib/python3.10/site-packages/github/CodeScanRule.py +98 -0
- venv/lib/python3.10/site-packages/github/CodeScanTool.py +87 -0
- venv/lib/python3.10/site-packages/github/CodeSecurityConfig.py +217 -0
- venv/lib/python3.10/site-packages/github/CodeSecurityConfigRepository.py +68 -0
- venv/lib/python3.10/site-packages/github/Commit.py +370 -0
- venv/lib/python3.10/site-packages/github/CommitCombinedStatus.py +114 -0
- venv/lib/python3.10/site-packages/github/CommitComment.py +253 -0
- venv/lib/python3.10/site-packages/github/CommitStats.py +74 -0
- venv/lib/python3.10/site-packages/github/CommitStatus.py +148 -0
- venv/lib/python3.10/site-packages/github/Comparison.py +170 -0
- venv/lib/python3.10/site-packages/github/Consts.py +181 -0
- venv/lib/python3.10/site-packages/github/ContentFile.py +280 -0
- venv/lib/python3.10/site-packages/github/Copilot.py +96 -0
- venv/lib/python3.10/site-packages/github/CopilotSeat.py +96 -0
- venv/lib/python3.10/site-packages/github/DefaultCodeSecurityConfig.py +84 -0
- venv/lib/python3.10/site-packages/github/DependabotAlert.py +173 -0
- venv/lib/python3.10/site-packages/github/DependabotAlertAdvisory.py +73 -0
- venv/lib/python3.10/site-packages/github/DependabotAlertDependency.py +80 -0
- venv/lib/python3.10/site-packages/github/DependabotAlertVulnerability.py +83 -0
- venv/lib/python3.10/site-packages/github/Deployment.py +298 -0
- venv/lib/python3.10/site-packages/github/DeploymentStatus.py +198 -0
- venv/lib/python3.10/site-packages/github/DiscussionBase.py +135 -0
- venv/lib/python3.10/site-packages/github/DiscussionCommentBase.py +135 -0
- venv/lib/python3.10/site-packages/github/Download.py +249 -0
- venv/lib/python3.10/site-packages/github/Enterprise.py +96 -0
- venv/lib/python3.10/site-packages/github/EnterpriseConsumedLicenses.py +109 -0
- venv/lib/python3.10/site-packages/github/Environment.py +299 -0
- venv/lib/python3.10/site-packages/github/EnvironmentDeploymentBranchPolicy.py +80 -0
- venv/lib/python3.10/site-packages/github/EnvironmentProtectionRule.py +108 -0
- venv/lib/python3.10/site-packages/github/EnvironmentProtectionRuleReviewer.py +101 -0
- venv/lib/python3.10/site-packages/github/Event.py +126 -0
- venv/lib/python3.10/site-packages/github/File.py +138 -0
- venv/lib/python3.10/site-packages/github/Gist.py +335 -0
- venv/lib/python3.10/site-packages/github/GistComment.py +150 -0
- venv/lib/python3.10/site-packages/github/__pycache__/AccessToken.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/github/__pycache__/AdvisoryBase.cpython-310.pyc +0 -0
venv/lib/python3.10/site-packages/git/index/__init__.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This module is part of GitPython and is released under the
|
| 2 |
+
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
|
| 3 |
+
|
| 4 |
+
"""Initialize the index package."""
|
| 5 |
+
|
| 6 |
+
__all__ = [
|
| 7 |
+
"BaseIndexEntry",
|
| 8 |
+
"BlobFilter",
|
| 9 |
+
"CheckoutError",
|
| 10 |
+
"IndexEntry",
|
| 11 |
+
"IndexFile",
|
| 12 |
+
"StageType",
|
| 13 |
+
]
|
| 14 |
+
|
| 15 |
+
from .base import CheckoutError, IndexFile
|
| 16 |
+
from .typ import BaseIndexEntry, BlobFilter, IndexEntry, StageType
|
venv/lib/python3.10/site-packages/git/index/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (430 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/git/index/__pycache__/base.cpython-310.pyc
ADDED
|
Binary file (47 kB). View file
|
|
|
venv/lib/python3.10/site-packages/git/index/__pycache__/fun.cpython-310.pyc
ADDED
|
Binary file (10.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/git/index/__pycache__/typ.cpython-310.pyc
ADDED
|
Binary file (7.26 kB). View file
|
|
|
venv/lib/python3.10/site-packages/git/index/__pycache__/util.cpython-310.pyc
ADDED
|
Binary file (3.89 kB). View file
|
|
|
venv/lib/python3.10/site-packages/git/index/base.py
ADDED
|
@@ -0,0 +1,1518 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors
|
| 2 |
+
#
|
| 3 |
+
# This module is part of GitPython and is released under the
|
| 4 |
+
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
|
| 5 |
+
|
| 6 |
+
"""Module containing :class:`IndexFile`, an Index implementation facilitating all kinds
|
| 7 |
+
of index manipulations such as querying and merging."""
|
| 8 |
+
|
| 9 |
+
__all__ = ["IndexFile", "CheckoutError", "StageType"]
|
| 10 |
+
|
| 11 |
+
import contextlib
|
| 12 |
+
import datetime
|
| 13 |
+
import glob
|
| 14 |
+
from io import BytesIO
|
| 15 |
+
import os
|
| 16 |
+
import os.path as osp
|
| 17 |
+
from stat import S_ISLNK
|
| 18 |
+
import subprocess
|
| 19 |
+
import sys
|
| 20 |
+
import tempfile
|
| 21 |
+
|
| 22 |
+
from gitdb.base import IStream
|
| 23 |
+
from gitdb.db import MemoryDB
|
| 24 |
+
|
| 25 |
+
from git.compat import defenc, force_bytes
|
| 26 |
+
import git.diff as git_diff
|
| 27 |
+
from git.exc import CheckoutError, GitCommandError, GitError, InvalidGitRepositoryError
|
| 28 |
+
from git.objects import Blob, Commit, Object, Submodule, Tree
|
| 29 |
+
from git.objects.util import Serializable
|
| 30 |
+
from git.util import (
|
| 31 |
+
Actor,
|
| 32 |
+
LazyMixin,
|
| 33 |
+
LockedFD,
|
| 34 |
+
join_path_native,
|
| 35 |
+
file_contents_ro,
|
| 36 |
+
to_native_path_linux,
|
| 37 |
+
unbare_repo,
|
| 38 |
+
to_bin_sha,
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
from .fun import (
|
| 42 |
+
S_IFGITLINK,
|
| 43 |
+
aggressive_tree_merge,
|
| 44 |
+
entry_key,
|
| 45 |
+
read_cache,
|
| 46 |
+
run_commit_hook,
|
| 47 |
+
stat_mode_to_index_mode,
|
| 48 |
+
write_cache,
|
| 49 |
+
write_tree_from_cache,
|
| 50 |
+
)
|
| 51 |
+
from .typ import BaseIndexEntry, IndexEntry, StageType
|
| 52 |
+
from .util import TemporaryFileSwap, post_clear_cache, default_index, git_working_dir
|
| 53 |
+
|
| 54 |
+
# typing -----------------------------------------------------------------------------
|
| 55 |
+
|
| 56 |
+
from typing import (
|
| 57 |
+
Any,
|
| 58 |
+
BinaryIO,
|
| 59 |
+
Callable,
|
| 60 |
+
Dict,
|
| 61 |
+
Generator,
|
| 62 |
+
IO,
|
| 63 |
+
Iterable,
|
| 64 |
+
Iterator,
|
| 65 |
+
List,
|
| 66 |
+
NoReturn,
|
| 67 |
+
Sequence,
|
| 68 |
+
TYPE_CHECKING,
|
| 69 |
+
Tuple,
|
| 70 |
+
Union,
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
from git.types import Literal, PathLike
|
| 74 |
+
|
| 75 |
+
if TYPE_CHECKING:
|
| 76 |
+
from subprocess import Popen
|
| 77 |
+
|
| 78 |
+
from git.refs.reference import Reference
|
| 79 |
+
from git.repo import Repo
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
Treeish = Union[Tree, Commit, str, bytes]
|
| 83 |
+
|
| 84 |
+
# ------------------------------------------------------------------------------------
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
@contextlib.contextmanager
|
| 88 |
+
def _named_temporary_file_for_subprocess(directory: PathLike) -> Generator[str, None, None]:
|
| 89 |
+
"""Create a named temporary file git subprocesses can open, deleting it afterward.
|
| 90 |
+
|
| 91 |
+
:param directory:
|
| 92 |
+
The directory in which the file is created.
|
| 93 |
+
|
| 94 |
+
:return:
|
| 95 |
+
A context manager object that creates the file and provides its name on entry,
|
| 96 |
+
and deletes it on exit.
|
| 97 |
+
"""
|
| 98 |
+
if sys.platform == "win32":
|
| 99 |
+
fd, name = tempfile.mkstemp(dir=directory)
|
| 100 |
+
os.close(fd)
|
| 101 |
+
try:
|
| 102 |
+
yield name
|
| 103 |
+
finally:
|
| 104 |
+
os.remove(name)
|
| 105 |
+
else:
|
| 106 |
+
with tempfile.NamedTemporaryFile(dir=directory) as ctx:
|
| 107 |
+
yield ctx.name
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
|
| 111 |
+
"""An Index that can be manipulated using a native implementation in order to save
|
| 112 |
+
git command function calls wherever possible.
|
| 113 |
+
|
| 114 |
+
This provides custom merging facilities allowing to merge without actually changing
|
| 115 |
+
your index or your working tree. This way you can perform your own test merges based
|
| 116 |
+
on the index only without having to deal with the working copy. This is useful in
|
| 117 |
+
case of partial working trees.
|
| 118 |
+
|
| 119 |
+
Entries:
|
| 120 |
+
|
| 121 |
+
The index contains an entries dict whose keys are tuples of type
|
| 122 |
+
:class:`~git.index.typ.IndexEntry` to facilitate access.
|
| 123 |
+
|
| 124 |
+
You may read the entries dict or manipulate it using IndexEntry instance, i.e.::
|
| 125 |
+
|
| 126 |
+
index.entries[index.entry_key(index_entry_instance)] = index_entry_instance
|
| 127 |
+
|
| 128 |
+
Make sure you use :meth:`index.write() <write>` once you are done manipulating the
|
| 129 |
+
index directly before operating on it using the git command.
|
| 130 |
+
"""
|
| 131 |
+
|
| 132 |
+
__slots__ = ("repo", "version", "entries", "_extension_data", "_file_path")
|
| 133 |
+
|
| 134 |
+
_VERSION = 2
|
| 135 |
+
"""The latest version we support."""
|
| 136 |
+
|
| 137 |
+
S_IFGITLINK = S_IFGITLINK
|
| 138 |
+
"""Flags for a submodule."""
|
| 139 |
+
|
| 140 |
+
def __init__(self, repo: "Repo", file_path: Union[PathLike, None] = None) -> None:
|
| 141 |
+
"""Initialize this Index instance, optionally from the given `file_path`.
|
| 142 |
+
|
| 143 |
+
If no `file_path` is given, we will be created from the current index file.
|
| 144 |
+
|
| 145 |
+
If a stream is not given, the stream will be initialized from the current
|
| 146 |
+
repository's index on demand.
|
| 147 |
+
"""
|
| 148 |
+
self.repo = repo
|
| 149 |
+
self.version = self._VERSION
|
| 150 |
+
self._extension_data = b""
|
| 151 |
+
self._file_path: PathLike = file_path or self._index_path()
|
| 152 |
+
|
| 153 |
+
def _set_cache_(self, attr: str) -> None:
|
| 154 |
+
if attr == "entries":
|
| 155 |
+
try:
|
| 156 |
+
fd = os.open(self._file_path, os.O_RDONLY)
|
| 157 |
+
except OSError:
|
| 158 |
+
# In new repositories, there may be no index, which means we are empty.
|
| 159 |
+
self.entries: Dict[Tuple[PathLike, StageType], IndexEntry] = {}
|
| 160 |
+
return
|
| 161 |
+
# END exception handling
|
| 162 |
+
|
| 163 |
+
try:
|
| 164 |
+
stream = file_contents_ro(fd, stream=True, allow_mmap=True)
|
| 165 |
+
finally:
|
| 166 |
+
os.close(fd)
|
| 167 |
+
|
| 168 |
+
self._deserialize(stream)
|
| 169 |
+
else:
|
| 170 |
+
super()._set_cache_(attr)
|
| 171 |
+
|
| 172 |
+
def _index_path(self) -> PathLike:
|
| 173 |
+
if self.repo.git_dir:
|
| 174 |
+
return join_path_native(self.repo.git_dir, "index")
|
| 175 |
+
else:
|
| 176 |
+
raise GitCommandError("No git directory given to join index path")
|
| 177 |
+
|
| 178 |
+
@property
|
| 179 |
+
def path(self) -> PathLike:
|
| 180 |
+
""":return: Path to the index file we are representing"""
|
| 181 |
+
return self._file_path
|
| 182 |
+
|
| 183 |
+
def _delete_entries_cache(self) -> None:
|
| 184 |
+
"""Safely clear the entries cache so it can be recreated."""
|
| 185 |
+
try:
|
| 186 |
+
del self.entries
|
| 187 |
+
except AttributeError:
|
| 188 |
+
# It failed in Python 2.6.5 with AttributeError.
|
| 189 |
+
# FIXME: Look into whether we can just remove this except clause now.
|
| 190 |
+
pass
|
| 191 |
+
# END exception handling
|
| 192 |
+
|
| 193 |
+
# { Serializable Interface
|
| 194 |
+
|
| 195 |
+
def _deserialize(self, stream: IO) -> "IndexFile":
|
| 196 |
+
"""Initialize this instance with index values read from the given stream."""
|
| 197 |
+
self.version, self.entries, self._extension_data, _conten_sha = read_cache(stream)
|
| 198 |
+
return self
|
| 199 |
+
|
| 200 |
+
def _entries_sorted(self) -> List[IndexEntry]:
|
| 201 |
+
""":return: List of entries, in a sorted fashion, first by path, then by stage"""
|
| 202 |
+
return sorted(self.entries.values(), key=lambda e: (e.path, e.stage))
|
| 203 |
+
|
| 204 |
+
def _serialize(self, stream: IO, ignore_extension_data: bool = False) -> "IndexFile":
|
| 205 |
+
entries = self._entries_sorted()
|
| 206 |
+
extension_data = self._extension_data # type: Union[None, bytes]
|
| 207 |
+
if ignore_extension_data:
|
| 208 |
+
extension_data = None
|
| 209 |
+
write_cache(entries, stream, extension_data)
|
| 210 |
+
return self
|
| 211 |
+
|
| 212 |
+
# } END serializable interface
|
| 213 |
+
|
| 214 |
+
def write(
|
| 215 |
+
self,
|
| 216 |
+
file_path: Union[None, PathLike] = None,
|
| 217 |
+
ignore_extension_data: bool = False,
|
| 218 |
+
) -> None:
|
| 219 |
+
"""Write the current state to our file path or to the given one.
|
| 220 |
+
|
| 221 |
+
:param file_path:
|
| 222 |
+
If ``None``, we will write to our stored file path from which we have been
|
| 223 |
+
initialized. Otherwise we write to the given file path. Please note that
|
| 224 |
+
this will change the `file_path` of this index to the one you gave.
|
| 225 |
+
|
| 226 |
+
:param ignore_extension_data:
|
| 227 |
+
If ``True``, the TREE type extension data read in the index will not be
|
| 228 |
+
written to disk. NOTE that no extension data is actually written. Use this
|
| 229 |
+
if you have altered the index and would like to use
|
| 230 |
+
:manpage:`git-write-tree(1)` afterwards to create a tree representing your
|
| 231 |
+
written changes. If this data is present in the written index,
|
| 232 |
+
:manpage:`git-write-tree(1)` will instead write the stored/cached tree.
|
| 233 |
+
Alternatively, use :meth:`write_tree` to handle this case automatically.
|
| 234 |
+
"""
|
| 235 |
+
# Make sure we have our entries read before getting a write lock.
|
| 236 |
+
# Otherwise it would be done when streaming.
|
| 237 |
+
# This can happen if one doesn't change the index, but writes it right away.
|
| 238 |
+
self.entries # noqa: B018
|
| 239 |
+
lfd = LockedFD(file_path or self._file_path)
|
| 240 |
+
stream = lfd.open(write=True, stream=True)
|
| 241 |
+
|
| 242 |
+
try:
|
| 243 |
+
self._serialize(stream, ignore_extension_data)
|
| 244 |
+
except BaseException:
|
| 245 |
+
lfd.rollback()
|
| 246 |
+
raise
|
| 247 |
+
|
| 248 |
+
lfd.commit()
|
| 249 |
+
|
| 250 |
+
# Make sure we represent what we have written.
|
| 251 |
+
if file_path is not None:
|
| 252 |
+
self._file_path = file_path
|
| 253 |
+
|
| 254 |
+
@post_clear_cache
|
| 255 |
+
@default_index
|
| 256 |
+
def merge_tree(self, rhs: Treeish, base: Union[None, Treeish] = None) -> "IndexFile":
|
| 257 |
+
"""Merge the given `rhs` treeish into the current index, possibly taking
|
| 258 |
+
a common base treeish into account.
|
| 259 |
+
|
| 260 |
+
As opposed to the :func:`from_tree` method, this allows you to use an already
|
| 261 |
+
existing tree as the left side of the merge.
|
| 262 |
+
|
| 263 |
+
:param rhs:
|
| 264 |
+
Treeish reference pointing to the 'other' side of the merge.
|
| 265 |
+
|
| 266 |
+
:param base:
|
| 267 |
+
Optional treeish reference pointing to the common base of `rhs` and this
|
| 268 |
+
index which equals lhs.
|
| 269 |
+
|
| 270 |
+
:return:
|
| 271 |
+
self (containing the merge and possibly unmerged entries in case of
|
| 272 |
+
conflicts)
|
| 273 |
+
|
| 274 |
+
:raise git.exc.GitCommandError:
|
| 275 |
+
If there is a merge conflict. The error will be raised at the first
|
| 276 |
+
conflicting path. If you want to have proper merge resolution to be done by
|
| 277 |
+
yourself, you have to commit the changed index (or make a valid tree from
|
| 278 |
+
it) and retry with a three-way :meth:`index.from_tree <from_tree>` call.
|
| 279 |
+
"""
|
| 280 |
+
# -i : ignore working tree status
|
| 281 |
+
# --aggressive : handle more merge cases
|
| 282 |
+
# -m : do an actual merge
|
| 283 |
+
args: List[Union[Treeish, str]] = ["--aggressive", "-i", "-m"]
|
| 284 |
+
if base is not None:
|
| 285 |
+
args.append(base)
|
| 286 |
+
args.append(rhs)
|
| 287 |
+
|
| 288 |
+
self.repo.git.read_tree(args)
|
| 289 |
+
return self
|
| 290 |
+
|
| 291 |
+
@classmethod
|
| 292 |
+
def new(cls, repo: "Repo", *tree_sha: Union[str, Tree]) -> "IndexFile":
|
| 293 |
+
"""Merge the given treeish revisions into a new index which is returned.
|
| 294 |
+
|
| 295 |
+
This method behaves like ``git-read-tree --aggressive`` when doing the merge.
|
| 296 |
+
|
| 297 |
+
:param repo:
|
| 298 |
+
The repository treeish are located in.
|
| 299 |
+
|
| 300 |
+
:param tree_sha:
|
| 301 |
+
20 byte or 40 byte tree sha or tree objects.
|
| 302 |
+
|
| 303 |
+
:return:
|
| 304 |
+
New :class:`IndexFile` instance. Its path will be undefined.
|
| 305 |
+
If you intend to write such a merged Index, supply an alternate
|
| 306 |
+
``file_path`` to its :meth:`write` method.
|
| 307 |
+
"""
|
| 308 |
+
tree_sha_bytes: List[bytes] = [to_bin_sha(str(t)) for t in tree_sha]
|
| 309 |
+
base_entries = aggressive_tree_merge(repo.odb, tree_sha_bytes)
|
| 310 |
+
|
| 311 |
+
inst = cls(repo)
|
| 312 |
+
# Convert to entries dict.
|
| 313 |
+
entries: Dict[Tuple[PathLike, int], IndexEntry] = dict(
|
| 314 |
+
zip(
|
| 315 |
+
((e.path, e.stage) for e in base_entries),
|
| 316 |
+
(IndexEntry.from_base(e) for e in base_entries),
|
| 317 |
+
)
|
| 318 |
+
)
|
| 319 |
+
|
| 320 |
+
inst.entries = entries
|
| 321 |
+
return inst
|
| 322 |
+
|
| 323 |
+
@classmethod
|
| 324 |
+
def from_tree(cls, repo: "Repo", *treeish: Treeish, **kwargs: Any) -> "IndexFile":
|
| 325 |
+
R"""Merge the given treeish revisions into a new index which is returned.
|
| 326 |
+
The original index will remain unaltered.
|
| 327 |
+
|
| 328 |
+
:param repo:
|
| 329 |
+
The repository treeish are located in.
|
| 330 |
+
|
| 331 |
+
:param treeish:
|
| 332 |
+
One, two or three :class:`~git.objects.tree.Tree` objects,
|
| 333 |
+
:class:`~git.objects.commit.Commit`\s or 40 byte hexshas.
|
| 334 |
+
|
| 335 |
+
The result changes according to the amount of trees:
|
| 336 |
+
|
| 337 |
+
1. If 1 Tree is given, it will just be read into a new index.
|
| 338 |
+
2. If 2 Trees are given, they will be merged into a new index using a two
|
| 339 |
+
way merge algorithm. Tree 1 is the 'current' tree, tree 2 is the 'other'
|
| 340 |
+
one. It behaves like a fast-forward.
|
| 341 |
+
3. If 3 Trees are given, a 3-way merge will be performed with the first tree
|
| 342 |
+
being the common ancestor of tree 2 and tree 3. Tree 2 is the 'current'
|
| 343 |
+
tree, tree 3 is the 'other' one.
|
| 344 |
+
|
| 345 |
+
:param kwargs:
|
| 346 |
+
Additional arguments passed to :manpage:`git-read-tree(1)`.
|
| 347 |
+
|
| 348 |
+
:return:
|
| 349 |
+
New :class:`IndexFile` instance. It will point to a temporary index location
|
| 350 |
+
which does not exist anymore. If you intend to write such a merged Index,
|
| 351 |
+
supply an alternate ``file_path`` to its :meth:`write` method.
|
| 352 |
+
|
| 353 |
+
:note:
|
| 354 |
+
In the three-way merge case, ``--aggressive`` will be specified to
|
| 355 |
+
automatically resolve more cases in a commonly correct manner. Specify
|
| 356 |
+
``trivial=True`` as a keyword argument to override that.
|
| 357 |
+
|
| 358 |
+
As the underlying :manpage:`git-read-tree(1)` command takes into account the
|
| 359 |
+
current index, it will be temporarily moved out of the way to prevent any
|
| 360 |
+
unexpected interference.
|
| 361 |
+
"""
|
| 362 |
+
if len(treeish) == 0 or len(treeish) > 3:
|
| 363 |
+
raise ValueError("Please specify between 1 and 3 treeish, got %i" % len(treeish))
|
| 364 |
+
|
| 365 |
+
arg_list: List[Union[Treeish, str]] = []
|
| 366 |
+
# Ignore that the working tree and index possibly are out of date.
|
| 367 |
+
if len(treeish) > 1:
|
| 368 |
+
# Drop unmerged entries when reading our index and merging.
|
| 369 |
+
arg_list.append("--reset")
|
| 370 |
+
# Handle non-trivial cases the way a real merge does.
|
| 371 |
+
arg_list.append("--aggressive")
|
| 372 |
+
# END merge handling
|
| 373 |
+
|
| 374 |
+
# Create the temporary file in the .git directory to be sure renaming
|
| 375 |
+
# works - /tmp/ directories could be on another device.
|
| 376 |
+
with _named_temporary_file_for_subprocess(repo.git_dir) as tmp_index:
|
| 377 |
+
arg_list.append("--index-output=%s" % tmp_index)
|
| 378 |
+
arg_list.extend(treeish)
|
| 379 |
+
|
| 380 |
+
# Move the current index out of the way - otherwise the merge may fail as it
|
| 381 |
+
# considers existing entries. Moving it essentially clears the index.
|
| 382 |
+
# Unfortunately there is no 'soft' way to do it.
|
| 383 |
+
# The TemporaryFileSwap ensures the original file gets put back.
|
| 384 |
+
with TemporaryFileSwap(join_path_native(repo.git_dir, "index")):
|
| 385 |
+
repo.git.read_tree(*arg_list, **kwargs)
|
| 386 |
+
index = cls(repo, tmp_index)
|
| 387 |
+
index.entries # noqa: B018 # Force it to read the file as we will delete the temp-file.
|
| 388 |
+
return index
|
| 389 |
+
# END index merge handling
|
| 390 |
+
|
| 391 |
+
# UTILITIES
|
| 392 |
+
|
| 393 |
+
@unbare_repo
|
| 394 |
+
def _iter_expand_paths(self: "IndexFile", paths: Sequence[PathLike]) -> Iterator[PathLike]:
|
| 395 |
+
"""Expand the directories in list of paths to the corresponding paths
|
| 396 |
+
accordingly.
|
| 397 |
+
|
| 398 |
+
:note:
|
| 399 |
+
git will add items multiple times even if a glob overlapped with manually
|
| 400 |
+
specified paths or if paths where specified multiple times - we respect that
|
| 401 |
+
and do not prune.
|
| 402 |
+
"""
|
| 403 |
+
|
| 404 |
+
def raise_exc(e: Exception) -> NoReturn:
|
| 405 |
+
raise e
|
| 406 |
+
|
| 407 |
+
r = str(self.repo.working_tree_dir)
|
| 408 |
+
rs = r + os.sep
|
| 409 |
+
for path in paths:
|
| 410 |
+
abs_path = str(path)
|
| 411 |
+
if not osp.isabs(abs_path):
|
| 412 |
+
abs_path = osp.join(r, path)
|
| 413 |
+
# END make absolute path
|
| 414 |
+
|
| 415 |
+
try:
|
| 416 |
+
st = os.lstat(abs_path) # Handles non-symlinks as well.
|
| 417 |
+
except OSError:
|
| 418 |
+
# The lstat call may fail as the path may contain globs as well.
|
| 419 |
+
pass
|
| 420 |
+
else:
|
| 421 |
+
if S_ISLNK(st.st_mode):
|
| 422 |
+
yield abs_path.replace(rs, "")
|
| 423 |
+
continue
|
| 424 |
+
# END check symlink
|
| 425 |
+
|
| 426 |
+
# If the path is not already pointing to an existing file, resolve globs if possible.
|
| 427 |
+
if not os.path.exists(abs_path) and ("?" in abs_path or "*" in abs_path or "[" in abs_path):
|
| 428 |
+
resolved_paths = glob.glob(abs_path)
|
| 429 |
+
# not abs_path in resolved_paths:
|
| 430 |
+
# A glob() resolving to the same path we are feeding it with is a
|
| 431 |
+
# glob() that failed to resolve. If we continued calling ourselves
|
| 432 |
+
# we'd endlessly recurse. If the condition below evaluates to true
|
| 433 |
+
# then we are likely dealing with a file whose name contains wildcard
|
| 434 |
+
# characters.
|
| 435 |
+
if abs_path not in resolved_paths:
|
| 436 |
+
for f in self._iter_expand_paths(glob.glob(abs_path)):
|
| 437 |
+
yield str(f).replace(rs, "")
|
| 438 |
+
continue
|
| 439 |
+
# END glob handling
|
| 440 |
+
try:
|
| 441 |
+
for root, _dirs, files in os.walk(abs_path, onerror=raise_exc):
|
| 442 |
+
for rela_file in files:
|
| 443 |
+
# Add relative paths only.
|
| 444 |
+
yield osp.join(root.replace(rs, ""), rela_file)
|
| 445 |
+
# END for each file in subdir
|
| 446 |
+
# END for each subdirectory
|
| 447 |
+
except OSError:
|
| 448 |
+
# It was a file or something that could not be iterated.
|
| 449 |
+
yield abs_path.replace(rs, "")
|
| 450 |
+
# END path exception handling
|
| 451 |
+
# END for each path
|
| 452 |
+
|
| 453 |
+
def _write_path_to_stdin(
|
| 454 |
+
self,
|
| 455 |
+
proc: "Popen",
|
| 456 |
+
filepath: PathLike,
|
| 457 |
+
item: PathLike,
|
| 458 |
+
fmakeexc: Callable[..., GitError],
|
| 459 |
+
fprogress: Callable[[PathLike, bool, PathLike], None],
|
| 460 |
+
read_from_stdout: bool = True,
|
| 461 |
+
) -> Union[None, str]:
|
| 462 |
+
"""Write path to ``proc.stdin`` and make sure it processes the item, including
|
| 463 |
+
progress.
|
| 464 |
+
|
| 465 |
+
:return:
|
| 466 |
+
stdout string
|
| 467 |
+
|
| 468 |
+
:param read_from_stdout:
|
| 469 |
+
If ``True``, ``proc.stdout`` will be read after the item was sent to stdin.
|
| 470 |
+
In that case, it will return ``None``.
|
| 471 |
+
|
| 472 |
+
:note:
|
| 473 |
+
There is a bug in :manpage:`git-update-index(1)` that prevents it from
|
| 474 |
+
sending reports just in time. This is why we have a version that tries to
|
| 475 |
+
read stdout and one which doesn't. In fact, the stdout is not important as
|
| 476 |
+
the piped-in files are processed anyway and just in time.
|
| 477 |
+
|
| 478 |
+
:note:
|
| 479 |
+
Newlines are essential here, git's behaviour is somewhat inconsistent on
|
| 480 |
+
this depending on the version, hence we try our best to deal with newlines
|
| 481 |
+
carefully. Usually the last newline will not be sent, instead we will close
|
| 482 |
+
stdin to break the pipe.
|
| 483 |
+
"""
|
| 484 |
+
fprogress(filepath, False, item)
|
| 485 |
+
rval: Union[None, str] = None
|
| 486 |
+
|
| 487 |
+
if proc.stdin is not None:
|
| 488 |
+
try:
|
| 489 |
+
proc.stdin.write(("%s\n" % filepath).encode(defenc))
|
| 490 |
+
except IOError as e:
|
| 491 |
+
# Pipe broke, usually because some error happened.
|
| 492 |
+
raise fmakeexc() from e
|
| 493 |
+
# END write exception handling
|
| 494 |
+
proc.stdin.flush()
|
| 495 |
+
|
| 496 |
+
if read_from_stdout and proc.stdout is not None:
|
| 497 |
+
rval = proc.stdout.readline().strip()
|
| 498 |
+
fprogress(filepath, True, item)
|
| 499 |
+
return rval
|
| 500 |
+
|
| 501 |
+
def iter_blobs(
|
| 502 |
+
self, predicate: Callable[[Tuple[StageType, Blob]], bool] = lambda t: True
|
| 503 |
+
) -> Iterator[Tuple[StageType, Blob]]:
|
| 504 |
+
"""
|
| 505 |
+
:return:
|
| 506 |
+
Iterator yielding tuples of :class:`~git.objects.blob.Blob` objects and
|
| 507 |
+
stages, tuple(stage, Blob).
|
| 508 |
+
|
| 509 |
+
:param predicate:
|
| 510 |
+
Function(t) returning ``True`` if tuple(stage, Blob) should be yielded by
|
| 511 |
+
the iterator. A default filter, the `~git.index.typ.BlobFilter`, allows you
|
| 512 |
+
to yield blobs only if they match a given list of paths.
|
| 513 |
+
"""
|
| 514 |
+
for entry in self.entries.values():
|
| 515 |
+
blob = entry.to_blob(self.repo)
|
| 516 |
+
blob.size = entry.size
|
| 517 |
+
output = (entry.stage, blob)
|
| 518 |
+
if predicate(output):
|
| 519 |
+
yield output
|
| 520 |
+
# END for each entry
|
| 521 |
+
|
| 522 |
+
def unmerged_blobs(self) -> Dict[PathLike, List[Tuple[StageType, Blob]]]:
|
| 523 |
+
"""
|
| 524 |
+
:return:
|
| 525 |
+
Dict(path : list(tuple(stage, Blob, ...))), being a dictionary associating a
|
| 526 |
+
path in the index with a list containing sorted stage/blob pairs.
|
| 527 |
+
|
| 528 |
+
:note:
|
| 529 |
+
Blobs that have been removed in one side simply do not exist in the given
|
| 530 |
+
stage. That is, a file removed on the 'other' branch whose entries are at
|
| 531 |
+
stage 3 will not have a stage 3 entry.
|
| 532 |
+
"""
|
| 533 |
+
is_unmerged_blob = lambda t: t[0] != 0
|
| 534 |
+
path_map: Dict[PathLike, List[Tuple[StageType, Blob]]] = {}
|
| 535 |
+
for stage, blob in self.iter_blobs(is_unmerged_blob):
|
| 536 |
+
path_map.setdefault(blob.path, []).append((stage, blob))
|
| 537 |
+
# END for each unmerged blob
|
| 538 |
+
for line in path_map.values():
|
| 539 |
+
line.sort()
|
| 540 |
+
|
| 541 |
+
return path_map
|
| 542 |
+
|
| 543 |
+
@classmethod
|
| 544 |
+
def entry_key(cls, *entry: Union[BaseIndexEntry, PathLike, StageType]) -> Tuple[PathLike, StageType]:
|
| 545 |
+
return entry_key(*entry)
|
| 546 |
+
|
| 547 |
+
def resolve_blobs(self, iter_blobs: Iterator[Blob]) -> "IndexFile":
|
| 548 |
+
"""Resolve the blobs given in blob iterator.
|
| 549 |
+
|
| 550 |
+
This will effectively remove the index entries of the respective path at all
|
| 551 |
+
non-null stages and add the given blob as new stage null blob.
|
| 552 |
+
|
| 553 |
+
For each path there may only be one blob, otherwise a :exc:`ValueError` will be
|
| 554 |
+
raised claiming the path is already at stage 0.
|
| 555 |
+
|
| 556 |
+
:raise ValueError:
|
| 557 |
+
If one of the blobs already existed at stage 0.
|
| 558 |
+
|
| 559 |
+
:return:
|
| 560 |
+
self
|
| 561 |
+
|
| 562 |
+
:note:
|
| 563 |
+
You will have to write the index manually once you are done, i.e.
|
| 564 |
+
``index.resolve_blobs(blobs).write()``.
|
| 565 |
+
"""
|
| 566 |
+
for blob in iter_blobs:
|
| 567 |
+
stage_null_key = (blob.path, 0)
|
| 568 |
+
if stage_null_key in self.entries:
|
| 569 |
+
raise ValueError("Path %r already exists at stage 0" % str(blob.path))
|
| 570 |
+
# END assert blob is not stage 0 already
|
| 571 |
+
|
| 572 |
+
# Delete all possible stages.
|
| 573 |
+
for stage in (1, 2, 3):
|
| 574 |
+
try:
|
| 575 |
+
del self.entries[(blob.path, stage)]
|
| 576 |
+
except KeyError:
|
| 577 |
+
pass
|
| 578 |
+
# END ignore key errors
|
| 579 |
+
# END for each possible stage
|
| 580 |
+
|
| 581 |
+
self.entries[stage_null_key] = IndexEntry.from_blob(blob)
|
| 582 |
+
# END for each blob
|
| 583 |
+
|
| 584 |
+
return self
|
| 585 |
+
|
| 586 |
+
def update(self) -> "IndexFile":
|
| 587 |
+
"""Reread the contents of our index file, discarding all cached information
|
| 588 |
+
we might have.
|
| 589 |
+
|
| 590 |
+
:note:
|
| 591 |
+
This is a possibly dangerous operations as it will discard your changes to
|
| 592 |
+
:attr:`index.entries <entries>`.
|
| 593 |
+
|
| 594 |
+
:return:
|
| 595 |
+
self
|
| 596 |
+
"""
|
| 597 |
+
self._delete_entries_cache()
|
| 598 |
+
# Allows to lazily reread on demand.
|
| 599 |
+
return self
|
| 600 |
+
|
| 601 |
+
def write_tree(self) -> Tree:
|
| 602 |
+
"""Write this index to a corresponding :class:`~git.objects.tree.Tree` object
|
| 603 |
+
into the repository's object database and return it.
|
| 604 |
+
|
| 605 |
+
:return:
|
| 606 |
+
:class:`~git.objects.tree.Tree` object representing this index.
|
| 607 |
+
|
| 608 |
+
:note:
|
| 609 |
+
The tree will be written even if one or more objects the tree refers to does
|
| 610 |
+
not yet exist in the object database. This could happen if you added entries
|
| 611 |
+
to the index directly.
|
| 612 |
+
|
| 613 |
+
:raise ValueError:
|
| 614 |
+
If there are no entries in the cache.
|
| 615 |
+
|
| 616 |
+
:raise git.exc.UnmergedEntriesError:
|
| 617 |
+
"""
|
| 618 |
+
# We obtain no lock as we just flush our contents to disk as tree.
|
| 619 |
+
# If we are a new index, the entries access will load our data accordingly.
|
| 620 |
+
mdb = MemoryDB()
|
| 621 |
+
entries = self._entries_sorted()
|
| 622 |
+
binsha, tree_items = write_tree_from_cache(entries, mdb, slice(0, len(entries)))
|
| 623 |
+
|
| 624 |
+
# Copy changed trees only.
|
| 625 |
+
mdb.stream_copy(mdb.sha_iter(), self.repo.odb)
|
| 626 |
+
|
| 627 |
+
# Note: Additional deserialization could be saved if write_tree_from_cache would
|
| 628 |
+
# return sorted tree entries.
|
| 629 |
+
root_tree = Tree(self.repo, binsha, path="")
|
| 630 |
+
root_tree._cache = tree_items
|
| 631 |
+
return root_tree
|
| 632 |
+
|
| 633 |
+
def _process_diff_args(
|
| 634 |
+
self,
|
| 635 |
+
args: List[Union[PathLike, "git_diff.Diffable"]],
|
| 636 |
+
) -> List[Union[PathLike, "git_diff.Diffable"]]:
|
| 637 |
+
try:
|
| 638 |
+
args.pop(args.index(self))
|
| 639 |
+
except IndexError:
|
| 640 |
+
pass
|
| 641 |
+
# END remove self
|
| 642 |
+
return args
|
| 643 |
+
|
| 644 |
+
def _to_relative_path(self, path: PathLike) -> PathLike:
|
| 645 |
+
"""
|
| 646 |
+
:return:
|
| 647 |
+
Version of path relative to our git directory or raise :exc:`ValueError` if
|
| 648 |
+
it is not within our git directory.
|
| 649 |
+
|
| 650 |
+
:raise ValueError:
|
| 651 |
+
"""
|
| 652 |
+
if not osp.isabs(path):
|
| 653 |
+
return path
|
| 654 |
+
if self.repo.bare:
|
| 655 |
+
raise InvalidGitRepositoryError("require non-bare repository")
|
| 656 |
+
if not osp.normpath(str(path)).startswith(str(self.repo.working_tree_dir)):
|
| 657 |
+
raise ValueError("Absolute path %r is not in git repository at %r" % (path, self.repo.working_tree_dir))
|
| 658 |
+
return os.path.relpath(path, self.repo.working_tree_dir)
|
| 659 |
+
|
| 660 |
+
def _preprocess_add_items(
|
| 661 |
+
self, items: Union[PathLike, Sequence[Union[PathLike, Blob, BaseIndexEntry, "Submodule"]]]
|
| 662 |
+
) -> Tuple[List[PathLike], List[BaseIndexEntry]]:
|
| 663 |
+
"""Split the items into two lists of path strings and BaseEntries."""
|
| 664 |
+
paths = []
|
| 665 |
+
entries = []
|
| 666 |
+
# if it is a string put in list
|
| 667 |
+
if isinstance(items, (str, os.PathLike)):
|
| 668 |
+
items = [items]
|
| 669 |
+
|
| 670 |
+
for item in items:
|
| 671 |
+
if isinstance(item, (str, os.PathLike)):
|
| 672 |
+
paths.append(self._to_relative_path(item))
|
| 673 |
+
elif isinstance(item, (Blob, Submodule)):
|
| 674 |
+
entries.append(BaseIndexEntry.from_blob(item))
|
| 675 |
+
elif isinstance(item, BaseIndexEntry):
|
| 676 |
+
entries.append(item)
|
| 677 |
+
else:
|
| 678 |
+
raise TypeError("Invalid Type: %r" % item)
|
| 679 |
+
# END for each item
|
| 680 |
+
return paths, entries
|
| 681 |
+
|
| 682 |
+
def _store_path(self, filepath: PathLike, fprogress: Callable) -> BaseIndexEntry:
|
| 683 |
+
"""Store file at filepath in the database and return the base index entry.
|
| 684 |
+
|
| 685 |
+
:note:
|
| 686 |
+
This needs the :func:`~git.index.util.git_working_dir` decorator active!
|
| 687 |
+
This must be ensured in the calling code.
|
| 688 |
+
"""
|
| 689 |
+
st = os.lstat(filepath) # Handles non-symlinks as well.
|
| 690 |
+
if S_ISLNK(st.st_mode):
|
| 691 |
+
# In PY3, readlink is a string, but we need bytes.
|
| 692 |
+
# In PY2, it was just OS encoded bytes, we assumed UTF-8.
|
| 693 |
+
open_stream: Callable[[], BinaryIO] = lambda: BytesIO(force_bytes(os.readlink(filepath), encoding=defenc))
|
| 694 |
+
else:
|
| 695 |
+
open_stream = lambda: open(filepath, "rb")
|
| 696 |
+
with open_stream() as stream:
|
| 697 |
+
fprogress(filepath, False, filepath)
|
| 698 |
+
istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream))
|
| 699 |
+
fprogress(filepath, True, filepath)
|
| 700 |
+
return BaseIndexEntry(
|
| 701 |
+
(
|
| 702 |
+
stat_mode_to_index_mode(st.st_mode),
|
| 703 |
+
istream.binsha,
|
| 704 |
+
0,
|
| 705 |
+
to_native_path_linux(filepath),
|
| 706 |
+
)
|
| 707 |
+
)
|
| 708 |
+
|
| 709 |
+
@unbare_repo
|
| 710 |
+
@git_working_dir
|
| 711 |
+
def _entries_for_paths(
|
| 712 |
+
self,
|
| 713 |
+
paths: List[str],
|
| 714 |
+
path_rewriter: Union[Callable, None],
|
| 715 |
+
fprogress: Callable,
|
| 716 |
+
entries: List[BaseIndexEntry],
|
| 717 |
+
) -> List[BaseIndexEntry]:
|
| 718 |
+
entries_added: List[BaseIndexEntry] = []
|
| 719 |
+
if path_rewriter:
|
| 720 |
+
for path in paths:
|
| 721 |
+
if osp.isabs(path):
|
| 722 |
+
abspath = path
|
| 723 |
+
gitrelative_path = path[len(str(self.repo.working_tree_dir)) + 1 :]
|
| 724 |
+
else:
|
| 725 |
+
gitrelative_path = path
|
| 726 |
+
if self.repo.working_tree_dir:
|
| 727 |
+
abspath = osp.join(self.repo.working_tree_dir, gitrelative_path)
|
| 728 |
+
# END obtain relative and absolute paths
|
| 729 |
+
|
| 730 |
+
blob = Blob(
|
| 731 |
+
self.repo,
|
| 732 |
+
Blob.NULL_BIN_SHA,
|
| 733 |
+
stat_mode_to_index_mode(os.stat(abspath).st_mode),
|
| 734 |
+
to_native_path_linux(gitrelative_path),
|
| 735 |
+
)
|
| 736 |
+
# TODO: variable undefined
|
| 737 |
+
entries.append(BaseIndexEntry.from_blob(blob))
|
| 738 |
+
# END for each path
|
| 739 |
+
del paths[:]
|
| 740 |
+
# END rewrite paths
|
| 741 |
+
|
| 742 |
+
# HANDLE PATHS
|
| 743 |
+
assert len(entries_added) == 0
|
| 744 |
+
for filepath in self._iter_expand_paths(paths):
|
| 745 |
+
entries_added.append(self._store_path(filepath, fprogress))
|
| 746 |
+
# END for each filepath
|
| 747 |
+
# END path handling
|
| 748 |
+
return entries_added
|
| 749 |
+
|
| 750 |
+
def add(
|
| 751 |
+
self,
|
| 752 |
+
items: Union[PathLike, Sequence[Union[PathLike, Blob, BaseIndexEntry, "Submodule"]]],
|
| 753 |
+
force: bool = True,
|
| 754 |
+
fprogress: Callable = lambda *args: None,
|
| 755 |
+
path_rewriter: Union[Callable[..., PathLike], None] = None,
|
| 756 |
+
write: bool = True,
|
| 757 |
+
write_extension_data: bool = False,
|
| 758 |
+
) -> List[BaseIndexEntry]:
|
| 759 |
+
R"""Add files from the working tree, specific blobs, or
|
| 760 |
+
:class:`~git.index.typ.BaseIndexEntry`\s to the index.
|
| 761 |
+
|
| 762 |
+
:param items:
|
| 763 |
+
Multiple types of items are supported, types can be mixed within one call.
|
| 764 |
+
Different types imply a different handling. File paths may generally be
|
| 765 |
+
relative or absolute.
|
| 766 |
+
|
| 767 |
+
- path string
|
| 768 |
+
|
| 769 |
+
Strings denote a relative or absolute path into the repository pointing
|
| 770 |
+
to an existing file, e.g., ``CHANGES``, `lib/myfile.ext``,
|
| 771 |
+
``/home/gitrepo/lib/myfile.ext``.
|
| 772 |
+
|
| 773 |
+
Absolute paths must start with working tree directory of this index's
|
| 774 |
+
repository to be considered valid. For example, if it was initialized
|
| 775 |
+
with a non-normalized path, like ``/root/repo/../repo``, absolute paths
|
| 776 |
+
to be added must start with ``/root/repo/../repo``.
|
| 777 |
+
|
| 778 |
+
Paths provided like this must exist. When added, they will be written
|
| 779 |
+
into the object database.
|
| 780 |
+
|
| 781 |
+
PathStrings may contain globs, such as ``lib/__init__*``. Or they can be
|
| 782 |
+
directories like ``lib``, which will add all the files within the
|
| 783 |
+
directory and subdirectories.
|
| 784 |
+
|
| 785 |
+
This equals a straight :manpage:`git-add(1)`.
|
| 786 |
+
|
| 787 |
+
They are added at stage 0.
|
| 788 |
+
|
| 789 |
+
- :class:~`git.objects.blob.Blob` or
|
| 790 |
+
:class:`~git.objects.submodule.base.Submodule` object
|
| 791 |
+
|
| 792 |
+
Blobs are added as they are assuming a valid mode is set.
|
| 793 |
+
|
| 794 |
+
The file they refer to may or may not exist in the file system, but must
|
| 795 |
+
be a path relative to our repository.
|
| 796 |
+
|
| 797 |
+
If their sha is null (40*0), their path must exist in the file system
|
| 798 |
+
relative to the git repository as an object will be created from the
|
| 799 |
+
data at the path.
|
| 800 |
+
|
| 801 |
+
The handling now very much equals the way string paths are processed,
|
| 802 |
+
except that the mode you have set will be kept. This allows you to
|
| 803 |
+
create symlinks by settings the mode respectively and writing the target
|
| 804 |
+
of the symlink directly into the file. This equals a default Linux
|
| 805 |
+
symlink which is not dereferenced automatically, except that it can be
|
| 806 |
+
created on filesystems not supporting it as well.
|
| 807 |
+
|
| 808 |
+
Please note that globs or directories are not allowed in
|
| 809 |
+
:class:`~git.objects.blob.Blob` objects.
|
| 810 |
+
|
| 811 |
+
They are added at stage 0.
|
| 812 |
+
|
| 813 |
+
- :class:`~git.index.typ.BaseIndexEntry` or type
|
| 814 |
+
|
| 815 |
+
Handling equals the one of :class:~`git.objects.blob.Blob` objects, but
|
| 816 |
+
the stage may be explicitly set. Please note that Index Entries require
|
| 817 |
+
binary sha's.
|
| 818 |
+
|
| 819 |
+
:param force:
|
| 820 |
+
**CURRENTLY INEFFECTIVE**
|
| 821 |
+
If ``True``, otherwise ignored or excluded files will be added anyway. As
|
| 822 |
+
opposed to the :manpage:`git-add(1)` command, we enable this flag by default
|
| 823 |
+
as the API user usually wants the item to be added even though they might be
|
| 824 |
+
excluded.
|
| 825 |
+
|
| 826 |
+
:param fprogress:
|
| 827 |
+
Function with signature ``f(path, done=False, item=item)`` called for each
|
| 828 |
+
path to be added, one time once it is about to be added where ``done=False``
|
| 829 |
+
and once after it was added where ``done=True``.
|
| 830 |
+
|
| 831 |
+
``item`` is set to the actual item we handle, either a path or a
|
| 832 |
+
:class:`~git.index.typ.BaseIndexEntry`.
|
| 833 |
+
|
| 834 |
+
Please note that the processed path is not guaranteed to be present in the
|
| 835 |
+
index already as the index is currently being processed.
|
| 836 |
+
|
| 837 |
+
:param path_rewriter:
|
| 838 |
+
Function, with signature ``(string) func(BaseIndexEntry)``, returning a path
|
| 839 |
+
for each passed entry which is the path to be actually recorded for the
|
| 840 |
+
object created from :attr:`entry.path <git.index.typ.BaseIndexEntry.path>`.
|
| 841 |
+
This allows you to write an index which is not identical to the layout of
|
| 842 |
+
the actual files on your hard-disk. If not ``None`` and `items` contain
|
| 843 |
+
plain paths, these paths will be converted to Entries beforehand and passed
|
| 844 |
+
to the path_rewriter. Please note that ``entry.path`` is relative to the git
|
| 845 |
+
repository.
|
| 846 |
+
|
| 847 |
+
:param write:
|
| 848 |
+
If ``True``, the index will be written once it was altered. Otherwise the
|
| 849 |
+
changes only exist in memory and are not available to git commands.
|
| 850 |
+
|
| 851 |
+
:param write_extension_data:
|
| 852 |
+
If ``True``, extension data will be written back to the index. This can lead
|
| 853 |
+
to issues in case it is containing the 'TREE' extension, which will cause
|
| 854 |
+
the :manpage:`git-commit(1)` command to write an old tree, instead of a new
|
| 855 |
+
one representing the now changed index.
|
| 856 |
+
|
| 857 |
+
This doesn't matter if you use :meth:`IndexFile.commit`, which ignores the
|
| 858 |
+
'TREE' extension altogether. You should set it to ``True`` if you intend to
|
| 859 |
+
use :meth:`IndexFile.commit` exclusively while maintaining support for
|
| 860 |
+
third-party extensions. Besides that, you can usually safely ignore the
|
| 861 |
+
built-in extensions when using GitPython on repositories that are not
|
| 862 |
+
handled manually at all.
|
| 863 |
+
|
| 864 |
+
All current built-in extensions are listed here:
|
| 865 |
+
https://git-scm.com/docs/index-format
|
| 866 |
+
|
| 867 |
+
:return:
|
| 868 |
+
List of :class:`~git.index.typ.BaseIndexEntry`\s representing the entries
|
| 869 |
+
just actually added.
|
| 870 |
+
|
| 871 |
+
:raise OSError:
|
| 872 |
+
If a supplied path did not exist. Please note that
|
| 873 |
+
:class:`~git.index.typ.BaseIndexEntry` objects that do not have a null sha
|
| 874 |
+
will be added even if their paths do not exist.
|
| 875 |
+
"""
|
| 876 |
+
# Sort the entries into strings and Entries.
|
| 877 |
+
# Blobs are converted to entries automatically.
|
| 878 |
+
# Paths can be git-added. For everything else we use git-update-index.
|
| 879 |
+
paths, entries = self._preprocess_add_items(items)
|
| 880 |
+
entries_added: List[BaseIndexEntry] = []
|
| 881 |
+
# This code needs a working tree, so we try not to run it unless required.
|
| 882 |
+
# That way, we are OK on a bare repository as well.
|
| 883 |
+
# If there are no paths, the rewriter has nothing to do either.
|
| 884 |
+
if paths:
|
| 885 |
+
entries_added.extend(self._entries_for_paths(paths, path_rewriter, fprogress, entries))
|
| 886 |
+
|
| 887 |
+
# HANDLE ENTRIES
|
| 888 |
+
if entries:
|
| 889 |
+
null_mode_entries = [e for e in entries if e.mode == 0]
|
| 890 |
+
if null_mode_entries:
|
| 891 |
+
raise ValueError(
|
| 892 |
+
"At least one Entry has a null-mode - please use index.remove to remove files for clarity"
|
| 893 |
+
)
|
| 894 |
+
# END null mode should be remove
|
| 895 |
+
|
| 896 |
+
# HANDLE ENTRY OBJECT CREATION
|
| 897 |
+
# Create objects if required, otherwise go with the existing shas.
|
| 898 |
+
null_entries_indices = [i for i, e in enumerate(entries) if e.binsha == Object.NULL_BIN_SHA]
|
| 899 |
+
if null_entries_indices:
|
| 900 |
+
|
| 901 |
+
@git_working_dir
|
| 902 |
+
def handle_null_entries(self: "IndexFile") -> None:
|
| 903 |
+
for ei in null_entries_indices:
|
| 904 |
+
null_entry = entries[ei]
|
| 905 |
+
new_entry = self._store_path(null_entry.path, fprogress)
|
| 906 |
+
|
| 907 |
+
# Update null entry.
|
| 908 |
+
entries[ei] = BaseIndexEntry(
|
| 909 |
+
(
|
| 910 |
+
null_entry.mode,
|
| 911 |
+
new_entry.binsha,
|
| 912 |
+
null_entry.stage,
|
| 913 |
+
null_entry.path,
|
| 914 |
+
)
|
| 915 |
+
)
|
| 916 |
+
# END for each entry index
|
| 917 |
+
|
| 918 |
+
# END closure
|
| 919 |
+
|
| 920 |
+
handle_null_entries(self)
|
| 921 |
+
# END null_entry handling
|
| 922 |
+
|
| 923 |
+
# REWRITE PATHS
|
| 924 |
+
# If we have to rewrite the entries, do so now, after we have generated all
|
| 925 |
+
# object sha's.
|
| 926 |
+
if path_rewriter:
|
| 927 |
+
for i, e in enumerate(entries):
|
| 928 |
+
entries[i] = BaseIndexEntry((e.mode, e.binsha, e.stage, path_rewriter(e)))
|
| 929 |
+
# END for each entry
|
| 930 |
+
# END handle path rewriting
|
| 931 |
+
|
| 932 |
+
# Just go through the remaining entries and provide progress info.
|
| 933 |
+
for i, entry in enumerate(entries):
|
| 934 |
+
progress_sent = i in null_entries_indices
|
| 935 |
+
if not progress_sent:
|
| 936 |
+
fprogress(entry.path, False, entry)
|
| 937 |
+
fprogress(entry.path, True, entry)
|
| 938 |
+
# END handle progress
|
| 939 |
+
# END for each entry
|
| 940 |
+
entries_added.extend(entries)
|
| 941 |
+
# END if there are base entries
|
| 942 |
+
|
| 943 |
+
# FINALIZE
|
| 944 |
+
# Add the new entries to this instance.
|
| 945 |
+
for entry in entries_added:
|
| 946 |
+
self.entries[(entry.path, 0)] = IndexEntry.from_base(entry)
|
| 947 |
+
|
| 948 |
+
if write:
|
| 949 |
+
self.write(ignore_extension_data=not write_extension_data)
|
| 950 |
+
# END handle write
|
| 951 |
+
|
| 952 |
+
return entries_added
|
| 953 |
+
|
| 954 |
+
def _items_to_rela_paths(
|
| 955 |
+
self,
|
| 956 |
+
items: Union[PathLike, Sequence[Union[PathLike, BaseIndexEntry, Blob, Submodule]]],
|
| 957 |
+
) -> List[PathLike]:
|
| 958 |
+
"""Returns a list of repo-relative paths from the given items which
|
| 959 |
+
may be absolute or relative paths, entries or blobs."""
|
| 960 |
+
paths = []
|
| 961 |
+
# If string, put in list.
|
| 962 |
+
if isinstance(items, (str, os.PathLike)):
|
| 963 |
+
items = [items]
|
| 964 |
+
|
| 965 |
+
for item in items:
|
| 966 |
+
if isinstance(item, (BaseIndexEntry, (Blob, Submodule))):
|
| 967 |
+
paths.append(self._to_relative_path(item.path))
|
| 968 |
+
elif isinstance(item, (str, os.PathLike)):
|
| 969 |
+
paths.append(self._to_relative_path(item))
|
| 970 |
+
else:
|
| 971 |
+
raise TypeError("Invalid item type: %r" % item)
|
| 972 |
+
# END for each item
|
| 973 |
+
return paths
|
| 974 |
+
|
| 975 |
+
@post_clear_cache
|
| 976 |
+
@default_index
|
| 977 |
+
def remove(
|
| 978 |
+
self,
|
| 979 |
+
items: Union[PathLike, Sequence[Union[PathLike, Blob, BaseIndexEntry, "Submodule"]]],
|
| 980 |
+
working_tree: bool = False,
|
| 981 |
+
**kwargs: Any,
|
| 982 |
+
) -> List[str]:
|
| 983 |
+
R"""Remove the given items from the index and optionally from the working tree
|
| 984 |
+
as well.
|
| 985 |
+
|
| 986 |
+
:param items:
|
| 987 |
+
Multiple types of items are supported which may be be freely mixed.
|
| 988 |
+
|
| 989 |
+
- path string
|
| 990 |
+
|
| 991 |
+
Remove the given path at all stages. If it is a directory, you must
|
| 992 |
+
specify the ``r=True`` keyword argument to remove all file entries below
|
| 993 |
+
it. If absolute paths are given, they will be converted to a path
|
| 994 |
+
relative to the git repository directory containing the working tree
|
| 995 |
+
|
| 996 |
+
The path string may include globs, such as ``*.c``.
|
| 997 |
+
|
| 998 |
+
- :class:~`git.objects.blob.Blob` object
|
| 999 |
+
|
| 1000 |
+
Only the path portion is used in this case.
|
| 1001 |
+
|
| 1002 |
+
- :class:`~git.index.typ.BaseIndexEntry` or compatible type
|
| 1003 |
+
|
| 1004 |
+
The only relevant information here is the path. The stage is ignored.
|
| 1005 |
+
|
| 1006 |
+
:param working_tree:
|
| 1007 |
+
If ``True``, the entry will also be removed from the working tree,
|
| 1008 |
+
physically removing the respective file. This may fail if there are
|
| 1009 |
+
uncommitted changes in it.
|
| 1010 |
+
|
| 1011 |
+
:param kwargs:
|
| 1012 |
+
Additional keyword arguments to be passed to :manpage:`git-rm(1)`, such as
|
| 1013 |
+
``r`` to allow recursive removal.
|
| 1014 |
+
|
| 1015 |
+
:return:
|
| 1016 |
+
List(path_string, ...) list of repository relative paths that have been
|
| 1017 |
+
removed effectively.
|
| 1018 |
+
|
| 1019 |
+
This is interesting to know in case you have provided a directory or globs.
|
| 1020 |
+
Paths are relative to the repository.
|
| 1021 |
+
"""
|
| 1022 |
+
args = []
|
| 1023 |
+
if not working_tree:
|
| 1024 |
+
args.append("--cached")
|
| 1025 |
+
args.append("--")
|
| 1026 |
+
|
| 1027 |
+
# Preprocess paths.
|
| 1028 |
+
paths = self._items_to_rela_paths(items)
|
| 1029 |
+
removed_paths = self.repo.git.rm(args, paths, **kwargs).splitlines()
|
| 1030 |
+
|
| 1031 |
+
# Process output to gain proper paths.
|
| 1032 |
+
# rm 'path'
|
| 1033 |
+
return [p[4:-1] for p in removed_paths]
|
| 1034 |
+
|
| 1035 |
+
@post_clear_cache
|
| 1036 |
+
@default_index
|
| 1037 |
+
def move(
|
| 1038 |
+
self,
|
| 1039 |
+
items: Union[PathLike, Sequence[Union[PathLike, Blob, BaseIndexEntry, "Submodule"]]],
|
| 1040 |
+
skip_errors: bool = False,
|
| 1041 |
+
**kwargs: Any,
|
| 1042 |
+
) -> List[Tuple[str, str]]:
|
| 1043 |
+
"""Rename/move the items, whereas the last item is considered the destination of
|
| 1044 |
+
the move operation.
|
| 1045 |
+
|
| 1046 |
+
If the destination is a file, the first item (of two) must be a file as well.
|
| 1047 |
+
|
| 1048 |
+
If the destination is a directory, it may be preceded by one or more directories
|
| 1049 |
+
or files.
|
| 1050 |
+
|
| 1051 |
+
The working tree will be affected in non-bare repositories.
|
| 1052 |
+
|
| 1053 |
+
:param items:
|
| 1054 |
+
Multiple types of items are supported, please see the :meth:`remove` method
|
| 1055 |
+
for reference.
|
| 1056 |
+
|
| 1057 |
+
:param skip_errors:
|
| 1058 |
+
If ``True``, errors such as ones resulting from missing source files will be
|
| 1059 |
+
skipped.
|
| 1060 |
+
|
| 1061 |
+
:param kwargs:
|
| 1062 |
+
Additional arguments you would like to pass to :manpage:`git-mv(1)`, such as
|
| 1063 |
+
``dry_run`` or ``force``.
|
| 1064 |
+
|
| 1065 |
+
:return:
|
| 1066 |
+
List(tuple(source_path_string, destination_path_string), ...)
|
| 1067 |
+
|
| 1068 |
+
A list of pairs, containing the source file moved as well as its actual
|
| 1069 |
+
destination. Relative to the repository root.
|
| 1070 |
+
|
| 1071 |
+
:raise ValueError:
|
| 1072 |
+
If only one item was given.
|
| 1073 |
+
|
| 1074 |
+
:raise git.exc.GitCommandError:
|
| 1075 |
+
If git could not handle your request.
|
| 1076 |
+
"""
|
| 1077 |
+
args = []
|
| 1078 |
+
if skip_errors:
|
| 1079 |
+
args.append("-k")
|
| 1080 |
+
|
| 1081 |
+
paths = self._items_to_rela_paths(items)
|
| 1082 |
+
if len(paths) < 2:
|
| 1083 |
+
raise ValueError("Please provide at least one source and one destination of the move operation")
|
| 1084 |
+
|
| 1085 |
+
was_dry_run = kwargs.pop("dry_run", kwargs.pop("n", None))
|
| 1086 |
+
kwargs["dry_run"] = True
|
| 1087 |
+
|
| 1088 |
+
# First execute rename in dry run so the command tells us what it actually does
|
| 1089 |
+
# (for later output).
|
| 1090 |
+
out = []
|
| 1091 |
+
mvlines = self.repo.git.mv(args, paths, **kwargs).splitlines()
|
| 1092 |
+
|
| 1093 |
+
# Parse result - first 0:n/2 lines are 'checking ', the remaining ones are the
|
| 1094 |
+
# 'renaming' ones which we parse.
|
| 1095 |
+
for ln in range(int(len(mvlines) / 2), len(mvlines)):
|
| 1096 |
+
tokens = mvlines[ln].split(" to ")
|
| 1097 |
+
assert len(tokens) == 2, "Too many tokens in %s" % mvlines[ln]
|
| 1098 |
+
|
| 1099 |
+
# [0] = Renaming x
|
| 1100 |
+
# [1] = y
|
| 1101 |
+
out.append((tokens[0][9:], tokens[1]))
|
| 1102 |
+
# END for each line to parse
|
| 1103 |
+
|
| 1104 |
+
# Either prepare for the real run, or output the dry-run result.
|
| 1105 |
+
if was_dry_run:
|
| 1106 |
+
return out
|
| 1107 |
+
# END handle dry run
|
| 1108 |
+
|
| 1109 |
+
# Now apply the actual operation.
|
| 1110 |
+
kwargs.pop("dry_run")
|
| 1111 |
+
self.repo.git.mv(args, paths, **kwargs)
|
| 1112 |
+
|
| 1113 |
+
return out
|
| 1114 |
+
|
| 1115 |
+
def commit(
|
| 1116 |
+
self,
|
| 1117 |
+
message: str,
|
| 1118 |
+
parent_commits: Union[List[Commit], None] = None,
|
| 1119 |
+
head: bool = True,
|
| 1120 |
+
author: Union[None, Actor] = None,
|
| 1121 |
+
committer: Union[None, Actor] = None,
|
| 1122 |
+
author_date: Union[datetime.datetime, str, None] = None,
|
| 1123 |
+
commit_date: Union[datetime.datetime, str, None] = None,
|
| 1124 |
+
skip_hooks: bool = False,
|
| 1125 |
+
) -> Commit:
|
| 1126 |
+
"""Commit the current default index file, creating a
|
| 1127 |
+
:class:`~git.objects.commit.Commit` object.
|
| 1128 |
+
|
| 1129 |
+
For more information on the arguments, see
|
| 1130 |
+
:meth:`Commit.create_from_tree <git.objects.commit.Commit.create_from_tree>`.
|
| 1131 |
+
|
| 1132 |
+
:note:
|
| 1133 |
+
If you have manually altered the :attr:`entries` member of this instance,
|
| 1134 |
+
don't forget to :meth:`write` your changes to disk beforehand.
|
| 1135 |
+
|
| 1136 |
+
:note:
|
| 1137 |
+
Passing ``skip_hooks=True`` is the equivalent of using ``-n`` or
|
| 1138 |
+
``--no-verify`` on the command line.
|
| 1139 |
+
|
| 1140 |
+
:return:
|
| 1141 |
+
:class:`~git.objects.commit.Commit` object representing the new commit
|
| 1142 |
+
"""
|
| 1143 |
+
if not skip_hooks:
|
| 1144 |
+
run_commit_hook("pre-commit", self)
|
| 1145 |
+
|
| 1146 |
+
self._write_commit_editmsg(message)
|
| 1147 |
+
run_commit_hook("commit-msg", self, self._commit_editmsg_filepath())
|
| 1148 |
+
message = self._read_commit_editmsg()
|
| 1149 |
+
self._remove_commit_editmsg()
|
| 1150 |
+
tree = self.write_tree()
|
| 1151 |
+
rval = Commit.create_from_tree(
|
| 1152 |
+
self.repo,
|
| 1153 |
+
tree,
|
| 1154 |
+
message,
|
| 1155 |
+
parent_commits,
|
| 1156 |
+
head,
|
| 1157 |
+
author=author,
|
| 1158 |
+
committer=committer,
|
| 1159 |
+
author_date=author_date,
|
| 1160 |
+
commit_date=commit_date,
|
| 1161 |
+
)
|
| 1162 |
+
if not skip_hooks:
|
| 1163 |
+
run_commit_hook("post-commit", self)
|
| 1164 |
+
return rval
|
| 1165 |
+
|
| 1166 |
+
def _write_commit_editmsg(self, message: str) -> None:
|
| 1167 |
+
with open(self._commit_editmsg_filepath(), "wb") as commit_editmsg_file:
|
| 1168 |
+
commit_editmsg_file.write(message.encode(defenc))
|
| 1169 |
+
|
| 1170 |
+
def _remove_commit_editmsg(self) -> None:
|
| 1171 |
+
os.remove(self._commit_editmsg_filepath())
|
| 1172 |
+
|
| 1173 |
+
def _read_commit_editmsg(self) -> str:
|
| 1174 |
+
with open(self._commit_editmsg_filepath(), "rb") as commit_editmsg_file:
|
| 1175 |
+
return commit_editmsg_file.read().decode(defenc)
|
| 1176 |
+
|
| 1177 |
+
def _commit_editmsg_filepath(self) -> str:
|
| 1178 |
+
return osp.join(self.repo.common_dir, "COMMIT_EDITMSG")
|
| 1179 |
+
|
| 1180 |
+
def _flush_stdin_and_wait(cls, proc: "Popen[bytes]", ignore_stdout: bool = False) -> bytes:
|
| 1181 |
+
stdin_IO = proc.stdin
|
| 1182 |
+
if stdin_IO:
|
| 1183 |
+
stdin_IO.flush()
|
| 1184 |
+
stdin_IO.close()
|
| 1185 |
+
|
| 1186 |
+
stdout = b""
|
| 1187 |
+
if not ignore_stdout and proc.stdout:
|
| 1188 |
+
stdout = proc.stdout.read()
|
| 1189 |
+
|
| 1190 |
+
if proc.stdout:
|
| 1191 |
+
proc.stdout.close()
|
| 1192 |
+
proc.wait()
|
| 1193 |
+
return stdout
|
| 1194 |
+
|
| 1195 |
+
@default_index
|
| 1196 |
+
def checkout(
|
| 1197 |
+
self,
|
| 1198 |
+
paths: Union[None, Iterable[PathLike]] = None,
|
| 1199 |
+
force: bool = False,
|
| 1200 |
+
fprogress: Callable = lambda *args: None,
|
| 1201 |
+
**kwargs: Any,
|
| 1202 |
+
) -> Union[None, Iterator[PathLike], Sequence[PathLike]]:
|
| 1203 |
+
"""Check out the given paths or all files from the version known to the index
|
| 1204 |
+
into the working tree.
|
| 1205 |
+
|
| 1206 |
+
:note:
|
| 1207 |
+
Be sure you have written pending changes using the :meth:`write` method in
|
| 1208 |
+
case you have altered the entries dictionary directly.
|
| 1209 |
+
|
| 1210 |
+
:param paths:
|
| 1211 |
+
If ``None``, all paths in the index will be checked out.
|
| 1212 |
+
Otherwise an iterable of relative or absolute paths or a single path
|
| 1213 |
+
pointing to files or directories in the index is expected.
|
| 1214 |
+
|
| 1215 |
+
:param force:
|
| 1216 |
+
If ``True``, existing files will be overwritten even if they contain local
|
| 1217 |
+
modifications.
|
| 1218 |
+
If ``False``, these will trigger a :exc:`~git.exc.CheckoutError`.
|
| 1219 |
+
|
| 1220 |
+
:param fprogress:
|
| 1221 |
+
See :meth:`IndexFile.add` for signature and explanation.
|
| 1222 |
+
|
| 1223 |
+
The provided progress information will contain ``None`` as path and item if
|
| 1224 |
+
no explicit paths are given. Otherwise progress information will be send
|
| 1225 |
+
prior and after a file has been checked out.
|
| 1226 |
+
|
| 1227 |
+
:param kwargs:
|
| 1228 |
+
Additional arguments to be passed to :manpage:`git-checkout-index(1)`.
|
| 1229 |
+
|
| 1230 |
+
:return:
|
| 1231 |
+
Iterable yielding paths to files which have been checked out and are
|
| 1232 |
+
guaranteed to match the version stored in the index.
|
| 1233 |
+
|
| 1234 |
+
:raise git.exc.CheckoutError:
|
| 1235 |
+
* If at least one file failed to be checked out. This is a summary, hence it
|
| 1236 |
+
will checkout as many files as it can anyway.
|
| 1237 |
+
* If one of files or directories do not exist in the index (as opposed to
|
| 1238 |
+
the original git command, which ignores them).
|
| 1239 |
+
|
| 1240 |
+
:raise git.exc.GitCommandError:
|
| 1241 |
+
If error lines could not be parsed - this truly is an exceptional state.
|
| 1242 |
+
|
| 1243 |
+
:note:
|
| 1244 |
+
The checkout is limited to checking out the files in the index. Files which
|
| 1245 |
+
are not in the index anymore and exist in the working tree will not be
|
| 1246 |
+
deleted. This behaviour is fundamentally different to ``head.checkout``,
|
| 1247 |
+
i.e. if you want :manpage:`git-checkout(1)`-like behaviour, use
|
| 1248 |
+
``head.checkout`` instead of ``index.checkout``.
|
| 1249 |
+
"""
|
| 1250 |
+
args = ["--index"]
|
| 1251 |
+
if force:
|
| 1252 |
+
args.append("--force")
|
| 1253 |
+
|
| 1254 |
+
failed_files = []
|
| 1255 |
+
failed_reasons = []
|
| 1256 |
+
unknown_lines = []
|
| 1257 |
+
|
| 1258 |
+
def handle_stderr(proc: "Popen[bytes]", iter_checked_out_files: Iterable[PathLike]) -> None:
|
| 1259 |
+
stderr_IO = proc.stderr
|
| 1260 |
+
if not stderr_IO:
|
| 1261 |
+
return # Return early if stderr empty.
|
| 1262 |
+
|
| 1263 |
+
stderr_bytes = stderr_IO.read()
|
| 1264 |
+
# line contents:
|
| 1265 |
+
stderr = stderr_bytes.decode(defenc)
|
| 1266 |
+
# git-checkout-index: this already exists
|
| 1267 |
+
endings = (
|
| 1268 |
+
" already exists",
|
| 1269 |
+
" is not in the cache",
|
| 1270 |
+
" does not exist at stage",
|
| 1271 |
+
" is unmerged",
|
| 1272 |
+
)
|
| 1273 |
+
for line in stderr.splitlines():
|
| 1274 |
+
if not line.startswith("git checkout-index: ") and not line.startswith("git-checkout-index: "):
|
| 1275 |
+
is_a_dir = " is a directory"
|
| 1276 |
+
unlink_issue = "unable to unlink old '"
|
| 1277 |
+
already_exists_issue = " already exists, no checkout" # created by entry.c:checkout_entry(...)
|
| 1278 |
+
if line.endswith(is_a_dir):
|
| 1279 |
+
failed_files.append(line[: -len(is_a_dir)])
|
| 1280 |
+
failed_reasons.append(is_a_dir)
|
| 1281 |
+
elif line.startswith(unlink_issue):
|
| 1282 |
+
failed_files.append(line[len(unlink_issue) : line.rfind("'")])
|
| 1283 |
+
failed_reasons.append(unlink_issue)
|
| 1284 |
+
elif line.endswith(already_exists_issue):
|
| 1285 |
+
failed_files.append(line[: -len(already_exists_issue)])
|
| 1286 |
+
failed_reasons.append(already_exists_issue)
|
| 1287 |
+
else:
|
| 1288 |
+
unknown_lines.append(line)
|
| 1289 |
+
continue
|
| 1290 |
+
# END special lines parsing
|
| 1291 |
+
|
| 1292 |
+
for e in endings:
|
| 1293 |
+
if line.endswith(e):
|
| 1294 |
+
failed_files.append(line[20 : -len(e)])
|
| 1295 |
+
failed_reasons.append(e)
|
| 1296 |
+
break
|
| 1297 |
+
# END if ending matches
|
| 1298 |
+
# END for each possible ending
|
| 1299 |
+
# END for each line
|
| 1300 |
+
if unknown_lines:
|
| 1301 |
+
raise GitCommandError(("git-checkout-index",), 128, stderr)
|
| 1302 |
+
if failed_files:
|
| 1303 |
+
valid_files = list(set(iter_checked_out_files) - set(failed_files))
|
| 1304 |
+
raise CheckoutError(
|
| 1305 |
+
"Some files could not be checked out from the index due to local modifications",
|
| 1306 |
+
failed_files,
|
| 1307 |
+
valid_files,
|
| 1308 |
+
failed_reasons,
|
| 1309 |
+
)
|
| 1310 |
+
|
| 1311 |
+
# END stderr handler
|
| 1312 |
+
|
| 1313 |
+
if paths is None:
|
| 1314 |
+
args.append("--all")
|
| 1315 |
+
kwargs["as_process"] = 1
|
| 1316 |
+
fprogress(None, False, None)
|
| 1317 |
+
proc = self.repo.git.checkout_index(*args, **kwargs)
|
| 1318 |
+
proc.wait()
|
| 1319 |
+
fprogress(None, True, None)
|
| 1320 |
+
rval_iter = (e.path for e in self.entries.values())
|
| 1321 |
+
handle_stderr(proc, rval_iter)
|
| 1322 |
+
return rval_iter
|
| 1323 |
+
else:
|
| 1324 |
+
if isinstance(paths, str):
|
| 1325 |
+
paths = [paths]
|
| 1326 |
+
|
| 1327 |
+
# Make sure we have our entries loaded before we start checkout_index, which
|
| 1328 |
+
# will hold a lock on it. We try to get the lock as well during our entries
|
| 1329 |
+
# initialization.
|
| 1330 |
+
self.entries # noqa: B018
|
| 1331 |
+
|
| 1332 |
+
args.append("--stdin")
|
| 1333 |
+
kwargs["as_process"] = True
|
| 1334 |
+
kwargs["istream"] = subprocess.PIPE
|
| 1335 |
+
proc = self.repo.git.checkout_index(args, **kwargs)
|
| 1336 |
+
# FIXME: Reading from GIL!
|
| 1337 |
+
make_exc = lambda: GitCommandError(("git-checkout-index",) + tuple(args), 128, proc.stderr.read())
|
| 1338 |
+
checked_out_files: List[PathLike] = []
|
| 1339 |
+
|
| 1340 |
+
for path in paths:
|
| 1341 |
+
co_path = to_native_path_linux(self._to_relative_path(path))
|
| 1342 |
+
# If the item is not in the index, it could be a directory.
|
| 1343 |
+
path_is_directory = False
|
| 1344 |
+
|
| 1345 |
+
try:
|
| 1346 |
+
self.entries[(co_path, 0)]
|
| 1347 |
+
except KeyError:
|
| 1348 |
+
folder = str(co_path)
|
| 1349 |
+
if not folder.endswith("/"):
|
| 1350 |
+
folder += "/"
|
| 1351 |
+
for entry in self.entries.values():
|
| 1352 |
+
if str(entry.path).startswith(folder):
|
| 1353 |
+
p = entry.path
|
| 1354 |
+
self._write_path_to_stdin(proc, p, p, make_exc, fprogress, read_from_stdout=False)
|
| 1355 |
+
checked_out_files.append(p)
|
| 1356 |
+
path_is_directory = True
|
| 1357 |
+
# END if entry is in directory
|
| 1358 |
+
# END for each entry
|
| 1359 |
+
# END path exception handlnig
|
| 1360 |
+
|
| 1361 |
+
if not path_is_directory:
|
| 1362 |
+
self._write_path_to_stdin(proc, co_path, path, make_exc, fprogress, read_from_stdout=False)
|
| 1363 |
+
checked_out_files.append(co_path)
|
| 1364 |
+
# END path is a file
|
| 1365 |
+
# END for each path
|
| 1366 |
+
try:
|
| 1367 |
+
self._flush_stdin_and_wait(proc, ignore_stdout=True)
|
| 1368 |
+
except GitCommandError:
|
| 1369 |
+
# Without parsing stdout we don't know what failed.
|
| 1370 |
+
raise CheckoutError( # noqa: B904
|
| 1371 |
+
"Some files could not be checked out from the index, probably because they didn't exist.",
|
| 1372 |
+
failed_files,
|
| 1373 |
+
[],
|
| 1374 |
+
failed_reasons,
|
| 1375 |
+
)
|
| 1376 |
+
|
| 1377 |
+
handle_stderr(proc, checked_out_files)
|
| 1378 |
+
return checked_out_files
|
| 1379 |
+
# END paths handling
|
| 1380 |
+
|
| 1381 |
+
@default_index
|
| 1382 |
+
def reset(
|
| 1383 |
+
self,
|
| 1384 |
+
commit: Union[Commit, "Reference", str] = "HEAD",
|
| 1385 |
+
working_tree: bool = False,
|
| 1386 |
+
paths: Union[None, Iterable[PathLike]] = None,
|
| 1387 |
+
head: bool = False,
|
| 1388 |
+
**kwargs: Any,
|
| 1389 |
+
) -> "IndexFile":
|
| 1390 |
+
"""Reset the index to reflect the tree at the given commit. This will not adjust
|
| 1391 |
+
our HEAD reference by default, as opposed to
|
| 1392 |
+
:meth:`HEAD.reset <git.refs.head.HEAD.reset>`.
|
| 1393 |
+
|
| 1394 |
+
:param commit:
|
| 1395 |
+
Revision, :class:`~git.refs.reference.Reference` or
|
| 1396 |
+
:class:`~git.objects.commit.Commit` specifying the commit we should
|
| 1397 |
+
represent.
|
| 1398 |
+
|
| 1399 |
+
If you want to specify a tree only, use :meth:`IndexFile.from_tree` and
|
| 1400 |
+
overwrite the default index.
|
| 1401 |
+
|
| 1402 |
+
:param working_tree:
|
| 1403 |
+
If ``True``, the files in the working tree will reflect the changed index.
|
| 1404 |
+
If ``False``, the working tree will not be touched.
|
| 1405 |
+
Please note that changes to the working copy will be discarded without
|
| 1406 |
+
warning!
|
| 1407 |
+
|
| 1408 |
+
:param head:
|
| 1409 |
+
If ``True``, the head will be set to the given commit. This is ``False`` by
|
| 1410 |
+
default, but if ``True``, this method behaves like
|
| 1411 |
+
:meth:`HEAD.reset <git.refs.head.HEAD.reset>`.
|
| 1412 |
+
|
| 1413 |
+
:param paths:
|
| 1414 |
+
If given as an iterable of absolute or repository-relative paths, only these
|
| 1415 |
+
will be reset to their state at the given commit-ish.
|
| 1416 |
+
The paths need to exist at the commit, otherwise an exception will be
|
| 1417 |
+
raised.
|
| 1418 |
+
|
| 1419 |
+
:param kwargs:
|
| 1420 |
+
Additional keyword arguments passed to :manpage:`git-reset(1)`.
|
| 1421 |
+
|
| 1422 |
+
:note:
|
| 1423 |
+
:meth:`IndexFile.reset`, as opposed to
|
| 1424 |
+
:meth:`HEAD.reset <git.refs.head.HEAD.reset>`, will not delete any files in
|
| 1425 |
+
order to maintain a consistent working tree. Instead, it will just check out
|
| 1426 |
+
the files according to their state in the index.
|
| 1427 |
+
If you want :manpage:`git-reset(1)`-like behaviour, use
|
| 1428 |
+
:meth:`HEAD.reset <git.refs.head.HEAD.reset>` instead.
|
| 1429 |
+
|
| 1430 |
+
:return:
|
| 1431 |
+
self
|
| 1432 |
+
"""
|
| 1433 |
+
# What we actually want to do is to merge the tree into our existing index,
|
| 1434 |
+
# which is what git-read-tree does.
|
| 1435 |
+
new_inst = type(self).from_tree(self.repo, commit)
|
| 1436 |
+
if not paths:
|
| 1437 |
+
self.entries = new_inst.entries
|
| 1438 |
+
else:
|
| 1439 |
+
nie = new_inst.entries
|
| 1440 |
+
for path in paths:
|
| 1441 |
+
path = self._to_relative_path(path)
|
| 1442 |
+
try:
|
| 1443 |
+
key = entry_key(path, 0)
|
| 1444 |
+
self.entries[key] = nie[key]
|
| 1445 |
+
except KeyError:
|
| 1446 |
+
# If key is not in theirs, it mustn't be in ours.
|
| 1447 |
+
try:
|
| 1448 |
+
del self.entries[key]
|
| 1449 |
+
except KeyError:
|
| 1450 |
+
pass
|
| 1451 |
+
# END handle deletion keyerror
|
| 1452 |
+
# END handle keyerror
|
| 1453 |
+
# END for each path
|
| 1454 |
+
# END handle paths
|
| 1455 |
+
self.write()
|
| 1456 |
+
|
| 1457 |
+
if working_tree:
|
| 1458 |
+
self.checkout(paths=paths, force=True)
|
| 1459 |
+
# END handle working tree
|
| 1460 |
+
|
| 1461 |
+
if head:
|
| 1462 |
+
self.repo.head.set_commit(self.repo.commit(commit), logmsg="%s: Updating HEAD" % commit)
|
| 1463 |
+
# END handle head change
|
| 1464 |
+
|
| 1465 |
+
return self
|
| 1466 |
+
|
| 1467 |
+
# FIXME: This is documented to accept the same parameters as Diffable.diff, but this
|
| 1468 |
+
# does not handle NULL_TREE for `other`. (The suppressed mypy error is about this.)
|
| 1469 |
+
def diff(
|
| 1470 |
+
self,
|
| 1471 |
+
other: Union[ # type: ignore[override]
|
| 1472 |
+
Literal[git_diff.DiffConstants.INDEX],
|
| 1473 |
+
"Tree",
|
| 1474 |
+
"Commit",
|
| 1475 |
+
str,
|
| 1476 |
+
None,
|
| 1477 |
+
] = git_diff.INDEX,
|
| 1478 |
+
paths: Union[PathLike, List[PathLike], Tuple[PathLike, ...], None] = None,
|
| 1479 |
+
create_patch: bool = False,
|
| 1480 |
+
**kwargs: Any,
|
| 1481 |
+
) -> git_diff.DiffIndex[git_diff.Diff]:
|
| 1482 |
+
"""Diff this index against the working copy or a :class:`~git.objects.tree.Tree`
|
| 1483 |
+
or :class:`~git.objects.commit.Commit` object.
|
| 1484 |
+
|
| 1485 |
+
For documentation of the parameters and return values, see
|
| 1486 |
+
:meth:`Diffable.diff <git.diff.Diffable.diff>`.
|
| 1487 |
+
|
| 1488 |
+
:note:
|
| 1489 |
+
Will only work with indices that represent the default git index as they
|
| 1490 |
+
have not been initialized with a stream.
|
| 1491 |
+
"""
|
| 1492 |
+
# Only run if we are the default repository index.
|
| 1493 |
+
if self._file_path != self._index_path():
|
| 1494 |
+
raise AssertionError("Cannot call %r on indices that do not represent the default git index" % self.diff())
|
| 1495 |
+
# Index against index is always empty.
|
| 1496 |
+
if other is self.INDEX:
|
| 1497 |
+
return git_diff.DiffIndex()
|
| 1498 |
+
|
| 1499 |
+
# Index against anything but None is a reverse diff with the respective item.
|
| 1500 |
+
# Handle existing -R flags properly.
|
| 1501 |
+
# Transform strings to the object so that we can call diff on it.
|
| 1502 |
+
if isinstance(other, str):
|
| 1503 |
+
other = self.repo.rev_parse(other)
|
| 1504 |
+
# END object conversion
|
| 1505 |
+
|
| 1506 |
+
if isinstance(other, Object): # For Tree or Commit.
|
| 1507 |
+
# Invert the existing R flag.
|
| 1508 |
+
cur_val = kwargs.get("R", False)
|
| 1509 |
+
kwargs["R"] = not cur_val
|
| 1510 |
+
return other.diff(self.INDEX, paths, create_patch, **kwargs)
|
| 1511 |
+
# END diff against other item handling
|
| 1512 |
+
|
| 1513 |
+
# If other is not None here, something is wrong.
|
| 1514 |
+
if other is not None:
|
| 1515 |
+
raise ValueError("other must be None, Diffable.INDEX, a Tree or Commit, was %r" % other)
|
| 1516 |
+
|
| 1517 |
+
# Diff against working copy - can be handled by superclass natively.
|
| 1518 |
+
return super().diff(other, paths, create_patch, **kwargs)
|
venv/lib/python3.10/site-packages/git/index/fun.py
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This module is part of GitPython and is released under the
|
| 2 |
+
# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
|
| 3 |
+
|
| 4 |
+
"""Standalone functions to accompany the index implementation and make it more
|
| 5 |
+
versatile."""
|
| 6 |
+
|
| 7 |
+
__all__ = [
|
| 8 |
+
"write_cache",
|
| 9 |
+
"read_cache",
|
| 10 |
+
"write_tree_from_cache",
|
| 11 |
+
"entry_key",
|
| 12 |
+
"stat_mode_to_index_mode",
|
| 13 |
+
"S_IFGITLINK",
|
| 14 |
+
"run_commit_hook",
|
| 15 |
+
"hook_path",
|
| 16 |
+
]
|
| 17 |
+
|
| 18 |
+
from io import BytesIO
|
| 19 |
+
import os
|
| 20 |
+
import os.path as osp
|
| 21 |
+
from pathlib import Path
|
| 22 |
+
from stat import S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_ISDIR, S_ISLNK, S_IXUSR
|
| 23 |
+
import subprocess
|
| 24 |
+
import sys
|
| 25 |
+
|
| 26 |
+
from gitdb.base import IStream
|
| 27 |
+
from gitdb.typ import str_tree_type
|
| 28 |
+
|
| 29 |
+
from git.cmd import handle_process_output, safer_popen
|
| 30 |
+
from git.compat import defenc, force_bytes, force_text, safe_decode
|
| 31 |
+
from git.exc import HookExecutionError, UnmergedEntriesError
|
| 32 |
+
from git.objects.fun import (
|
| 33 |
+
traverse_tree_recursive,
|
| 34 |
+
traverse_trees_recursive,
|
| 35 |
+
tree_to_stream,
|
| 36 |
+
)
|
| 37 |
+
from git.util import IndexFileSHA1Writer, finalize_process
|
| 38 |
+
|
| 39 |
+
from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT
|
| 40 |
+
from .util import pack, unpack
|
| 41 |
+
|
| 42 |
+
# typing -----------------------------------------------------------------------------
|
| 43 |
+
|
| 44 |
+
from typing import Dict, IO, List, Sequence, TYPE_CHECKING, Tuple, Type, Union, cast
|
| 45 |
+
|
| 46 |
+
from git.types import PathLike
|
| 47 |
+
|
| 48 |
+
if TYPE_CHECKING:
|
| 49 |
+
from git.db import GitCmdObjectDB
|
| 50 |
+
from git.objects.tree import TreeCacheTup
|
| 51 |
+
|
| 52 |
+
from .base import IndexFile
|
| 53 |
+
|
| 54 |
+
# ------------------------------------------------------------------------------------
|
| 55 |
+
|
| 56 |
+
S_IFGITLINK = S_IFLNK | S_IFDIR
|
| 57 |
+
"""Flags for a submodule."""
|
| 58 |
+
|
| 59 |
+
CE_NAMEMASK_INV = ~CE_NAMEMASK
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def hook_path(name: str, git_dir: PathLike) -> str:
|
| 63 |
+
""":return: path to the given named hook in the given git repository directory"""
|
| 64 |
+
return osp.join(git_dir, "hooks", name)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def _has_file_extension(path: str) -> str:
|
| 68 |
+
return osp.splitext(path)[1]
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None:
|
| 72 |
+
"""Run the commit hook of the given name. Silently ignore hooks that do not exist.
|
| 73 |
+
|
| 74 |
+
:param name:
|
| 75 |
+
Name of hook, like ``pre-commit``.
|
| 76 |
+
|
| 77 |
+
:param index:
|
| 78 |
+
:class:`~git.index.base.IndexFile` instance.
|
| 79 |
+
|
| 80 |
+
:param args:
|
| 81 |
+
Arguments passed to hook file.
|
| 82 |
+
|
| 83 |
+
:raise git.exc.HookExecutionError:
|
| 84 |
+
"""
|
| 85 |
+
hp = hook_path(name, index.repo.git_dir)
|
| 86 |
+
if not os.access(hp, os.X_OK):
|
| 87 |
+
return
|
| 88 |
+
|
| 89 |
+
env = os.environ.copy()
|
| 90 |
+
env["GIT_INDEX_FILE"] = safe_decode(str(index.path))
|
| 91 |
+
env["GIT_EDITOR"] = ":"
|
| 92 |
+
cmd = [hp]
|
| 93 |
+
try:
|
| 94 |
+
if sys.platform == "win32" and not _has_file_extension(hp):
|
| 95 |
+
# Windows only uses extensions to determine how to open files
|
| 96 |
+
# (doesn't understand shebangs). Try using bash to run the hook.
|
| 97 |
+
relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix()
|
| 98 |
+
cmd = ["bash.exe", relative_hp]
|
| 99 |
+
|
| 100 |
+
process = safer_popen(
|
| 101 |
+
cmd + list(args),
|
| 102 |
+
env=env,
|
| 103 |
+
stdout=subprocess.PIPE,
|
| 104 |
+
stderr=subprocess.PIPE,
|
| 105 |
+
cwd=index.repo.working_dir,
|
| 106 |
+
)
|
| 107 |
+
except Exception as ex:
|
| 108 |
+
raise HookExecutionError(hp, ex) from ex
|
| 109 |
+
else:
|
| 110 |
+
stdout_list: List[str] = []
|
| 111 |
+
stderr_list: List[str] = []
|
| 112 |
+
handle_process_output(process, stdout_list.append, stderr_list.append, finalize_process)
|
| 113 |
+
stdout = "".join(stdout_list)
|
| 114 |
+
stderr = "".join(stderr_list)
|
| 115 |
+
if process.returncode != 0:
|
| 116 |
+
stdout = force_text(stdout, defenc)
|
| 117 |
+
stderr = force_text(stderr, defenc)
|
| 118 |
+
raise HookExecutionError(hp, process.returncode, stderr, stdout)
|
| 119 |
+
# END handle return code
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def stat_mode_to_index_mode(mode: int) -> int:
|
| 123 |
+
"""Convert the given mode from a stat call to the corresponding index mode and
|
| 124 |
+
return it."""
|
| 125 |
+
if S_ISLNK(mode): # symlinks
|
| 126 |
+
return S_IFLNK
|
| 127 |
+
if S_ISDIR(mode) or S_IFMT(mode) == S_IFGITLINK: # submodules
|
| 128 |
+
return S_IFGITLINK
|
| 129 |
+
return S_IFREG | (mode & S_IXUSR and 0o755 or 0o644) # blobs with or without executable bit
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def write_cache(
|
| 133 |
+
entries: Sequence[Union[BaseIndexEntry, "IndexEntry"]],
|
| 134 |
+
stream: IO[bytes],
|
| 135 |
+
extension_data: Union[None, bytes] = None,
|
| 136 |
+
ShaStreamCls: Type[IndexFileSHA1Writer] = IndexFileSHA1Writer,
|
| 137 |
+
) -> None:
|
| 138 |
+
"""Write the cache represented by entries to a stream.
|
| 139 |
+
|
| 140 |
+
:param entries:
|
| 141 |
+
**Sorted** list of entries.
|
| 142 |
+
|
| 143 |
+
:param stream:
|
| 144 |
+
Stream to wrap into the AdapterStreamCls - it is used for final output.
|
| 145 |
+
|
| 146 |
+
:param ShaStreamCls:
|
| 147 |
+
Type to use when writing to the stream. It produces a sha while writing to it,
|
| 148 |
+
before the data is passed on to the wrapped stream.
|
| 149 |
+
|
| 150 |
+
:param extension_data:
|
| 151 |
+
Any kind of data to write as a trailer, it must begin a 4 byte identifier,
|
| 152 |
+
followed by its size (4 bytes).
|
| 153 |
+
"""
|
| 154 |
+
# Wrap the stream into a compatible writer.
|
| 155 |
+
stream_sha = ShaStreamCls(stream)
|
| 156 |
+
|
| 157 |
+
tell = stream_sha.tell
|
| 158 |
+
write = stream_sha.write
|
| 159 |
+
|
| 160 |
+
# Header
|
| 161 |
+
version = 2
|
| 162 |
+
write(b"DIRC")
|
| 163 |
+
write(pack(">LL", version, len(entries)))
|
| 164 |
+
|
| 165 |
+
# Body
|
| 166 |
+
for entry in entries:
|
| 167 |
+
beginoffset = tell()
|
| 168 |
+
write(entry.ctime_bytes) # ctime
|
| 169 |
+
write(entry.mtime_bytes) # mtime
|
| 170 |
+
path_str = str(entry.path)
|
| 171 |
+
path: bytes = force_bytes(path_str, encoding=defenc)
|
| 172 |
+
plen = len(path) & CE_NAMEMASK # Path length
|
| 173 |
+
assert plen == len(path), "Path %s too long to fit into index" % entry.path
|
| 174 |
+
flags = plen | (entry.flags & CE_NAMEMASK_INV) # Clear possible previous values.
|
| 175 |
+
write(
|
| 176 |
+
pack(
|
| 177 |
+
">LLLLLL20sH",
|
| 178 |
+
entry.dev,
|
| 179 |
+
entry.inode,
|
| 180 |
+
entry.mode,
|
| 181 |
+
entry.uid,
|
| 182 |
+
entry.gid,
|
| 183 |
+
entry.size,
|
| 184 |
+
entry.binsha,
|
| 185 |
+
flags,
|
| 186 |
+
)
|
| 187 |
+
)
|
| 188 |
+
write(path)
|
| 189 |
+
real_size = (tell() - beginoffset + 8) & ~7
|
| 190 |
+
write(b"\0" * ((beginoffset + real_size) - tell()))
|
| 191 |
+
# END for each entry
|
| 192 |
+
|
| 193 |
+
# Write previously cached extensions data.
|
| 194 |
+
if extension_data is not None:
|
| 195 |
+
stream_sha.write(extension_data)
|
| 196 |
+
|
| 197 |
+
# Write the sha over the content.
|
| 198 |
+
stream_sha.write_sha()
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def read_header(stream: IO[bytes]) -> Tuple[int, int]:
|
| 202 |
+
"""Return tuple(version_long, num_entries) from the given stream."""
|
| 203 |
+
type_id = stream.read(4)
|
| 204 |
+
if type_id != b"DIRC":
|
| 205 |
+
raise AssertionError("Invalid index file header: %r" % type_id)
|
| 206 |
+
unpacked = cast(Tuple[int, int], unpack(">LL", stream.read(4 * 2)))
|
| 207 |
+
version, num_entries = unpacked
|
| 208 |
+
|
| 209 |
+
# TODO: Handle version 3: extended data, see read-cache.c.
|
| 210 |
+
assert version in (1, 2)
|
| 211 |
+
return version, num_entries
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def entry_key(*entry: Union[BaseIndexEntry, PathLike, int]) -> Tuple[PathLike, int]:
|
| 215 |
+
"""
|
| 216 |
+
:return:
|
| 217 |
+
Key suitable to be used for the
|
| 218 |
+
:attr:`index.entries <git.index.base.IndexFile.entries>` dictionary.
|
| 219 |
+
|
| 220 |
+
:param entry:
|
| 221 |
+
One instance of type BaseIndexEntry or the path and the stage.
|
| 222 |
+
"""
|
| 223 |
+
|
| 224 |
+
# def is_entry_key_tup(entry_key: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
|
| 225 |
+
# return isinstance(entry_key, tuple) and len(entry_key) == 2
|
| 226 |
+
|
| 227 |
+
if len(entry) == 1:
|
| 228 |
+
entry_first = entry[0]
|
| 229 |
+
assert isinstance(entry_first, BaseIndexEntry)
|
| 230 |
+
return (entry_first.path, entry_first.stage)
|
| 231 |
+
else:
|
| 232 |
+
# assert is_entry_key_tup(entry)
|
| 233 |
+
entry = cast(Tuple[PathLike, int], entry)
|
| 234 |
+
return entry
|
| 235 |
+
# END handle entry
|
| 236 |
+
|
| 237 |
+
|
| 238 |
+
def read_cache(
|
| 239 |
+
stream: IO[bytes],
|
| 240 |
+
) -> Tuple[int, Dict[Tuple[PathLike, int], "IndexEntry"], bytes, bytes]:
|
| 241 |
+
"""Read a cache file from the given stream.
|
| 242 |
+
|
| 243 |
+
:return:
|
| 244 |
+
tuple(version, entries_dict, extension_data, content_sha)
|
| 245 |
+
|
| 246 |
+
* *version* is the integer version number.
|
| 247 |
+
* *entries_dict* is a dictionary which maps IndexEntry instances to a path at a
|
| 248 |
+
stage.
|
| 249 |
+
* *extension_data* is ``""`` or 4 bytes of type + 4 bytes of size + size bytes.
|
| 250 |
+
* *content_sha* is a 20 byte sha on all cache file contents.
|
| 251 |
+
"""
|
| 252 |
+
version, num_entries = read_header(stream)
|
| 253 |
+
count = 0
|
| 254 |
+
entries: Dict[Tuple[PathLike, int], "IndexEntry"] = {}
|
| 255 |
+
|
| 256 |
+
read = stream.read
|
| 257 |
+
tell = stream.tell
|
| 258 |
+
while count < num_entries:
|
| 259 |
+
beginoffset = tell()
|
| 260 |
+
ctime = unpack(">8s", read(8))[0]
|
| 261 |
+
mtime = unpack(">8s", read(8))[0]
|
| 262 |
+
(dev, ino, mode, uid, gid, size, sha, flags) = unpack(">LLLLLL20sH", read(20 + 4 * 6 + 2))
|
| 263 |
+
path_size = flags & CE_NAMEMASK
|
| 264 |
+
path = read(path_size).decode(defenc)
|
| 265 |
+
|
| 266 |
+
real_size = (tell() - beginoffset + 8) & ~7
|
| 267 |
+
read((beginoffset + real_size) - tell())
|
| 268 |
+
entry = IndexEntry((mode, sha, flags, path, ctime, mtime, dev, ino, uid, gid, size))
|
| 269 |
+
# entry_key would be the method to use, but we save the effort.
|
| 270 |
+
entries[(path, entry.stage)] = entry
|
| 271 |
+
count += 1
|
| 272 |
+
# END for each entry
|
| 273 |
+
|
| 274 |
+
# The footer contains extension data and a sha on the content so far.
|
| 275 |
+
# Keep the extension footer,and verify we have a sha in the end.
|
| 276 |
+
# Extension data format is:
|
| 277 |
+
# 4 bytes ID
|
| 278 |
+
# 4 bytes length of chunk
|
| 279 |
+
# Repeated 0 - N times
|
| 280 |
+
extension_data = stream.read(~0)
|
| 281 |
+
assert len(extension_data) > 19, (
|
| 282 |
+
"Index Footer was not at least a sha on content as it was only %i bytes in size" % len(extension_data)
|
| 283 |
+
)
|
| 284 |
+
|
| 285 |
+
content_sha = extension_data[-20:]
|
| 286 |
+
|
| 287 |
+
# Truncate the sha in the end as we will dynamically create it anyway.
|
| 288 |
+
extension_data = extension_data[:-20]
|
| 289 |
+
|
| 290 |
+
return (version, entries, extension_data, content_sha)
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
def write_tree_from_cache(
|
| 294 |
+
entries: List[IndexEntry], odb: "GitCmdObjectDB", sl: slice, si: int = 0
|
| 295 |
+
) -> Tuple[bytes, List["TreeCacheTup"]]:
|
| 296 |
+
R"""Create a tree from the given sorted list of entries and put the respective
|
| 297 |
+
trees into the given object database.
|
| 298 |
+
|
| 299 |
+
:param entries:
|
| 300 |
+
**Sorted** list of :class:`~git.index.typ.IndexEntry`\s.
|
| 301 |
+
|
| 302 |
+
:param odb:
|
| 303 |
+
Object database to store the trees in.
|
| 304 |
+
|
| 305 |
+
:param si:
|
| 306 |
+
Start index at which we should start creating subtrees.
|
| 307 |
+
|
| 308 |
+
:param sl:
|
| 309 |
+
Slice indicating the range we should process on the entries list.
|
| 310 |
+
|
| 311 |
+
:return:
|
| 312 |
+
tuple(binsha, list(tree_entry, ...))
|
| 313 |
+
|
| 314 |
+
A tuple of a sha and a list of tree entries being a tuple of hexsha, mode, name.
|
| 315 |
+
"""
|
| 316 |
+
tree_items: List["TreeCacheTup"] = []
|
| 317 |
+
|
| 318 |
+
ci = sl.start
|
| 319 |
+
end = sl.stop
|
| 320 |
+
while ci < end:
|
| 321 |
+
entry = entries[ci]
|
| 322 |
+
if entry.stage != 0:
|
| 323 |
+
raise UnmergedEntriesError(entry)
|
| 324 |
+
# END abort on unmerged
|
| 325 |
+
ci += 1
|
| 326 |
+
rbound = entry.path.find("/", si)
|
| 327 |
+
if rbound == -1:
|
| 328 |
+
# It's not a tree.
|
| 329 |
+
tree_items.append((entry.binsha, entry.mode, entry.path[si:]))
|
| 330 |
+
else:
|
| 331 |
+
# Find common base range.
|
| 332 |
+
base = entry.path[si:rbound]
|
| 333 |
+
xi = ci
|
| 334 |
+
while xi < end:
|
| 335 |
+
oentry = entries[xi]
|
| 336 |
+
orbound = oentry.path.find("/", si)
|
| 337 |
+
if orbound == -1 or oentry.path[si:orbound] != base:
|
| 338 |
+
break
|
| 339 |
+
# END abort on base mismatch
|
| 340 |
+
xi += 1
|
| 341 |
+
# END find common base
|
| 342 |
+
|
| 343 |
+
# Enter recursion.
|
| 344 |
+
# ci - 1 as we want to count our current item as well.
|
| 345 |
+
sha, _tree_entry_list = write_tree_from_cache(entries, odb, slice(ci - 1, xi), rbound + 1)
|
| 346 |
+
tree_items.append((sha, S_IFDIR, base))
|
| 347 |
+
|
| 348 |
+
# Skip ahead.
|
| 349 |
+
ci = xi
|
| 350 |
+
# END handle bounds
|
| 351 |
+
# END for each entry
|
| 352 |
+
|
| 353 |
+
# Finally create the tree.
|
| 354 |
+
sio = BytesIO()
|
| 355 |
+
tree_to_stream(tree_items, sio.write) # Writes to stream as bytes, but doesn't change tree_items.
|
| 356 |
+
sio.seek(0)
|
| 357 |
+
|
| 358 |
+
istream = odb.store(IStream(str_tree_type, len(sio.getvalue()), sio))
|
| 359 |
+
return (istream.binsha, tree_items)
|
| 360 |
+
|
| 361 |
+
|
| 362 |
+
def _tree_entry_to_baseindexentry(tree_entry: "TreeCacheTup", stage: int) -> BaseIndexEntry:
|
| 363 |
+
return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def aggressive_tree_merge(odb: "GitCmdObjectDB", tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
|
| 367 |
+
R"""
|
| 368 |
+
:return:
|
| 369 |
+
List of :class:`~git.index.typ.BaseIndexEntry`\s representing the aggressive
|
| 370 |
+
merge of the given trees. All valid entries are on stage 0, whereas the
|
| 371 |
+
conflicting ones are left on stage 1, 2 or 3, whereas stage 1 corresponds to the
|
| 372 |
+
common ancestor tree, 2 to our tree and 3 to 'their' tree.
|
| 373 |
+
|
| 374 |
+
:param tree_shas:
|
| 375 |
+
1, 2 or 3 trees as identified by their binary 20 byte shas. If 1 or two, the
|
| 376 |
+
entries will effectively correspond to the last given tree. If 3 are given, a 3
|
| 377 |
+
way merge is performed.
|
| 378 |
+
"""
|
| 379 |
+
out: List[BaseIndexEntry] = []
|
| 380 |
+
|
| 381 |
+
# One and two way is the same for us, as we don't have to handle an existing
|
| 382 |
+
# index, instrea
|
| 383 |
+
if len(tree_shas) in (1, 2):
|
| 384 |
+
for entry in traverse_tree_recursive(odb, tree_shas[-1], ""):
|
| 385 |
+
out.append(_tree_entry_to_baseindexentry(entry, 0))
|
| 386 |
+
# END for each entry
|
| 387 |
+
return out
|
| 388 |
+
# END handle single tree
|
| 389 |
+
|
| 390 |
+
if len(tree_shas) > 3:
|
| 391 |
+
raise ValueError("Cannot handle %i trees at once" % len(tree_shas))
|
| 392 |
+
|
| 393 |
+
# Three trees.
|
| 394 |
+
for base, ours, theirs in traverse_trees_recursive(odb, tree_shas, ""):
|
| 395 |
+
if base is not None:
|
| 396 |
+
# Base version exists.
|
| 397 |
+
if ours is not None:
|
| 398 |
+
# Ours exists.
|
| 399 |
+
if theirs is not None:
|
| 400 |
+
# It exists in all branches. Ff it was changed in both
|
| 401 |
+
# its a conflict. Otherwise, we take the changed version.
|
| 402 |
+
# This should be the most common branch, so it comes first.
|
| 403 |
+
if (base[0] != ours[0] and base[0] != theirs[0] and ours[0] != theirs[0]) or (
|
| 404 |
+
base[1] != ours[1] and base[1] != theirs[1] and ours[1] != theirs[1]
|
| 405 |
+
):
|
| 406 |
+
# Changed by both.
|
| 407 |
+
out.append(_tree_entry_to_baseindexentry(base, 1))
|
| 408 |
+
out.append(_tree_entry_to_baseindexentry(ours, 2))
|
| 409 |
+
out.append(_tree_entry_to_baseindexentry(theirs, 3))
|
| 410 |
+
elif base[0] != ours[0] or base[1] != ours[1]:
|
| 411 |
+
# Only we changed it.
|
| 412 |
+
out.append(_tree_entry_to_baseindexentry(ours, 0))
|
| 413 |
+
else:
|
| 414 |
+
# Either nobody changed it, or they did. In either
|
| 415 |
+
# case, use theirs.
|
| 416 |
+
out.append(_tree_entry_to_baseindexentry(theirs, 0))
|
| 417 |
+
# END handle modification
|
| 418 |
+
else:
|
| 419 |
+
if ours[0] != base[0] or ours[1] != base[1]:
|
| 420 |
+
# They deleted it, we changed it, conflict.
|
| 421 |
+
out.append(_tree_entry_to_baseindexentry(base, 1))
|
| 422 |
+
out.append(_tree_entry_to_baseindexentry(ours, 2))
|
| 423 |
+
# else:
|
| 424 |
+
# # We didn't change it, ignore.
|
| 425 |
+
# pass
|
| 426 |
+
# END handle our change
|
| 427 |
+
# END handle theirs
|
| 428 |
+
else:
|
| 429 |
+
if theirs is None:
|
| 430 |
+
# Deleted in both, its fine - it's out.
|
| 431 |
+
pass
|
| 432 |
+
else:
|
| 433 |
+
if theirs[0] != base[0] or theirs[1] != base[1]:
|
| 434 |
+
# Deleted in ours, changed theirs, conflict.
|
| 435 |
+
out.append(_tree_entry_to_baseindexentry(base, 1))
|
| 436 |
+
out.append(_tree_entry_to_baseindexentry(theirs, 3))
|
| 437 |
+
# END theirs changed
|
| 438 |
+
# else:
|
| 439 |
+
# # Theirs didn't change.
|
| 440 |
+
# pass
|
| 441 |
+
# END handle theirs
|
| 442 |
+
# END handle ours
|
| 443 |
+
else:
|
| 444 |
+
# All three can't be None.
|
| 445 |
+
if ours is None:
|
| 446 |
+
# Added in their branch.
|
| 447 |
+
assert theirs is not None
|
| 448 |
+
out.append(_tree_entry_to_baseindexentry(theirs, 0))
|
| 449 |
+
elif theirs is None:
|
| 450 |
+
# Added in our branch.
|
| 451 |
+
out.append(_tree_entry_to_baseindexentry(ours, 0))
|
| 452 |
+
else:
|
| 453 |
+
# Both have it, except for the base, see whether it changed.
|
| 454 |
+
if ours[0] != theirs[0] or ours[1] != theirs[1]:
|
| 455 |
+
out.append(_tree_entry_to_baseindexentry(ours, 2))
|
| 456 |
+
out.append(_tree_entry_to_baseindexentry(theirs, 3))
|
| 457 |
+
else:
|
| 458 |
+
# It was added the same in both.
|
| 459 |
+
out.append(_tree_entry_to_baseindexentry(ours, 0))
|
| 460 |
+
# END handle two items
|
| 461 |
+
# END handle heads
|
| 462 |
+
# END handle base exists
|
| 463 |
+
# END for each entries tuple
|
| 464 |
+
|
| 465 |
+
return out
|
venv/lib/python3.10/site-packages/git/objects/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (659 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/git/objects/__pycache__/blob.cpython-310.pyc
ADDED
|
Binary file (1.34 kB). View file
|
|
|
venv/lib/python3.10/site-packages/git/objects/__pycache__/commit.cpython-310.pyc
ADDED
|
Binary file (22.4 kB). View file
|
|
|
venv/lib/python3.10/site-packages/git/objects/__pycache__/util.cpython-310.pyc
ADDED
|
Binary file (19.9 kB). View file
|
|
|
venv/lib/python3.10/site-packages/github/CodeScanAlertInstance.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2022 Eric Nieuwland <eric.nieuwland@gmail.com> #
|
| 4 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 5 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 6 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 7 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 8 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 9 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 10 |
+
# #
|
| 11 |
+
# This file is part of PyGithub. #
|
| 12 |
+
# http://pygithub.readthedocs.io/ #
|
| 13 |
+
# #
|
| 14 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 15 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 16 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 17 |
+
# any later version. #
|
| 18 |
+
# #
|
| 19 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 20 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 21 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 22 |
+
# details. #
|
| 23 |
+
# #
|
| 24 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 25 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 26 |
+
# #
|
| 27 |
+
################################################################################
|
| 28 |
+
|
| 29 |
+
from __future__ import annotations
|
| 30 |
+
|
| 31 |
+
from typing import TYPE_CHECKING, Any
|
| 32 |
+
|
| 33 |
+
import github.CodeScanAlertInstanceLocation
|
| 34 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 35 |
+
|
| 36 |
+
if TYPE_CHECKING:
|
| 37 |
+
from github.CodeScanAlertInstanceLocation import CodeScanAlertInstanceLocation
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class CodeScanAlertInstance(NonCompletableGithubObject):
|
| 41 |
+
"""
|
| 42 |
+
This class represents code scanning alert instances.
|
| 43 |
+
|
| 44 |
+
The reference can be found here
|
| 45 |
+
https://docs.github.com/en/rest/reference/code-scanning.
|
| 46 |
+
|
| 47 |
+
"""
|
| 48 |
+
|
| 49 |
+
def _initAttributes(self) -> None:
|
| 50 |
+
self._analysis_key: Attribute[str] = NotSet
|
| 51 |
+
self._classifications: Attribute[list[str]] = NotSet
|
| 52 |
+
self._commit_sha: Attribute[str] = NotSet
|
| 53 |
+
self._environment: Attribute[str] = NotSet
|
| 54 |
+
self._location: Attribute[CodeScanAlertInstanceLocation] = NotSet
|
| 55 |
+
self._message: Attribute[dict[str, Any]] = NotSet
|
| 56 |
+
self._ref: Attribute[str] = NotSet
|
| 57 |
+
self._state: Attribute[str] = NotSet
|
| 58 |
+
|
| 59 |
+
def __repr__(self) -> str:
|
| 60 |
+
return self.get__repr__({"ref": self.ref, "analysis_key": self.analysis_key})
|
| 61 |
+
|
| 62 |
+
@property
|
| 63 |
+
def analysis_key(self) -> str:
|
| 64 |
+
return self._analysis_key.value
|
| 65 |
+
|
| 66 |
+
@property
|
| 67 |
+
def classifications(self) -> list[str]:
|
| 68 |
+
return self._classifications.value
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def commit_sha(self) -> str:
|
| 72 |
+
return self._commit_sha.value
|
| 73 |
+
|
| 74 |
+
@property
|
| 75 |
+
def environment(self) -> str:
|
| 76 |
+
return self._environment.value
|
| 77 |
+
|
| 78 |
+
@property
|
| 79 |
+
def location(self) -> CodeScanAlertInstanceLocation:
|
| 80 |
+
return self._location.value
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def message(self) -> dict[str, Any]:
|
| 84 |
+
return self._message.value
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def ref(self) -> str:
|
| 88 |
+
return self._ref.value
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def state(self) -> str:
|
| 92 |
+
return self._state.value
|
| 93 |
+
|
| 94 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 95 |
+
if "analysis_key" in attributes: # pragma no branch
|
| 96 |
+
self._analysis_key = self._makeStringAttribute(attributes["analysis_key"])
|
| 97 |
+
if "classifications" in attributes: # pragma no branch
|
| 98 |
+
self._classifications = self._makeListOfStringsAttribute(attributes["classifications"])
|
| 99 |
+
if "commit_sha" in attributes: # pragma no branch
|
| 100 |
+
self._commit_sha = self._makeStringAttribute(attributes["commit_sha"])
|
| 101 |
+
if "environment" in attributes: # pragma no branch
|
| 102 |
+
self._environment = self._makeStringAttribute(attributes["environment"])
|
| 103 |
+
if "environment" in attributes: # pragma no branch
|
| 104 |
+
self._environment = self._makeStringAttribute(attributes["environment"])
|
| 105 |
+
if "location" in attributes: # pragma no branch
|
| 106 |
+
self._location = self._makeClassAttribute(
|
| 107 |
+
github.CodeScanAlertInstanceLocation.CodeScanAlertInstanceLocation,
|
| 108 |
+
attributes["location"],
|
| 109 |
+
)
|
| 110 |
+
if "message" in attributes: # pragma no branch
|
| 111 |
+
self._message = self._makeDictAttribute(attributes["message"])
|
| 112 |
+
if "ref" in attributes: # pragma no branch
|
| 113 |
+
self._ref = self._makeStringAttribute(attributes["ref"])
|
| 114 |
+
if "state" in attributes: # pragma no branch
|
| 115 |
+
self._state = self._makeStringAttribute(attributes["state"])
|
venv/lib/python3.10/site-packages/github/CodeScanAlertInstanceLocation.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2020 Dhruv Manilawala <dhruvmanila@gmail.com> #
|
| 4 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 5 |
+
# Copyright 2022 Eric Nieuwland <eric.nieuwland@gmail.com> #
|
| 6 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 7 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 8 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 9 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 11 |
+
# #
|
| 12 |
+
# This file is part of PyGithub. #
|
| 13 |
+
# http://pygithub.readthedocs.io/ #
|
| 14 |
+
# #
|
| 15 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 16 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 17 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 18 |
+
# any later version. #
|
| 19 |
+
# #
|
| 20 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 21 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 22 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 23 |
+
# details. #
|
| 24 |
+
# #
|
| 25 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 26 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 27 |
+
# #
|
| 28 |
+
################################################################################
|
| 29 |
+
|
| 30 |
+
from typing import Any, Dict
|
| 31 |
+
|
| 32 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class CodeScanAlertInstanceLocation(NonCompletableGithubObject):
|
| 36 |
+
"""
|
| 37 |
+
This class represents code scanning alert instance locations.
|
| 38 |
+
|
| 39 |
+
The reference can be found here
|
| 40 |
+
https://docs.github.com/en/rest/reference/code-scanning.
|
| 41 |
+
|
| 42 |
+
"""
|
| 43 |
+
|
| 44 |
+
def _initAttributes(self) -> None:
|
| 45 |
+
self._end_column: Attribute[int] = NotSet
|
| 46 |
+
self._end_line: Attribute[int] = NotSet
|
| 47 |
+
self._path: Attribute[str] = NotSet
|
| 48 |
+
self._start_column: Attribute[int] = NotSet
|
| 49 |
+
self._start_line: Attribute[int] = NotSet
|
| 50 |
+
|
| 51 |
+
def __repr__(self) -> str:
|
| 52 |
+
return self.get__repr__(
|
| 53 |
+
{
|
| 54 |
+
"path": self.path,
|
| 55 |
+
"start_line": self.start_line,
|
| 56 |
+
"start_column": self.start_column,
|
| 57 |
+
"end_line": self.end_line,
|
| 58 |
+
"end_column": self.end_column,
|
| 59 |
+
}
|
| 60 |
+
)
|
| 61 |
+
|
| 62 |
+
def __str__(self) -> str:
|
| 63 |
+
return f"{self.path} @ l{self.start_line}:c{self.start_column}-l{self.end_line}:c{self.end_column}"
|
| 64 |
+
|
| 65 |
+
@property
|
| 66 |
+
def end_column(self) -> int:
|
| 67 |
+
return self._end_column.value
|
| 68 |
+
|
| 69 |
+
@property
|
| 70 |
+
def end_line(self) -> int:
|
| 71 |
+
return self._end_line.value
|
| 72 |
+
|
| 73 |
+
@property
|
| 74 |
+
def path(self) -> str:
|
| 75 |
+
return self._path.value
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def start_column(self) -> int:
|
| 79 |
+
return self._start_column.value
|
| 80 |
+
|
| 81 |
+
@property
|
| 82 |
+
def start_line(self) -> int:
|
| 83 |
+
return self._start_line.value
|
| 84 |
+
|
| 85 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 86 |
+
if "end_column" in attributes: # pragma no branch
|
| 87 |
+
self._end_column = self._makeIntAttribute(attributes["end_column"])
|
| 88 |
+
if "end_line" in attributes: # pragma no branch
|
| 89 |
+
self._end_line = self._makeIntAttribute(attributes["end_line"])
|
| 90 |
+
if "path" in attributes: # pragma no branch
|
| 91 |
+
self._path = self._makeStringAttribute(attributes["path"])
|
| 92 |
+
if "start_column" in attributes: # pragma no branch
|
| 93 |
+
self._start_column = self._makeIntAttribute(attributes["start_column"])
|
| 94 |
+
if "start_line" in attributes: # pragma no branch
|
| 95 |
+
self._start_line = self._makeIntAttribute(attributes["start_line"])
|
venv/lib/python3.10/site-packages/github/CodeScanRule.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2020 Victor Zeng <zacker150@users.noreply.github.com> #
|
| 16 |
+
# Copyright 2022 Eric Nieuwland <eric.nieuwland@gmail.com> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 23 |
+
# #
|
| 24 |
+
# This file is part of PyGithub. #
|
| 25 |
+
# http://pygithub.readthedocs.io/ #
|
| 26 |
+
# #
|
| 27 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 28 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 29 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 30 |
+
# any later version. #
|
| 31 |
+
# #
|
| 32 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 33 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 34 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 35 |
+
# details. #
|
| 36 |
+
# #
|
| 37 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 38 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 39 |
+
# #
|
| 40 |
+
################################################################################
|
| 41 |
+
|
| 42 |
+
from __future__ import annotations
|
| 43 |
+
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class CodeScanRule(NonCompletableGithubObject):
|
| 50 |
+
"""
|
| 51 |
+
This class represents Alerts from code scanning.
|
| 52 |
+
|
| 53 |
+
The reference can be found here
|
| 54 |
+
https://docs.github.com/en/rest/reference/code-scanning.
|
| 55 |
+
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
def _initAttributes(self) -> None:
|
| 59 |
+
self._description: Attribute[str] = NotSet
|
| 60 |
+
self._id: Attribute[str] = NotSet
|
| 61 |
+
self._name: Attribute[str] = NotSet
|
| 62 |
+
self._security_severity_level: Attribute[str] = NotSet
|
| 63 |
+
self._severity: Attribute[str] = NotSet
|
| 64 |
+
|
| 65 |
+
def __repr__(self) -> str:
|
| 66 |
+
return self.get__repr__({"id": self.id, "name": self.name})
|
| 67 |
+
|
| 68 |
+
@property
|
| 69 |
+
def description(self) -> str:
|
| 70 |
+
return self._description.value
|
| 71 |
+
|
| 72 |
+
@property
|
| 73 |
+
def id(self) -> str:
|
| 74 |
+
return self._id.value
|
| 75 |
+
|
| 76 |
+
@property
|
| 77 |
+
def name(self) -> str:
|
| 78 |
+
return self._name.value
|
| 79 |
+
|
| 80 |
+
@property
|
| 81 |
+
def security_severity_level(self) -> str:
|
| 82 |
+
return self._security_severity_level.value
|
| 83 |
+
|
| 84 |
+
@property
|
| 85 |
+
def severity(self) -> str:
|
| 86 |
+
return self._severity.value
|
| 87 |
+
|
| 88 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 89 |
+
if "description" in attributes: # pragma no branch
|
| 90 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 91 |
+
if "id" in attributes: # pragma no branch
|
| 92 |
+
self._id = self._makeStringAttribute(attributes["id"])
|
| 93 |
+
if "name" in attributes: # pragma no branch
|
| 94 |
+
self._name = self._makeStringAttribute(attributes["name"])
|
| 95 |
+
if "security_severity_level" in attributes: # pragma no branch
|
| 96 |
+
self._security_severity_level = self._makeStringAttribute(attributes["security_severity_level"])
|
| 97 |
+
if "severity" in attributes: # pragma no branch
|
| 98 |
+
self._severity = self._makeStringAttribute(attributes["severity"])
|
venv/lib/python3.10/site-packages/github/CodeScanTool.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2022 Eric Nieuwland <eric.nieuwland@gmail.com> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 19 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 20 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 21 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
from typing import Any, Dict
|
| 42 |
+
|
| 43 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
class CodeScanTool(NonCompletableGithubObject):
|
| 47 |
+
"""
|
| 48 |
+
This class represents code scanning tools.
|
| 49 |
+
|
| 50 |
+
The reference can be found here
|
| 51 |
+
https://docs.github.com/en/rest/reference/code-scanning.
|
| 52 |
+
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
def _initAttributes(self) -> None:
|
| 56 |
+
self._guid: Attribute[str] = NotSet
|
| 57 |
+
self._name: Attribute[str] = NotSet
|
| 58 |
+
self._version: Attribute[str] = NotSet
|
| 59 |
+
|
| 60 |
+
def __repr__(self) -> str:
|
| 61 |
+
return self.get__repr__(
|
| 62 |
+
{
|
| 63 |
+
"guid": self.guid,
|
| 64 |
+
"name": self.name,
|
| 65 |
+
"version": self.version,
|
| 66 |
+
}
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
@property
|
| 70 |
+
def guid(self) -> str:
|
| 71 |
+
return self._guid.value
|
| 72 |
+
|
| 73 |
+
@property
|
| 74 |
+
def name(self) -> str:
|
| 75 |
+
return self._name.value
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def version(self) -> str:
|
| 79 |
+
return self._version.value
|
| 80 |
+
|
| 81 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 82 |
+
if "guid" in attributes: # pragma no branch
|
| 83 |
+
self._guid = self._makeStringAttribute(attributes["guid"])
|
| 84 |
+
if "name" in attributes: # pragma no branch
|
| 85 |
+
self._name = self._makeStringAttribute(attributes["name"])
|
| 86 |
+
if "version" in attributes: # pragma no branch
|
| 87 |
+
self._version = self._makeStringAttribute(attributes["version"])
|
venv/lib/python3.10/site-packages/github/CodeSecurityConfig.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2025 Bill Napier <napier@pobox.com> #
|
| 4 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 5 |
+
# #
|
| 6 |
+
# This file is part of PyGithub. #
|
| 7 |
+
# http://pygithub.readthedocs.io/ #
|
| 8 |
+
# #
|
| 9 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 10 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 11 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 12 |
+
# any later version. #
|
| 13 |
+
# #
|
| 14 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 15 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 16 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 17 |
+
# details. #
|
| 18 |
+
# #
|
| 19 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 20 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 21 |
+
# #
|
| 22 |
+
################################################################################
|
| 23 |
+
|
| 24 |
+
from __future__ import annotations
|
| 25 |
+
|
| 26 |
+
from datetime import datetime
|
| 27 |
+
from typing import Any
|
| 28 |
+
|
| 29 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class CodeSecurityConfig(NonCompletableGithubObject):
|
| 33 |
+
"""
|
| 34 |
+
This class represents Configurations for Code Security.
|
| 35 |
+
|
| 36 |
+
The reference can be found here
|
| 37 |
+
https://docs.github.com/en/rest/code-security/configurations.
|
| 38 |
+
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
def _initAttributes(self) -> None:
|
| 42 |
+
self._id: Attribute[int] = NotSet
|
| 43 |
+
self._name: Attribute[str] = NotSet
|
| 44 |
+
self._advanced_security: Attribute[str] = NotSet
|
| 45 |
+
self._code_scanning_default_setup: Attribute[str] = NotSet
|
| 46 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 47 |
+
self._dependabot_alerts: Attribute[str] = NotSet
|
| 48 |
+
self._dependabot_security_updates: Attribute[str] = NotSet
|
| 49 |
+
self._dependency_graph: Attribute[str] = NotSet
|
| 50 |
+
self._dependency_graph_autosubmit_action: Attribute[str] = NotSet
|
| 51 |
+
self._description: Attribute[str] = NotSet
|
| 52 |
+
self._enforcement: Attribute[str] = NotSet
|
| 53 |
+
self._html_url: Attribute[str] = NotSet
|
| 54 |
+
self._private_vulnerability_reporting: Attribute[str] = NotSet
|
| 55 |
+
self._secret_scanning: Attribute[str] = NotSet
|
| 56 |
+
self._secret_scanning_delegated_bypass: Attribute[str] = NotSet
|
| 57 |
+
self._secret_scanning_non_provider_patterns: Attribute[str] = NotSet
|
| 58 |
+
self._secret_scanning_push_protection: Attribute[str] = NotSet
|
| 59 |
+
self._secret_scanning_validity_checks: Attribute[str] = NotSet
|
| 60 |
+
self._target_type: Attribute[str] = NotSet
|
| 61 |
+
self._url: Attribute[str] = NotSet
|
| 62 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 63 |
+
|
| 64 |
+
def __repr__(self) -> str:
|
| 65 |
+
return self.get__repr__(
|
| 66 |
+
{
|
| 67 |
+
"id": self.id,
|
| 68 |
+
"name": self.name,
|
| 69 |
+
"description": self.description,
|
| 70 |
+
}
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
@property
|
| 74 |
+
def advanced_security(self) -> str:
|
| 75 |
+
return self._advanced_security.value
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def code_scanning_default_setup(self) -> str:
|
| 79 |
+
return self._code_scanning_default_setup.value
|
| 80 |
+
|
| 81 |
+
@property
|
| 82 |
+
def created_at(self) -> datetime:
|
| 83 |
+
return self._created_at.value
|
| 84 |
+
|
| 85 |
+
@property
|
| 86 |
+
def dependabot_alerts(self) -> str:
|
| 87 |
+
return self._dependabot_alerts.value
|
| 88 |
+
|
| 89 |
+
@property
|
| 90 |
+
def dependabot_security_updates(self) -> str:
|
| 91 |
+
return self._dependabot_security_updates.value
|
| 92 |
+
|
| 93 |
+
@property
|
| 94 |
+
def dependency_graph(self) -> str:
|
| 95 |
+
return self._dependency_graph.value
|
| 96 |
+
|
| 97 |
+
@property
|
| 98 |
+
def dependency_graph_autosubmit_action(self) -> str:
|
| 99 |
+
return self._dependency_graph_autosubmit_action.value
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def description(self) -> str:
|
| 103 |
+
return self._description.value
|
| 104 |
+
|
| 105 |
+
@property
|
| 106 |
+
def enforcement(self) -> str:
|
| 107 |
+
return self._enforcement.value
|
| 108 |
+
|
| 109 |
+
@property
|
| 110 |
+
def html_url(self) -> str:
|
| 111 |
+
return self._html_url.value
|
| 112 |
+
|
| 113 |
+
@property
|
| 114 |
+
def id(self) -> int:
|
| 115 |
+
return self._id.value
|
| 116 |
+
|
| 117 |
+
@property
|
| 118 |
+
def name(self) -> str:
|
| 119 |
+
return self._name.value
|
| 120 |
+
|
| 121 |
+
@property
|
| 122 |
+
def private_vulnerability_reporting(self) -> str:
|
| 123 |
+
return self._private_vulnerability_reporting.value
|
| 124 |
+
|
| 125 |
+
@property
|
| 126 |
+
def secret_scanning(self) -> str:
|
| 127 |
+
return self._secret_scanning.value
|
| 128 |
+
|
| 129 |
+
@property
|
| 130 |
+
def secret_scanning_delegated_bypass(self) -> str:
|
| 131 |
+
return self._secret_scanning_delegated_bypass.value
|
| 132 |
+
|
| 133 |
+
@property
|
| 134 |
+
def secret_scanning_non_provider_patterns(self) -> str:
|
| 135 |
+
return self._secret_scanning_non_provider_patterns.value
|
| 136 |
+
|
| 137 |
+
@property
|
| 138 |
+
def secret_scanning_push_protection(self) -> str:
|
| 139 |
+
return self._secret_scanning_push_protection.value
|
| 140 |
+
|
| 141 |
+
@property
|
| 142 |
+
def secret_scanning_validity_checks(self) -> str:
|
| 143 |
+
return self._secret_scanning_validity_checks.value
|
| 144 |
+
|
| 145 |
+
@property
|
| 146 |
+
def target_type(self) -> str:
|
| 147 |
+
return self._target_type.value
|
| 148 |
+
|
| 149 |
+
@property
|
| 150 |
+
def updated_at(self) -> datetime:
|
| 151 |
+
return self._updated_at.value
|
| 152 |
+
|
| 153 |
+
@property
|
| 154 |
+
def url(self) -> str:
|
| 155 |
+
return self._url.value
|
| 156 |
+
|
| 157 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 158 |
+
if "advanced_security" in attributes: # pragma no branch
|
| 159 |
+
self._advanced_security = self._makeStringAttribute(attributes["advanced_security"])
|
| 160 |
+
if "code_scanning_default_setup" in attributes: # pragma no branch
|
| 161 |
+
self._code_scanning_default_setup = self._makeStringAttribute(attributes["code_scanning_default_setup"])
|
| 162 |
+
if "created_at" in attributes: # pragma no branch
|
| 163 |
+
assert attributes["created_at"] is None or isinstance(attributes["created_at"], str), attributes[
|
| 164 |
+
"created_at"
|
| 165 |
+
]
|
| 166 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 167 |
+
if "dependabot_alerts" in attributes: # pragma no branch
|
| 168 |
+
self._dependabot_alerts = self._makeStringAttribute(attributes["dependabot_alerts"])
|
| 169 |
+
if "dependabot_security_updates" in attributes: # pragma no branch
|
| 170 |
+
self._dependabot_security_updates = self._makeStringAttribute(attributes["dependabot_security_updates"])
|
| 171 |
+
if "dependency_graph" in attributes: # pragma no branch
|
| 172 |
+
self._dependency_graph = self._makeStringAttribute(attributes["dependency_graph"])
|
| 173 |
+
if "dependency_graph_autosubmit_action" in attributes: # pragma no branch
|
| 174 |
+
self._dependency_graph_autosubmit_action = self._makeStringAttribute(
|
| 175 |
+
attributes["dependency_graph_autosubmit_action"]
|
| 176 |
+
)
|
| 177 |
+
if "description" in attributes: # pragma no branch
|
| 178 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 179 |
+
if "enforcement" in attributes: # pragma no branch
|
| 180 |
+
self._enforcement = self._makeStringAttribute(attributes["enforcement"])
|
| 181 |
+
if "html_url" in attributes: # pragma no branch
|
| 182 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 183 |
+
if "id" in attributes: # pragma no branch
|
| 184 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 185 |
+
if "name" in attributes: # pragma no branch
|
| 186 |
+
self._name = self._makeStringAttribute(attributes["name"])
|
| 187 |
+
if "private_vulnerability_reporting" in attributes: # pragma no branch
|
| 188 |
+
self._private_vulnerability_reporting = self._makeStringAttribute(
|
| 189 |
+
attributes["private_vulnerability_reporting"]
|
| 190 |
+
)
|
| 191 |
+
if "secret_scanning" in attributes: # pragma no branch
|
| 192 |
+
self._secret_scanning = self._makeStringAttribute(attributes["secret_scanning"])
|
| 193 |
+
if "secret_scanning_delegated_bypass" in attributes: # pragma no branch
|
| 194 |
+
self._secret_scanning_delegated_bypass = self._makeStringAttribute(
|
| 195 |
+
attributes["secret_scanning_delegated_bypass"]
|
| 196 |
+
)
|
| 197 |
+
if "secret_scanning_non_provider_patterns" in attributes: # pragma no branch
|
| 198 |
+
self._secret_scanning_non_provider_patterns = self._makeStringAttribute(
|
| 199 |
+
attributes["secret_scanning_non_provider_patterns"]
|
| 200 |
+
)
|
| 201 |
+
if "secret_scanning_push_protection" in attributes: # pragma no branch
|
| 202 |
+
self._secret_scanning_push_protection = self._makeStringAttribute(
|
| 203 |
+
attributes["secret_scanning_push_protection"]
|
| 204 |
+
)
|
| 205 |
+
if "secret_scanning_validity_checks" in attributes: # pragma no branch
|
| 206 |
+
self._secret_scanning_validity_checks = self._makeStringAttribute(
|
| 207 |
+
attributes["secret_scanning_validity_checks"]
|
| 208 |
+
)
|
| 209 |
+
if "target_type" in attributes: # pragma no branch
|
| 210 |
+
self._target_type = self._makeStringAttribute(attributes["target_type"])
|
| 211 |
+
if "updated_at" in attributes: # pragma no branch
|
| 212 |
+
assert attributes["updated_at"] is None or isinstance(attributes["updated_at"], str), attributes[
|
| 213 |
+
"updated_at"
|
| 214 |
+
]
|
| 215 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 216 |
+
if "url" in attributes: # pragma no branch
|
| 217 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/CodeSecurityConfigRepository.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 4 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 5 |
+
# Copyright 2024 Thomas Cooper <coopernetes@proton.me> #
|
| 6 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 7 |
+
# #
|
| 8 |
+
# This file is part of PyGithub. #
|
| 9 |
+
# http://pygithub.readthedocs.io/ #
|
| 10 |
+
# #
|
| 11 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 12 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 13 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 14 |
+
# any later version. #
|
| 15 |
+
# #
|
| 16 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 17 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 18 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 19 |
+
# details. #
|
| 20 |
+
# #
|
| 21 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 22 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 23 |
+
# #
|
| 24 |
+
################################################################################
|
| 25 |
+
|
| 26 |
+
from __future__ import annotations
|
| 27 |
+
|
| 28 |
+
from typing import TYPE_CHECKING, Any
|
| 29 |
+
|
| 30 |
+
import github.Repository
|
| 31 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 32 |
+
|
| 33 |
+
if TYPE_CHECKING:
|
| 34 |
+
from github.Repository import Repository
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class CodeSecurityConfigRepository(NonCompletableGithubObject):
|
| 38 |
+
"""
|
| 39 |
+
This class represents CodeSecurityConfigRepository.
|
| 40 |
+
|
| 41 |
+
The reference can be found here
|
| 42 |
+
https://docs.github.com/en/rest/code-security/configurations
|
| 43 |
+
|
| 44 |
+
The OpenAPI schema can be found at
|
| 45 |
+
- /components/schemas/code-security-configuration-repositories
|
| 46 |
+
|
| 47 |
+
"""
|
| 48 |
+
|
| 49 |
+
def _initAttributes(self) -> None:
|
| 50 |
+
self._repository: Attribute[Repository] = NotSet
|
| 51 |
+
self._status: Attribute[str] = NotSet
|
| 52 |
+
|
| 53 |
+
def __repr__(self) -> str:
|
| 54 |
+
return self.repository.__repr__()
|
| 55 |
+
|
| 56 |
+
@property
|
| 57 |
+
def repository(self) -> Repository:
|
| 58 |
+
return self._repository.value
|
| 59 |
+
|
| 60 |
+
@property
|
| 61 |
+
def status(self) -> str:
|
| 62 |
+
return self._status.value
|
| 63 |
+
|
| 64 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 65 |
+
if "repository" in attributes: # pragma no branch
|
| 66 |
+
self._repository = self._makeClassAttribute(github.Repository.Repository, attributes["repository"])
|
| 67 |
+
if "status" in attributes: # pragma no branch
|
| 68 |
+
self._status = self._makeStringAttribute(attributes["status"])
|
venv/lib/python3.10/site-packages/github/Commit.py
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2013 martinqt <m.ki2@laposte.net> #
|
| 8 |
+
# Copyright 2014 Andy Casey <acasey@mso.anu.edu.au> #
|
| 9 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 10 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 11 |
+
# Copyright 2016 John Eskew <jeskew@edx.org> #
|
| 12 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2020 Danilo Martins <mawkee@gmail.com> #
|
| 17 |
+
# Copyright 2020 Dhruv Manilawala <dhruvmanila@gmail.com> #
|
| 18 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 19 |
+
# Copyright 2021 Mark Walker <mark.walker@realbuzz.com> #
|
| 20 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 21 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 23 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 24 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 25 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 26 |
+
# Copyright 2024 iarspider <iarspider@gmail.com> #
|
| 27 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 28 |
+
# Copyright 2025 xmo-odoo <xmo@odoo.com> #
|
| 29 |
+
# #
|
| 30 |
+
# This file is part of PyGithub. #
|
| 31 |
+
# http://pygithub.readthedocs.io/ #
|
| 32 |
+
# #
|
| 33 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 34 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 35 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 36 |
+
# any later version. #
|
| 37 |
+
# #
|
| 38 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 39 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 40 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 41 |
+
# details. #
|
| 42 |
+
# #
|
| 43 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 44 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 45 |
+
# #
|
| 46 |
+
################################################################################
|
| 47 |
+
|
| 48 |
+
from __future__ import annotations
|
| 49 |
+
|
| 50 |
+
from typing import TYPE_CHECKING, Any
|
| 51 |
+
|
| 52 |
+
import github.Branch
|
| 53 |
+
import github.CheckRun
|
| 54 |
+
import github.CheckSuite
|
| 55 |
+
import github.CommitCombinedStatus
|
| 56 |
+
import github.CommitComment
|
| 57 |
+
import github.CommitStats
|
| 58 |
+
import github.CommitStatus
|
| 59 |
+
import github.File
|
| 60 |
+
import github.GitCommit
|
| 61 |
+
import github.NamedUser
|
| 62 |
+
import github.PaginatedList
|
| 63 |
+
import github.Repository
|
| 64 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet, Opt, is_optional
|
| 65 |
+
from github.PaginatedList import PaginatedList
|
| 66 |
+
|
| 67 |
+
if TYPE_CHECKING:
|
| 68 |
+
from github.Branch import Branch
|
| 69 |
+
from github.CheckRun import CheckRun
|
| 70 |
+
from github.CheckSuite import CheckSuite
|
| 71 |
+
from github.CommitCombinedStatus import CommitCombinedStatus
|
| 72 |
+
from github.CommitComment import CommitComment
|
| 73 |
+
from github.CommitStats import CommitStats
|
| 74 |
+
from github.CommitStatus import CommitStatus
|
| 75 |
+
from github.File import File
|
| 76 |
+
from github.GitCommit import GitCommit
|
| 77 |
+
from github.NamedUser import NamedUser
|
| 78 |
+
from github.PullRequest import PullRequest
|
| 79 |
+
from github.Repository import Repository
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
class Commit(CompletableGithubObject):
|
| 83 |
+
"""
|
| 84 |
+
This class represents Commits.
|
| 85 |
+
|
| 86 |
+
The reference can be found here
|
| 87 |
+
https://docs.github.com/en/rest/commits/commits#get-a-commit-object
|
| 88 |
+
|
| 89 |
+
The OpenAPI schema can be found at
|
| 90 |
+
- /components/schemas/branch-short/properties/commit
|
| 91 |
+
- /components/schemas/commit
|
| 92 |
+
- /components/schemas/commit-search-result-item
|
| 93 |
+
- /components/schemas/commit-search-result-item/properties/parents/items
|
| 94 |
+
- /components/schemas/commit/properties/parents/items
|
| 95 |
+
- /components/schemas/short-branch/properties/commit
|
| 96 |
+
- /components/schemas/tag/properties/commit
|
| 97 |
+
|
| 98 |
+
"""
|
| 99 |
+
|
| 100 |
+
def _initAttributes(self) -> None:
|
| 101 |
+
self._author: Attribute[NamedUser] = NotSet
|
| 102 |
+
self._comments_url: Attribute[str] = NotSet
|
| 103 |
+
self._commit: Attribute[GitCommit] = NotSet
|
| 104 |
+
self._committer: Attribute[NamedUser] = NotSet
|
| 105 |
+
self._files: Attribute[list[File]] = NotSet
|
| 106 |
+
self._html_url: Attribute[str] = NotSet
|
| 107 |
+
self._node_id: Attribute[str] = NotSet
|
| 108 |
+
self._parents: Attribute[list[Commit]] = NotSet
|
| 109 |
+
self._repository: Attribute[Repository] = NotSet
|
| 110 |
+
self._score: Attribute[float] = NotSet
|
| 111 |
+
self._sha: Attribute[str] = NotSet
|
| 112 |
+
self._stats: Attribute[CommitStats] = NotSet
|
| 113 |
+
self._text_matches: Attribute[dict[str, Any]] = NotSet
|
| 114 |
+
self._url: Attribute[str] = NotSet
|
| 115 |
+
|
| 116 |
+
def __repr__(self) -> str:
|
| 117 |
+
return self.get__repr__({"sha": self._sha.value})
|
| 118 |
+
|
| 119 |
+
@property
|
| 120 |
+
def _identity(self) -> str:
|
| 121 |
+
return self.sha
|
| 122 |
+
|
| 123 |
+
@property
|
| 124 |
+
def author(self) -> NamedUser:
|
| 125 |
+
self._completeIfNotSet(self._author)
|
| 126 |
+
return self._author.value
|
| 127 |
+
|
| 128 |
+
@property
|
| 129 |
+
def comments_url(self) -> str:
|
| 130 |
+
self._completeIfNotSet(self._comments_url)
|
| 131 |
+
return self._comments_url.value
|
| 132 |
+
|
| 133 |
+
@property
|
| 134 |
+
def commit(self) -> GitCommit:
|
| 135 |
+
self._completeIfNotSet(self._commit)
|
| 136 |
+
return self._commit.value
|
| 137 |
+
|
| 138 |
+
@property
|
| 139 |
+
def committer(self) -> NamedUser:
|
| 140 |
+
self._completeIfNotSet(self._committer)
|
| 141 |
+
return self._committer.value
|
| 142 |
+
|
| 143 |
+
# This should be a method, but this used to be a property and cannot be changed without breaking user code
|
| 144 |
+
# TODO: remove @property on version 3
|
| 145 |
+
@property
|
| 146 |
+
def files(self) -> PaginatedList[File]:
|
| 147 |
+
return PaginatedList(
|
| 148 |
+
github.File.File,
|
| 149 |
+
self._requester,
|
| 150 |
+
self.url,
|
| 151 |
+
{},
|
| 152 |
+
headers=None,
|
| 153 |
+
list_item="files",
|
| 154 |
+
total_count_item="total_files",
|
| 155 |
+
firstData=self.raw_data,
|
| 156 |
+
firstHeaders=self.raw_headers,
|
| 157 |
+
)
|
| 158 |
+
|
| 159 |
+
@property
|
| 160 |
+
def html_url(self) -> str:
|
| 161 |
+
self._completeIfNotSet(self._html_url)
|
| 162 |
+
return self._html_url.value
|
| 163 |
+
|
| 164 |
+
@property
|
| 165 |
+
def node_id(self) -> str:
|
| 166 |
+
self._completeIfNotSet(self._node_id)
|
| 167 |
+
return self._node_id.value
|
| 168 |
+
|
| 169 |
+
@property
|
| 170 |
+
def parents(self) -> list[Commit]:
|
| 171 |
+
self._completeIfNotSet(self._parents)
|
| 172 |
+
return self._parents.value
|
| 173 |
+
|
| 174 |
+
@property
|
| 175 |
+
def repository(self) -> Repository:
|
| 176 |
+
self._completeIfNotSet(self._repository)
|
| 177 |
+
return self._repository.value
|
| 178 |
+
|
| 179 |
+
@property
|
| 180 |
+
def score(self) -> float:
|
| 181 |
+
self._completeIfNotSet(self._score)
|
| 182 |
+
return self._score.value
|
| 183 |
+
|
| 184 |
+
@property
|
| 185 |
+
def sha(self) -> str:
|
| 186 |
+
self._completeIfNotSet(self._sha)
|
| 187 |
+
return self._sha.value
|
| 188 |
+
|
| 189 |
+
@property
|
| 190 |
+
def stats(self) -> CommitStats:
|
| 191 |
+
self._completeIfNotSet(self._stats)
|
| 192 |
+
return self._stats.value
|
| 193 |
+
|
| 194 |
+
@property
|
| 195 |
+
def text_matches(self) -> dict[str, Any]:
|
| 196 |
+
self._completeIfNotSet(self._text_matches)
|
| 197 |
+
return self._text_matches.value
|
| 198 |
+
|
| 199 |
+
@property
|
| 200 |
+
def url(self) -> str:
|
| 201 |
+
self._completeIfNotSet(self._url)
|
| 202 |
+
return self._url.value
|
| 203 |
+
|
| 204 |
+
def create_comment(
|
| 205 |
+
self,
|
| 206 |
+
body: str,
|
| 207 |
+
line: Opt[int] = NotSet,
|
| 208 |
+
path: Opt[str] = NotSet,
|
| 209 |
+
position: Opt[int] = NotSet,
|
| 210 |
+
) -> CommitComment:
|
| 211 |
+
"""
|
| 212 |
+
:calls: `POST /repos/{owner}/{repo}/commits/{sha}/comments <https://docs.github.com/en/rest/reference/repos#comments>`_
|
| 213 |
+
"""
|
| 214 |
+
assert isinstance(body, str), body
|
| 215 |
+
assert is_optional(line, int), line
|
| 216 |
+
assert is_optional(path, str), path
|
| 217 |
+
assert is_optional(position, int), position
|
| 218 |
+
post_parameters = NotSet.remove_unset_items({"body": body, "line": line, "path": path, "position": position})
|
| 219 |
+
|
| 220 |
+
headers, data = self._requester.requestJsonAndCheck("POST", f"{self.url}/comments", input=post_parameters)
|
| 221 |
+
return github.CommitComment.CommitComment(self._requester, headers, data, completed=True)
|
| 222 |
+
|
| 223 |
+
def create_status(
|
| 224 |
+
self,
|
| 225 |
+
state: str,
|
| 226 |
+
target_url: Opt[str] = NotSet,
|
| 227 |
+
description: Opt[str] = NotSet,
|
| 228 |
+
context: Opt[str] = NotSet,
|
| 229 |
+
) -> CommitStatus:
|
| 230 |
+
"""
|
| 231 |
+
:calls: `POST /repos/{owner}/{repo}/statuses/{sha} <https://docs.github.com/en/rest/reference/repos#statuses>`_
|
| 232 |
+
"""
|
| 233 |
+
assert isinstance(state, str), state
|
| 234 |
+
assert is_optional(target_url, str), target_url
|
| 235 |
+
assert is_optional(description, str), description
|
| 236 |
+
assert is_optional(context, str), context
|
| 237 |
+
post_parameters = NotSet.remove_unset_items(
|
| 238 |
+
{
|
| 239 |
+
"state": state,
|
| 240 |
+
"target_url": target_url,
|
| 241 |
+
"description": description,
|
| 242 |
+
"context": context,
|
| 243 |
+
}
|
| 244 |
+
)
|
| 245 |
+
|
| 246 |
+
headers, data = self._requester.requestJsonAndCheck(
|
| 247 |
+
"POST",
|
| 248 |
+
f"{self._parentUrl(self._parentUrl(self.url))}/statuses/{self.sha}",
|
| 249 |
+
input=post_parameters,
|
| 250 |
+
)
|
| 251 |
+
return github.CommitStatus.CommitStatus(self._requester, headers, data)
|
| 252 |
+
|
| 253 |
+
def get_branches_where_head(self) -> list[Branch]:
|
| 254 |
+
"""
|
| 255 |
+
:calls: `GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head <https://docs.github.com/rest/commits/commits#list-branches-for-head-commit>`_
|
| 256 |
+
"""
|
| 257 |
+
headers, data = self._requester.requestJsonAndCheck("GET", f"{self.url}/branches-where-head")
|
| 258 |
+
return [github.Branch.Branch(self._requester, headers, item) for item in data]
|
| 259 |
+
|
| 260 |
+
def get_comments(self) -> PaginatedList[CommitComment]:
|
| 261 |
+
"""
|
| 262 |
+
:calls: `GET /repos/{owner}/{repo}/commits/{sha}/comments <https://docs.github.com/en/rest/reference/repos#comments>`_
|
| 263 |
+
"""
|
| 264 |
+
return PaginatedList(
|
| 265 |
+
github.CommitComment.CommitComment,
|
| 266 |
+
self._requester,
|
| 267 |
+
f"{self.url}/comments",
|
| 268 |
+
None,
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
def get_statuses(self) -> PaginatedList[CommitStatus]:
|
| 272 |
+
"""
|
| 273 |
+
:calls: `GET /repos/{owner}/{repo}/statuses/{ref} <https://docs.github.com/en/rest/reference/repos#statuses>`_
|
| 274 |
+
"""
|
| 275 |
+
return PaginatedList(
|
| 276 |
+
github.CommitStatus.CommitStatus,
|
| 277 |
+
self._requester,
|
| 278 |
+
f"{self._parentUrl(self._parentUrl(self.url))}/statuses/{self.sha}",
|
| 279 |
+
None,
|
| 280 |
+
)
|
| 281 |
+
|
| 282 |
+
def get_combined_status(self) -> CommitCombinedStatus:
|
| 283 |
+
"""
|
| 284 |
+
:calls: `GET /repos/{owner}/{repo}/commits/{ref}/status/ <http://docs.github.com/en/rest/reference/repos#statuses>`_
|
| 285 |
+
"""
|
| 286 |
+
headers, data = self._requester.requestJsonAndCheck("GET", f"{self.url}/status")
|
| 287 |
+
return github.CommitCombinedStatus.CommitCombinedStatus(self._requester, headers, data)
|
| 288 |
+
|
| 289 |
+
def get_pulls(self) -> PaginatedList[PullRequest]:
|
| 290 |
+
"""
|
| 291 |
+
:calls: `GET /repos/{owner}/{repo}/commits/{sha}/pulls <https://docs.github.com/en/rest/reference/repos#list-pull-requests-associated-with-a-commit>`_
|
| 292 |
+
"""
|
| 293 |
+
return PaginatedList(
|
| 294 |
+
github.PullRequest.PullRequest,
|
| 295 |
+
self._requester,
|
| 296 |
+
f"{self.url}/pulls",
|
| 297 |
+
None,
|
| 298 |
+
headers={"Accept": "application/vnd.github.groot-preview+json"},
|
| 299 |
+
)
|
| 300 |
+
|
| 301 |
+
def get_check_runs(
|
| 302 |
+
self,
|
| 303 |
+
check_name: Opt[str] = NotSet,
|
| 304 |
+
status: Opt[str] = NotSet,
|
| 305 |
+
filter: Opt[str] = NotSet,
|
| 306 |
+
) -> PaginatedList[CheckRun]:
|
| 307 |
+
"""
|
| 308 |
+
:calls: `GET /repos/{owner}/{repo}/commits/{sha}/check-runs <https://docs.github.com/en/rest/reference/checks#list-check-runs-for-a-git-reference>`_
|
| 309 |
+
"""
|
| 310 |
+
assert is_optional(check_name, str), check_name
|
| 311 |
+
assert is_optional(status, str), status
|
| 312 |
+
assert is_optional(filter, str), filter
|
| 313 |
+
url_parameters = NotSet.remove_unset_items({"check_name": check_name, "status": status, "filter": filter})
|
| 314 |
+
|
| 315 |
+
return PaginatedList(
|
| 316 |
+
github.CheckRun.CheckRun,
|
| 317 |
+
self._requester,
|
| 318 |
+
f"{self.url}/check-runs",
|
| 319 |
+
url_parameters,
|
| 320 |
+
headers={"Accept": "application/vnd.github.v3+json"},
|
| 321 |
+
list_item="check_runs",
|
| 322 |
+
)
|
| 323 |
+
|
| 324 |
+
def get_check_suites(self, app_id: Opt[int] = NotSet, check_name: Opt[str] = NotSet) -> PaginatedList[CheckSuite]:
|
| 325 |
+
"""
|
| 326 |
+
:class: `GET /repos/{owner}/{repo}/commits/{ref}/check-suites <https://docs.github.com/en/rest/reference/checks#list-check-suites-for-a-git-reference>`_
|
| 327 |
+
"""
|
| 328 |
+
assert is_optional(app_id, int), app_id
|
| 329 |
+
assert is_optional(check_name, str), check_name
|
| 330 |
+
parameters = NotSet.remove_unset_items({"app_id": app_id, "check_name": check_name})
|
| 331 |
+
|
| 332 |
+
request_headers = {"Accept": "application/vnd.github.v3+json"}
|
| 333 |
+
return PaginatedList(
|
| 334 |
+
github.CheckSuite.CheckSuite,
|
| 335 |
+
self._requester,
|
| 336 |
+
f"{self.url}/check-suites",
|
| 337 |
+
parameters,
|
| 338 |
+
headers=request_headers,
|
| 339 |
+
list_item="check_suites",
|
| 340 |
+
)
|
| 341 |
+
|
| 342 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 343 |
+
if "author" in attributes: # pragma no branch
|
| 344 |
+
self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"])
|
| 345 |
+
if "comments_url" in attributes: # pragma no branch
|
| 346 |
+
self._comments_url = self._makeStringAttribute(attributes["comments_url"])
|
| 347 |
+
if "commit" in attributes: # pragma no branch
|
| 348 |
+
self._commit = self._makeClassAttribute(github.GitCommit.GitCommit, attributes["commit"])
|
| 349 |
+
if "committer" in attributes: # pragma no branch
|
| 350 |
+
self._committer = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["committer"])
|
| 351 |
+
if "files" in attributes: # pragma no branch
|
| 352 |
+
self._files = self._makeListOfClassesAttribute(github.File.File, attributes["files"])
|
| 353 |
+
if "html_url" in attributes: # pragma no branch
|
| 354 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 355 |
+
if "node_id" in attributes: # pragma no branch
|
| 356 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 357 |
+
if "parents" in attributes: # pragma no branch
|
| 358 |
+
self._parents = self._makeListOfClassesAttribute(Commit, attributes["parents"])
|
| 359 |
+
if "repository" in attributes: # pragma no branch
|
| 360 |
+
self._repository = self._makeClassAttribute(github.Repository.Repository, attributes["repository"])
|
| 361 |
+
if "score" in attributes: # pragma no branch
|
| 362 |
+
self._score = self._makeFloatAttribute(attributes["score"])
|
| 363 |
+
if "sha" in attributes: # pragma no branch
|
| 364 |
+
self._sha = self._makeStringAttribute(attributes["sha"])
|
| 365 |
+
if "stats" in attributes: # pragma no branch
|
| 366 |
+
self._stats = self._makeClassAttribute(github.CommitStats.CommitStats, attributes["stats"])
|
| 367 |
+
if "text_matches" in attributes: # pragma no branch
|
| 368 |
+
self._text_matches = self._makeDictAttribute(attributes["text_matches"])
|
| 369 |
+
if "url" in attributes: # pragma no branch
|
| 370 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/CommitCombinedStatus.py
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 John Eskew <jeskew@edx.org> #
|
| 10 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 11 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 14 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 15 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 23 |
+
# #
|
| 24 |
+
# This file is part of PyGithub. #
|
| 25 |
+
# http://pygithub.readthedocs.io/ #
|
| 26 |
+
# #
|
| 27 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 28 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 29 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 30 |
+
# any later version. #
|
| 31 |
+
# #
|
| 32 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 33 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 34 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 35 |
+
# details. #
|
| 36 |
+
# #
|
| 37 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 38 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 39 |
+
# #
|
| 40 |
+
################################################################################
|
| 41 |
+
|
| 42 |
+
from __future__ import annotations
|
| 43 |
+
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.CommitStatus
|
| 47 |
+
import github.Repository
|
| 48 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class CommitCombinedStatus(NonCompletableGithubObject):
|
| 52 |
+
"""
|
| 53 |
+
This class represents CommitCombinedStatuses.
|
| 54 |
+
|
| 55 |
+
The reference can be found here
|
| 56 |
+
https://docs.github.com/en/rest/reference/repos#statuses
|
| 57 |
+
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
def _initAttributes(self) -> None:
|
| 61 |
+
self._commit_url: Attribute[str] = NotSet
|
| 62 |
+
self._repository: Attribute[github.Repository.Repository] = NotSet
|
| 63 |
+
self._sha: Attribute[str] = NotSet
|
| 64 |
+
self._state: Attribute[str] = NotSet
|
| 65 |
+
self._statuses: Attribute[list[github.CommitStatus.CommitStatus]] = NotSet
|
| 66 |
+
self._total_count: Attribute[int] = NotSet
|
| 67 |
+
self._url: Attribute[str] = NotSet
|
| 68 |
+
|
| 69 |
+
def __repr__(self) -> str:
|
| 70 |
+
return self.get__repr__({"sha": self._sha.value, "state": self._state.value})
|
| 71 |
+
|
| 72 |
+
@property
|
| 73 |
+
def commit_url(self) -> str:
|
| 74 |
+
return self._commit_url.value
|
| 75 |
+
|
| 76 |
+
@property
|
| 77 |
+
def repository(self) -> github.Repository.Repository:
|
| 78 |
+
return self._repository.value
|
| 79 |
+
|
| 80 |
+
@property
|
| 81 |
+
def sha(self) -> str:
|
| 82 |
+
return self._sha.value
|
| 83 |
+
|
| 84 |
+
@property
|
| 85 |
+
def state(self) -> str:
|
| 86 |
+
return self._state.value
|
| 87 |
+
|
| 88 |
+
@property
|
| 89 |
+
def statuses(self) -> list[github.CommitStatus.CommitStatus]:
|
| 90 |
+
return self._statuses.value
|
| 91 |
+
|
| 92 |
+
@property
|
| 93 |
+
def total_count(self) -> int:
|
| 94 |
+
return self._total_count.value
|
| 95 |
+
|
| 96 |
+
@property
|
| 97 |
+
def url(self) -> str:
|
| 98 |
+
return self._url.value
|
| 99 |
+
|
| 100 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 101 |
+
if "commit_url" in attributes: # pragma no branch
|
| 102 |
+
self._commit_url = self._makeStringAttribute(attributes["commit_url"])
|
| 103 |
+
if "repository" in attributes: # pragma no branch
|
| 104 |
+
self._repository = self._makeClassAttribute(github.Repository.Repository, attributes["repository"])
|
| 105 |
+
if "sha" in attributes: # pragma no branch
|
| 106 |
+
self._sha = self._makeStringAttribute(attributes["sha"])
|
| 107 |
+
if "state" in attributes: # pragma no branch
|
| 108 |
+
self._state = self._makeStringAttribute(attributes["state"])
|
| 109 |
+
if "statuses" in attributes: # pragma no branch
|
| 110 |
+
self._statuses = self._makeListOfClassesAttribute(github.CommitStatus.CommitStatus, attributes["statuses"])
|
| 111 |
+
if "total_count" in attributes: # pragma no branch
|
| 112 |
+
self._total_count = self._makeIntAttribute(attributes["total_count"])
|
| 113 |
+
if "url" in attributes: # pragma no branch
|
| 114 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/CommitComment.py
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2017 Nicolas Agustín Torres <nicolastrres@gmail.com> #
|
| 11 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2018 per1234 <accounts@perglass.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2020 Huan-Cheng Chang <changhc84@gmail.com> #
|
| 17 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 18 |
+
# Copyright 2021 Mark Walker <mark.walker@realbuzz.com> #
|
| 19 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 20 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 23 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 24 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 25 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 26 |
+
# #
|
| 27 |
+
# This file is part of PyGithub. #
|
| 28 |
+
# http://pygithub.readthedocs.io/ #
|
| 29 |
+
# #
|
| 30 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 31 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 32 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 33 |
+
# any later version. #
|
| 34 |
+
# #
|
| 35 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 36 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 37 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 38 |
+
# details. #
|
| 39 |
+
# #
|
| 40 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 41 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 42 |
+
# #
|
| 43 |
+
################################################################################
|
| 44 |
+
|
| 45 |
+
from __future__ import annotations
|
| 46 |
+
|
| 47 |
+
from datetime import datetime
|
| 48 |
+
from typing import TYPE_CHECKING, Any
|
| 49 |
+
|
| 50 |
+
import github.GithubObject
|
| 51 |
+
import github.NamedUser
|
| 52 |
+
from github import Consts
|
| 53 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 54 |
+
from github.PaginatedList import PaginatedList
|
| 55 |
+
|
| 56 |
+
if TYPE_CHECKING:
|
| 57 |
+
from github.Reaction import Reaction
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
class CommitComment(CompletableGithubObject):
|
| 61 |
+
"""
|
| 62 |
+
This class represents CommitComments.
|
| 63 |
+
|
| 64 |
+
The reference can be found here
|
| 65 |
+
https://docs.github.com/en/rest/reference/repos#comments
|
| 66 |
+
|
| 67 |
+
The OpenAPI schema can be found at
|
| 68 |
+
- /components/schemas/commit-comment
|
| 69 |
+
|
| 70 |
+
"""
|
| 71 |
+
|
| 72 |
+
def _initAttributes(self) -> None:
|
| 73 |
+
self._author_association: Attribute[str] = NotSet
|
| 74 |
+
self._body: Attribute[str] = NotSet
|
| 75 |
+
self._commit_id: Attribute[str] = NotSet
|
| 76 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 77 |
+
self._html_url: Attribute[str] = NotSet
|
| 78 |
+
self._id: Attribute[int] = NotSet
|
| 79 |
+
self._line: Attribute[int] = NotSet
|
| 80 |
+
self._node_id: Attribute[str] = NotSet
|
| 81 |
+
self._path: Attribute[str] = NotSet
|
| 82 |
+
self._position: Attribute[int] = NotSet
|
| 83 |
+
self._reactions: Attribute[dict[str, Any]] = NotSet
|
| 84 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 85 |
+
self._url: Attribute[str] = NotSet
|
| 86 |
+
self._user: Attribute[github.NamedUser.NamedUser] = NotSet
|
| 87 |
+
|
| 88 |
+
def __repr__(self) -> str:
|
| 89 |
+
return self.get__repr__({"id": self._id.value, "user": self.user})
|
| 90 |
+
|
| 91 |
+
@property
|
| 92 |
+
def author_association(self) -> str:
|
| 93 |
+
self._completeIfNotSet(self._author_association)
|
| 94 |
+
return self._author_association.value
|
| 95 |
+
|
| 96 |
+
@property
|
| 97 |
+
def body(self) -> str:
|
| 98 |
+
self._completeIfNotSet(self._body)
|
| 99 |
+
return self._body.value
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def commit_id(self) -> str:
|
| 103 |
+
self._completeIfNotSet(self._commit_id)
|
| 104 |
+
return self._commit_id.value
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def created_at(self) -> datetime:
|
| 108 |
+
self._completeIfNotSet(self._created_at)
|
| 109 |
+
return self._created_at.value
|
| 110 |
+
|
| 111 |
+
@property
|
| 112 |
+
def html_url(self) -> str:
|
| 113 |
+
self._completeIfNotSet(self._html_url)
|
| 114 |
+
return self._html_url.value
|
| 115 |
+
|
| 116 |
+
@property
|
| 117 |
+
def id(self) -> int:
|
| 118 |
+
self._completeIfNotSet(self._id)
|
| 119 |
+
return self._id.value
|
| 120 |
+
|
| 121 |
+
@property
|
| 122 |
+
def line(self) -> int:
|
| 123 |
+
self._completeIfNotSet(self._line)
|
| 124 |
+
return self._line.value
|
| 125 |
+
|
| 126 |
+
@property
|
| 127 |
+
def node_id(self) -> str:
|
| 128 |
+
self._completeIfNotSet(self._node_id)
|
| 129 |
+
return self._node_id.value
|
| 130 |
+
|
| 131 |
+
@property
|
| 132 |
+
def path(self) -> str:
|
| 133 |
+
self._completeIfNotSet(self._path)
|
| 134 |
+
return self._path.value
|
| 135 |
+
|
| 136 |
+
@property
|
| 137 |
+
def position(self) -> int:
|
| 138 |
+
self._completeIfNotSet(self._position)
|
| 139 |
+
return self._position.value
|
| 140 |
+
|
| 141 |
+
@property
|
| 142 |
+
def reactions(self) -> dict[str, Any]:
|
| 143 |
+
self._completeIfNotSet(self._reactions)
|
| 144 |
+
return self._reactions.value
|
| 145 |
+
|
| 146 |
+
@property
|
| 147 |
+
def updated_at(self) -> datetime:
|
| 148 |
+
self._completeIfNotSet(self._updated_at)
|
| 149 |
+
return self._updated_at.value
|
| 150 |
+
|
| 151 |
+
@property
|
| 152 |
+
def url(self) -> str:
|
| 153 |
+
self._completeIfNotSet(self._url)
|
| 154 |
+
return self._url.value
|
| 155 |
+
|
| 156 |
+
@property
|
| 157 |
+
def user(self) -> github.NamedUser.NamedUser:
|
| 158 |
+
self._completeIfNotSet(self._user)
|
| 159 |
+
return self._user.value
|
| 160 |
+
|
| 161 |
+
def delete(self) -> None:
|
| 162 |
+
"""
|
| 163 |
+
:calls: `DELETE /repos/{owner}/{repo}/comments/{id} <https://docs.github.com/en/rest/reference/repos#comments>`_
|
| 164 |
+
:rtype: None
|
| 165 |
+
"""
|
| 166 |
+
headers, data = self._requester.requestJsonAndCheck("DELETE", self.url)
|
| 167 |
+
|
| 168 |
+
def edit(self, body: str) -> None:
|
| 169 |
+
"""
|
| 170 |
+
:calls: `PATCH /repos/{owner}/{repo}/comments/{id} <https://docs.github.com/en/rest/reference/repos#comments>`_
|
| 171 |
+
"""
|
| 172 |
+
assert isinstance(body, str), body
|
| 173 |
+
post_parameters = {
|
| 174 |
+
"body": body,
|
| 175 |
+
}
|
| 176 |
+
headers, data = self._requester.requestJsonAndCheck("PATCH", self.url, input=post_parameters)
|
| 177 |
+
self._useAttributes(data)
|
| 178 |
+
|
| 179 |
+
def get_reactions(self) -> PaginatedList[Reaction]:
|
| 180 |
+
"""
|
| 181 |
+
:calls: `GET /repos/{owner}/{repo}/comments/{id}/reactions
|
| 182 |
+
<https://docs.github.com/en/rest/reference/reactions#list-reactions-for-a-commit-comment>`_
|
| 183 |
+
:return: :class: :class:`github.PaginatedList.PaginatedList` of :class:`github.Reaction.Reaction`
|
| 184 |
+
"""
|
| 185 |
+
return PaginatedList(
|
| 186 |
+
github.Reaction.Reaction,
|
| 187 |
+
self._requester,
|
| 188 |
+
f"{self.url}/reactions",
|
| 189 |
+
None,
|
| 190 |
+
headers={"Accept": Consts.mediaTypeReactionsPreview},
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
+
def create_reaction(self, reaction_type: str) -> Reaction:
|
| 194 |
+
"""
|
| 195 |
+
:calls: `POST /repos/{owner}/{repo}/comments/{id}/reactions
|
| 196 |
+
<https://docs.github.com/en/rest/reference/reactions#create-reaction-for-a-commit-comment>`_
|
| 197 |
+
"""
|
| 198 |
+
assert isinstance(reaction_type, str), reaction_type
|
| 199 |
+
post_parameters = {
|
| 200 |
+
"content": reaction_type,
|
| 201 |
+
}
|
| 202 |
+
headers, data = self._requester.requestJsonAndCheck(
|
| 203 |
+
"POST",
|
| 204 |
+
f"{self.url}/reactions",
|
| 205 |
+
input=post_parameters,
|
| 206 |
+
headers={"Accept": Consts.mediaTypeReactionsPreview},
|
| 207 |
+
)
|
| 208 |
+
return github.Reaction.Reaction(self._requester, headers, data, completed=True)
|
| 209 |
+
|
| 210 |
+
def delete_reaction(self, reaction_id: int) -> bool:
|
| 211 |
+
"""
|
| 212 |
+
:calls: `DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}
|
| 213 |
+
<https://docs.github.com/en/rest/reference/reactions#delete-a-commit-comment-reaction>`_
|
| 214 |
+
:param reaction_id: integer
|
| 215 |
+
:rtype: bool
|
| 216 |
+
"""
|
| 217 |
+
assert isinstance(reaction_id, int), reaction_id
|
| 218 |
+
status, _, _ = self._requester.requestJson(
|
| 219 |
+
"DELETE",
|
| 220 |
+
f"{self.url}/reactions/{reaction_id}",
|
| 221 |
+
headers={"Accept": Consts.mediaTypeReactionsPreview},
|
| 222 |
+
)
|
| 223 |
+
return status == 204
|
| 224 |
+
|
| 225 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 226 |
+
if "author_association" in attributes: # pragma no branch
|
| 227 |
+
self._author_association = self._makeStringAttribute(attributes["author_association"])
|
| 228 |
+
if "body" in attributes: # pragma no branch
|
| 229 |
+
self._body = self._makeStringAttribute(attributes["body"])
|
| 230 |
+
if "commit_id" in attributes: # pragma no branch
|
| 231 |
+
self._commit_id = self._makeStringAttribute(attributes["commit_id"])
|
| 232 |
+
if "created_at" in attributes: # pragma no branch
|
| 233 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 234 |
+
if "html_url" in attributes: # pragma no branch
|
| 235 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 236 |
+
if "id" in attributes: # pragma no branch
|
| 237 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 238 |
+
if "line" in attributes: # pragma no branch
|
| 239 |
+
self._line = self._makeIntAttribute(attributes["line"])
|
| 240 |
+
if "node_id" in attributes: # pragma no branch
|
| 241 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 242 |
+
if "path" in attributes: # pragma no branch
|
| 243 |
+
self._path = self._makeStringAttribute(attributes["path"])
|
| 244 |
+
if "position" in attributes: # pragma no branch
|
| 245 |
+
self._position = self._makeIntAttribute(attributes["position"])
|
| 246 |
+
if "reactions" in attributes: # pragma no branch
|
| 247 |
+
self._reactions = self._makeDictAttribute(attributes["reactions"])
|
| 248 |
+
if "updated_at" in attributes: # pragma no branch
|
| 249 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 250 |
+
if "url" in attributes: # pragma no branch
|
| 251 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
| 252 |
+
if "user" in attributes: # pragma no branch
|
| 253 |
+
self._user = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["user"])
|
venv/lib/python3.10/site-packages/github/CommitStats.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 9 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 10 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 12 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 14 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 15 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 16 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 17 |
+
# #
|
| 18 |
+
# This file is part of PyGithub. #
|
| 19 |
+
# http://pygithub.readthedocs.io/ #
|
| 20 |
+
# #
|
| 21 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 22 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 23 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 24 |
+
# any later version. #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 27 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 28 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 29 |
+
# details. #
|
| 30 |
+
# #
|
| 31 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 32 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 33 |
+
# #
|
| 34 |
+
################################################################################
|
| 35 |
+
|
| 36 |
+
from typing import Any, Dict
|
| 37 |
+
|
| 38 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class CommitStats(NonCompletableGithubObject):
|
| 42 |
+
"""
|
| 43 |
+
This class represents CommitStats.
|
| 44 |
+
|
| 45 |
+
The OpenAPI schema can be found at
|
| 46 |
+
- /components/schemas/commit/properties/stats
|
| 47 |
+
- /components/schemas/gist-history/properties/change_status
|
| 48 |
+
|
| 49 |
+
"""
|
| 50 |
+
|
| 51 |
+
def _initAttributes(self) -> None:
|
| 52 |
+
self._additions: Attribute[int] = NotSet
|
| 53 |
+
self._deletions: Attribute[int] = NotSet
|
| 54 |
+
self._total: Attribute[int] = NotSet
|
| 55 |
+
|
| 56 |
+
@property
|
| 57 |
+
def additions(self) -> int:
|
| 58 |
+
return self._additions.value
|
| 59 |
+
|
| 60 |
+
@property
|
| 61 |
+
def deletions(self) -> int:
|
| 62 |
+
return self._deletions.value
|
| 63 |
+
|
| 64 |
+
@property
|
| 65 |
+
def total(self) -> int:
|
| 66 |
+
return self._total.value
|
| 67 |
+
|
| 68 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 69 |
+
if "additions" in attributes: # pragma no branch
|
| 70 |
+
self._additions = self._makeIntAttribute(attributes["additions"])
|
| 71 |
+
if "deletions" in attributes: # pragma no branch
|
| 72 |
+
self._deletions = self._makeIntAttribute(attributes["deletions"])
|
| 73 |
+
if "total" in attributes: # pragma no branch
|
| 74 |
+
self._total = self._makeIntAttribute(attributes["total"])
|
venv/lib/python3.10/site-packages/github/CommitStatus.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2015 Matt Babineau <mbabineau@dataxu.com> #
|
| 9 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 10 |
+
# Copyright 2016 Martijn Koster <mak-github@greenhills.co.uk> #
|
| 11 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 12 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 18 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 19 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 20 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 21 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
from __future__ import annotations
|
| 42 |
+
|
| 43 |
+
from datetime import datetime
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.GithubObject
|
| 47 |
+
import github.NamedUser
|
| 48 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class CommitStatus(NonCompletableGithubObject):
|
| 52 |
+
"""
|
| 53 |
+
This class represents CommitStatuses.The reference can be found here https://docs.github.com/en/rest/reference/repos#statuses
|
| 54 |
+
|
| 55 |
+
The OpenAPI schema can be found at
|
| 56 |
+
- /components/schemas/status
|
| 57 |
+
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
def _initAttributes(self) -> None:
|
| 61 |
+
self._avatar_url: Attribute[str] = NotSet
|
| 62 |
+
self._context: Attribute[str] = NotSet
|
| 63 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 64 |
+
self._creator: Attribute[github.NamedUser.NamedUser] = NotSet
|
| 65 |
+
self._description: Attribute[str] = NotSet
|
| 66 |
+
self._id: Attribute[int] = NotSet
|
| 67 |
+
self._node_id: Attribute[str] = NotSet
|
| 68 |
+
self._state: Attribute[str] = NotSet
|
| 69 |
+
self._target_url: Attribute[str] = NotSet
|
| 70 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 71 |
+
self._url: Attribute[str] = NotSet
|
| 72 |
+
|
| 73 |
+
def __repr__(self) -> str:
|
| 74 |
+
return self.get__repr__(
|
| 75 |
+
{
|
| 76 |
+
"id": self._id.value,
|
| 77 |
+
"state": self._state.value,
|
| 78 |
+
"context": self._context.value,
|
| 79 |
+
}
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def avatar_url(self) -> str:
|
| 84 |
+
return self._avatar_url.value
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def context(self) -> str:
|
| 88 |
+
return self._context.value
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def created_at(self) -> datetime:
|
| 92 |
+
return self._created_at.value
|
| 93 |
+
|
| 94 |
+
@property
|
| 95 |
+
def creator(self) -> github.NamedUser.NamedUser:
|
| 96 |
+
return self._creator.value
|
| 97 |
+
|
| 98 |
+
@property
|
| 99 |
+
def description(self) -> str:
|
| 100 |
+
return self._description.value
|
| 101 |
+
|
| 102 |
+
@property
|
| 103 |
+
def id(self) -> int:
|
| 104 |
+
return self._id.value
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def node_id(self) -> str:
|
| 108 |
+
return self._node_id.value
|
| 109 |
+
|
| 110 |
+
@property
|
| 111 |
+
def state(self) -> str:
|
| 112 |
+
return self._state.value
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
def target_url(self) -> str:
|
| 116 |
+
return self._target_url.value
|
| 117 |
+
|
| 118 |
+
@property
|
| 119 |
+
def updated_at(self) -> datetime:
|
| 120 |
+
return self._updated_at.value
|
| 121 |
+
|
| 122 |
+
@property
|
| 123 |
+
def url(self) -> str:
|
| 124 |
+
return self._url.value
|
| 125 |
+
|
| 126 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 127 |
+
if "avatar_url" in attributes: # pragma no branch
|
| 128 |
+
self._avatar_url = self._makeStringAttribute(attributes["avatar_url"])
|
| 129 |
+
if "context" in attributes: # pragma no branch
|
| 130 |
+
self._context = self._makeStringAttribute(attributes["context"])
|
| 131 |
+
if "created_at" in attributes: # pragma no branch
|
| 132 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 133 |
+
if "creator" in attributes: # pragma no branch
|
| 134 |
+
self._creator = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["creator"])
|
| 135 |
+
if "description" in attributes: # pragma no branch
|
| 136 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 137 |
+
if "id" in attributes: # pragma no branch
|
| 138 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 139 |
+
if "node_id" in attributes: # pragma no branch
|
| 140 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 141 |
+
if "state" in attributes: # pragma no branch
|
| 142 |
+
self._state = self._makeStringAttribute(attributes["state"])
|
| 143 |
+
if "target_url" in attributes: # pragma no branch
|
| 144 |
+
self._target_url = self._makeStringAttribute(attributes["target_url"])
|
| 145 |
+
if "updated_at" in attributes: # pragma no branch
|
| 146 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 147 |
+
if "url" in attributes: # pragma no branch
|
| 148 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/Comparison.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 9 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 10 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 12 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 14 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 15 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 16 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 17 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# #
|
| 20 |
+
# This file is part of PyGithub. #
|
| 21 |
+
# http://pygithub.readthedocs.io/ #
|
| 22 |
+
# #
|
| 23 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 24 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 25 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 26 |
+
# any later version. #
|
| 27 |
+
# #
|
| 28 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 29 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 30 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 31 |
+
# details. #
|
| 32 |
+
# #
|
| 33 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 34 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 35 |
+
# #
|
| 36 |
+
################################################################################
|
| 37 |
+
|
| 38 |
+
from __future__ import annotations
|
| 39 |
+
|
| 40 |
+
from typing import Any
|
| 41 |
+
|
| 42 |
+
import github.Commit
|
| 43 |
+
import github.File
|
| 44 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 45 |
+
from github.PaginatedList import PaginatedList
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
class Comparison(CompletableGithubObject):
|
| 49 |
+
"""
|
| 50 |
+
This class represents Comparisons.
|
| 51 |
+
"""
|
| 52 |
+
|
| 53 |
+
def _initAttributes(self) -> None:
|
| 54 |
+
self._ahead_by: Attribute[int] = NotSet
|
| 55 |
+
self._base_commit: Attribute[github.Commit.Commit] = NotSet
|
| 56 |
+
self._behind_by: Attribute[int] = NotSet
|
| 57 |
+
self._diff_url: Attribute[str] = NotSet
|
| 58 |
+
self._files: Attribute[list[github.File.File]] = NotSet
|
| 59 |
+
self._html_url: Attribute[str] = NotSet
|
| 60 |
+
self._merge_base_commit: Attribute[github.Commit.Commit] = NotSet
|
| 61 |
+
self._patch_url: Attribute[str] = NotSet
|
| 62 |
+
self._permalink_url: Attribute[str] = NotSet
|
| 63 |
+
self._status: Attribute[str] = NotSet
|
| 64 |
+
self._total_commits: Attribute[int] = NotSet
|
| 65 |
+
self._url: Attribute[str] = NotSet
|
| 66 |
+
|
| 67 |
+
def __repr__(self) -> str:
|
| 68 |
+
return self.get__repr__({"url": self._url.value})
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def ahead_by(self) -> int:
|
| 72 |
+
self._completeIfNotSet(self._ahead_by)
|
| 73 |
+
return self._ahead_by.value
|
| 74 |
+
|
| 75 |
+
@property
|
| 76 |
+
def base_commit(self) -> github.Commit.Commit:
|
| 77 |
+
self._completeIfNotSet(self._base_commit)
|
| 78 |
+
return self._base_commit.value
|
| 79 |
+
|
| 80 |
+
@property
|
| 81 |
+
def behind_by(self) -> int:
|
| 82 |
+
self._completeIfNotSet(self._behind_by)
|
| 83 |
+
return self._behind_by.value
|
| 84 |
+
|
| 85 |
+
# This should be a method, but this used to be a property and cannot be changed without breaking user code
|
| 86 |
+
# TODO: remove @property on version 3
|
| 87 |
+
@property
|
| 88 |
+
def commits(self) -> PaginatedList[github.Commit.Commit]:
|
| 89 |
+
return PaginatedList(
|
| 90 |
+
github.Commit.Commit,
|
| 91 |
+
self._requester,
|
| 92 |
+
self.url,
|
| 93 |
+
{},
|
| 94 |
+
headers=None,
|
| 95 |
+
list_item="commits",
|
| 96 |
+
total_count_item="total_commits",
|
| 97 |
+
firstData=self.raw_data,
|
| 98 |
+
firstHeaders=self.raw_headers,
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def diff_url(self) -> str:
|
| 103 |
+
self._completeIfNotSet(self._diff_url)
|
| 104 |
+
return self._diff_url.value
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def files(self) -> list[github.File.File]:
|
| 108 |
+
self._completeIfNotSet(self._files)
|
| 109 |
+
return self._files.value
|
| 110 |
+
|
| 111 |
+
@property
|
| 112 |
+
def html_url(self) -> str:
|
| 113 |
+
self._completeIfNotSet(self._html_url)
|
| 114 |
+
return self._html_url.value
|
| 115 |
+
|
| 116 |
+
@property
|
| 117 |
+
def merge_base_commit(self) -> github.Commit.Commit:
|
| 118 |
+
self._completeIfNotSet(self._merge_base_commit)
|
| 119 |
+
return self._merge_base_commit.value
|
| 120 |
+
|
| 121 |
+
@property
|
| 122 |
+
def patch_url(self) -> str:
|
| 123 |
+
self._completeIfNotSet(self._patch_url)
|
| 124 |
+
return self._patch_url.value
|
| 125 |
+
|
| 126 |
+
@property
|
| 127 |
+
def permalink_url(self) -> str:
|
| 128 |
+
self._completeIfNotSet(self._permalink_url)
|
| 129 |
+
return self._permalink_url.value
|
| 130 |
+
|
| 131 |
+
@property
|
| 132 |
+
def status(self) -> str:
|
| 133 |
+
self._completeIfNotSet(self._status)
|
| 134 |
+
return self._status.value
|
| 135 |
+
|
| 136 |
+
@property
|
| 137 |
+
def total_commits(self) -> int:
|
| 138 |
+
self._completeIfNotSet(self._total_commits)
|
| 139 |
+
return self._total_commits.value
|
| 140 |
+
|
| 141 |
+
@property
|
| 142 |
+
def url(self) -> str:
|
| 143 |
+
self._completeIfNotSet(self._url)
|
| 144 |
+
return self._url.value
|
| 145 |
+
|
| 146 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 147 |
+
if "ahead_by" in attributes: # pragma no branch
|
| 148 |
+
self._ahead_by = self._makeIntAttribute(attributes["ahead_by"])
|
| 149 |
+
if "base_commit" in attributes: # pragma no branch
|
| 150 |
+
self._base_commit = self._makeClassAttribute(github.Commit.Commit, attributes["base_commit"])
|
| 151 |
+
if "behind_by" in attributes: # pragma no branch
|
| 152 |
+
self._behind_by = self._makeIntAttribute(attributes["behind_by"])
|
| 153 |
+
if "diff_url" in attributes: # pragma no branch
|
| 154 |
+
self._diff_url = self._makeStringAttribute(attributes["diff_url"])
|
| 155 |
+
if "files" in attributes: # pragma no branch
|
| 156 |
+
self._files = self._makeListOfClassesAttribute(github.File.File, attributes["files"])
|
| 157 |
+
if "html_url" in attributes: # pragma no branch
|
| 158 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 159 |
+
if "merge_base_commit" in attributes: # pragma no branch
|
| 160 |
+
self._merge_base_commit = self._makeClassAttribute(github.Commit.Commit, attributes["merge_base_commit"])
|
| 161 |
+
if "patch_url" in attributes: # pragma no branch
|
| 162 |
+
self._patch_url = self._makeStringAttribute(attributes["patch_url"])
|
| 163 |
+
if "permalink_url" in attributes: # pragma no branch
|
| 164 |
+
self._permalink_url = self._makeStringAttribute(attributes["permalink_url"])
|
| 165 |
+
if "status" in attributes: # pragma no branch
|
| 166 |
+
self._status = self._makeStringAttribute(attributes["status"])
|
| 167 |
+
if "total_commits" in attributes: # pragma no branch
|
| 168 |
+
self._total_commits = self._makeIntAttribute(attributes["total_commits"])
|
| 169 |
+
if "url" in attributes: # pragma no branch
|
| 170 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/Consts.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jakub Wilk <jwilk@jwilk.net> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Aaron L. Levine <allevin@sandia.gov> #
|
| 11 |
+
# Copyright 2018 Alice GIRARD <bouhahah@gmail.com> #
|
| 12 |
+
# Copyright 2018 Maarten Fonville <mfonville@users.noreply.github.com> #
|
| 13 |
+
# Copyright 2018 Shubham Singh <41840111+singh811@users.noreply.github.com> #
|
| 14 |
+
# Copyright 2018 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2018 Yossarian King <yggy@blackbirdinteractive.com> #
|
| 17 |
+
# Copyright 2018 h.shi <10385628+AnYeMoWang@users.noreply.github.com> #
|
| 18 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 19 |
+
# Copyright 2019 Adam Baratz <adam.baratz@gmail.com> #
|
| 20 |
+
# Copyright 2019 Nick Campbell <nicholas.j.campbell@gmail.com> #
|
| 21 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 22 |
+
# Copyright 2019 Tim Gates <tim.gates@iress.com> #
|
| 23 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 24 |
+
# Copyright 2019 Will Li <cuichen.li94@gmail.com> #
|
| 25 |
+
# Copyright 2020 Adrian Bridgett <58699309+tl-adrian-bridgett@users.noreply.github.com>#
|
| 26 |
+
# Copyright 2020 Anuj Bansal <bansalanuj1996@gmail.com> #
|
| 27 |
+
# Copyright 2020 Colby Gallup <colbygallup@gmail.com> #
|
| 28 |
+
# Copyright 2020 Pascal Hofmann <mail@pascalhofmann.de> #
|
| 29 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 30 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 31 |
+
# Copyright 2021 Tanner <51724788+lightningboltemoji@users.noreply.github.com> #
|
| 32 |
+
# Copyright 2022 KimSia Sim <245021+simkimsia@users.noreply.github.com> #
|
| 33 |
+
# Copyright 2023 Denis Blanchette <dblanchette@coveo.com> #
|
| 34 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 35 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 36 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 37 |
+
# #
|
| 38 |
+
# This file is part of PyGithub. #
|
| 39 |
+
# http://pygithub.readthedocs.io/ #
|
| 40 |
+
# #
|
| 41 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 42 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 43 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 44 |
+
# any later version. #
|
| 45 |
+
# #
|
| 46 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 47 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 48 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 49 |
+
# details. #
|
| 50 |
+
# #
|
| 51 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 52 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 53 |
+
# #
|
| 54 |
+
################################################################################
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
REQ_IF_NONE_MATCH = "If-None-Match"
|
| 58 |
+
REQ_IF_MODIFIED_SINCE = "If-Modified-Since"
|
| 59 |
+
PROCESSING_202_WAIT_TIME = 2
|
| 60 |
+
|
| 61 |
+
# ##############################################################################
|
| 62 |
+
# Response Header #
|
| 63 |
+
# (Lower Case) #
|
| 64 |
+
# ##############################################################################
|
| 65 |
+
RES_ETAG = "etag"
|
| 66 |
+
RES_LAST_MODIFIED = "last-modified"
|
| 67 |
+
|
| 68 |
+
# Inspired by https://github.com/google/go-github
|
| 69 |
+
|
| 70 |
+
# Headers
|
| 71 |
+
|
| 72 |
+
headerRateLimit = "x-ratelimit-limit"
|
| 73 |
+
headerRateRemaining = "x-ratelimit-remaining"
|
| 74 |
+
headerRateReset = "x-ratelimit-reset"
|
| 75 |
+
headerOAuthScopes = "x-oauth-scopes"
|
| 76 |
+
headerOTP = "x-github-otp"
|
| 77 |
+
|
| 78 |
+
defaultMediaType = "application/octet-stream"
|
| 79 |
+
|
| 80 |
+
# Custom media type for preview API
|
| 81 |
+
|
| 82 |
+
# https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
|
| 83 |
+
mediaTypeStarringPreview = "application/vnd.github.v3.star+json"
|
| 84 |
+
|
| 85 |
+
# https://developer.github.com/changes/2016-02-19-source-import-preview-api/
|
| 86 |
+
mediaTypeImportPreview = "application/vnd.github.barred-rock-preview"
|
| 87 |
+
|
| 88 |
+
# https://developer.github.com/changes/2016-05-12-reactions-api-preview/
|
| 89 |
+
mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview"
|
| 90 |
+
|
| 91 |
+
# https://developer.github.com/changes/2016-09-14-Integrations-Early-Access/
|
| 92 |
+
mediaTypeIntegrationPreview = "application/vnd.github.machine-man-preview+json"
|
| 93 |
+
|
| 94 |
+
# https://developer.github.com/changes/2016-09-14-projects-api/
|
| 95 |
+
mediaTypeProjectsPreview = "application/vnd.github.inertia-preview+json"
|
| 96 |
+
|
| 97 |
+
# https://developer.github.com/changes/2017-01-05-commit-search-api/
|
| 98 |
+
mediaTypeCommitSearchPreview = "application/vnd.github.cloak-preview"
|
| 99 |
+
|
| 100 |
+
# https://developer.github.com/changes/2017-02-28-user-blocking-apis-and-webhook/
|
| 101 |
+
mediaTypeBlockUsersPreview = "application/vnd.github.giant-sentry-fist-preview+json"
|
| 102 |
+
|
| 103 |
+
# https://developer.github.com/changes/2017-07-17-update-topics-on-repositories/
|
| 104 |
+
mediaTypeTopicsPreview = "application/vnd.github.mercy-preview+json"
|
| 105 |
+
|
| 106 |
+
# https://developer.github.com/changes/2018-02-22-label-description-search-preview/
|
| 107 |
+
mediaTypeLabelDescriptionSearchPreview = "application/vnd.github.symmetra-preview+json"
|
| 108 |
+
|
| 109 |
+
# https://developer.github.com/changes/2018-01-10-lock-reason-api-preview/
|
| 110 |
+
mediaTypeLockReasonPreview = "application/vnd.github.sailor-v-preview+json"
|
| 111 |
+
|
| 112 |
+
# https://developer.github.com/changes/2018-01-25-organization-invitation-api-preview/
|
| 113 |
+
mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview+json"
|
| 114 |
+
|
| 115 |
+
# https://developer.github.com/changes/2018-02-07-team-discussions-api
|
| 116 |
+
mediaTypeTeamDiscussionsPreview = "application/vnd.github.echo-preview+json"
|
| 117 |
+
|
| 118 |
+
# https://developer.github.com/changes/2018-03-16-protected-branches-required-approving-reviews/
|
| 119 |
+
mediaTypeRequireMultipleApprovingReviews = "application/vnd.github.luke-cage-preview+json"
|
| 120 |
+
|
| 121 |
+
# https://developer.github.com/changes/2018-05-24-user-migration-api/
|
| 122 |
+
mediaTypeMigrationPreview = "application/vnd.github.wyandotte-preview+json"
|
| 123 |
+
|
| 124 |
+
# https://developer.github.com/changes/2019-07-16-repository-templates-api/
|
| 125 |
+
mediaTypeTemplatesPreview = "application/vnd.github.baptiste-preview+json"
|
| 126 |
+
|
| 127 |
+
# https://docs.github.com/en/rest/reference/search#highlighting-code-search-results-1
|
| 128 |
+
highLightSearchPreview = "application/vnd.github.v3.text-match+json"
|
| 129 |
+
|
| 130 |
+
# https://developer.github.com/changes/2018-02-22-protected-branches-required-signatures/
|
| 131 |
+
signaturesProtectedBranchesPreview = "application/vnd.github.zzzax-preview+json"
|
| 132 |
+
|
| 133 |
+
# https://developer.github.com/changes/2019-04-24-vulnerability-alerts/
|
| 134 |
+
vulnerabilityAlertsPreview = "application/vnd.github.dorian-preview+json"
|
| 135 |
+
|
| 136 |
+
# https://developer.github.com/changes/2019-06-04-automated-security-fixes/
|
| 137 |
+
automatedSecurityFixes = "application/vnd.github.london-preview+json"
|
| 138 |
+
|
| 139 |
+
# https://developer.github.com/changes/2019-05-29-update-branch-api/
|
| 140 |
+
updateBranchPreview = "application/vnd.github.lydian-preview+json"
|
| 141 |
+
|
| 142 |
+
# https://developer.github.com/changes/2016-05-23-timeline-preview-api/
|
| 143 |
+
issueTimelineEventsPreview = "application/vnd.github.mockingbird-preview"
|
| 144 |
+
|
| 145 |
+
# https://docs.github.com/en/rest/reference/teams#check-if-a-team-manages-a-repository
|
| 146 |
+
teamRepositoryPermissions = "application/vnd.github.v3.repository+json"
|
| 147 |
+
|
| 148 |
+
# https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/
|
| 149 |
+
deploymentEnhancementsPreview = "application/vnd.github.ant-man-preview+json"
|
| 150 |
+
|
| 151 |
+
# https://developer.github.com/changes/2018-10-16-deployments-environments-states-and-auto-inactive-updates/
|
| 152 |
+
deploymentStatusEnhancementsPreview = "application/vnd.github.flash-preview+json"
|
| 153 |
+
|
| 154 |
+
# https://developer.github.com/changes/2019-12-03-internal-visibility-changes/
|
| 155 |
+
repoVisibilityPreview = "application/vnd.github.nebula-preview+json"
|
| 156 |
+
|
| 157 |
+
DEFAULT_BASE_URL = "https://api.github.com"
|
| 158 |
+
DEFAULT_OAUTH_URL = "https://github.com/login/oauth"
|
| 159 |
+
DEFAULT_STATUS_URL = "https://status.github.com"
|
| 160 |
+
DEFAULT_USER_AGENT = "PyGithub/Python"
|
| 161 |
+
# As of 2018-05-17, Github imposes a 10s limit for completion of API requests.
|
| 162 |
+
# Thus, the timeout should be slightly > 10s to account for network/front-end
|
| 163 |
+
# latency.
|
| 164 |
+
DEFAULT_TIMEOUT = 15
|
| 165 |
+
DEFAULT_PER_PAGE = 30
|
| 166 |
+
|
| 167 |
+
# JWT expiry in seconds. Could be set for max 600 seconds (10 minutes).
|
| 168 |
+
# https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app
|
| 169 |
+
DEFAULT_JWT_EXPIRY = 300
|
| 170 |
+
MIN_JWT_EXPIRY = 15
|
| 171 |
+
MAX_JWT_EXPIRY = 600
|
| 172 |
+
# https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#generating-a-json-web-token-jwt
|
| 173 |
+
# "The time the JWT was created. To protect against clock drift, we recommend you set this 60 seconds in the past."
|
| 174 |
+
DEFAULT_JWT_ISSUED_AT = -60
|
| 175 |
+
# https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app
|
| 176 |
+
# "Your JWT must be signed using the RS256 algorithm"
|
| 177 |
+
DEFAULT_JWT_ALGORITHM = "RS256"
|
| 178 |
+
|
| 179 |
+
# https://docs.github.com/en/rest/guides/best-practices-for-integrators?apiVersion=2022-11-28#dealing-with-secondary-rate-limits
|
| 180 |
+
DEFAULT_SECONDS_BETWEEN_REQUESTS = 0.25
|
| 181 |
+
DEFAULT_SECONDS_BETWEEN_WRITES = 1.0
|
venv/lib/python3.10/site-packages/github/ContentFile.py
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Thialfihar <thi@thialfihar.org> #
|
| 8 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 9 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 10 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 11 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2018 h.shi <10385628+AnYeMoWang@users.noreply.github.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Adam Baratz <adam.baratz@gmail.com> #
|
| 15 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 17 |
+
# Copyright 2020 Alice GIRARD <bouhahah@gmail.com> #
|
| 18 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 19 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 20 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 23 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 24 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 25 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 26 |
+
# #
|
| 27 |
+
# This file is part of PyGithub. #
|
| 28 |
+
# http://pygithub.readthedocs.io/ #
|
| 29 |
+
# #
|
| 30 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 31 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 32 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 33 |
+
# any later version. #
|
| 34 |
+
# #
|
| 35 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 36 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 37 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 38 |
+
# details. #
|
| 39 |
+
# #
|
| 40 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 41 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 42 |
+
# #
|
| 43 |
+
################################################################################
|
| 44 |
+
|
| 45 |
+
from __future__ import annotations
|
| 46 |
+
|
| 47 |
+
import base64
|
| 48 |
+
from datetime import datetime
|
| 49 |
+
from typing import TYPE_CHECKING, Any
|
| 50 |
+
|
| 51 |
+
import github.GitCommit
|
| 52 |
+
import github.GithubObject
|
| 53 |
+
import github.License
|
| 54 |
+
import github.Repository
|
| 55 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet, _ValuedAttribute
|
| 56 |
+
|
| 57 |
+
if TYPE_CHECKING:
|
| 58 |
+
from github.GitCommit import GitCommit
|
| 59 |
+
from github.License import License
|
| 60 |
+
from github.Repository import Repository
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
class ContentFile(CompletableGithubObject):
|
| 64 |
+
"""
|
| 65 |
+
This class represents ContentFiles.
|
| 66 |
+
|
| 67 |
+
The reference can be found here
|
| 68 |
+
https://docs.github.com/en/rest/reference/repos#contents
|
| 69 |
+
|
| 70 |
+
The OpenAPI schema can be found at
|
| 71 |
+
- /components/schemas/code-search-result-item
|
| 72 |
+
- /components/schemas/content-directory
|
| 73 |
+
- /components/schemas/content-file
|
| 74 |
+
- /components/schemas/content-submodule
|
| 75 |
+
- /components/schemas/content-symlink
|
| 76 |
+
- /components/schemas/file-commit
|
| 77 |
+
- /components/schemas/license-content
|
| 78 |
+
|
| 79 |
+
"""
|
| 80 |
+
|
| 81 |
+
def _initAttributes(self) -> None:
|
| 82 |
+
self.__links: Attribute[dict[str, Any]] = NotSet
|
| 83 |
+
self._commit: Attribute[GitCommit] = NotSet
|
| 84 |
+
self._content: Attribute[str] = NotSet
|
| 85 |
+
self._download_url: Attribute[str] = NotSet
|
| 86 |
+
self._encoding: Attribute[str] = NotSet
|
| 87 |
+
self._file_size: Attribute[int] = NotSet
|
| 88 |
+
self._git_url: Attribute[str] = NotSet
|
| 89 |
+
self._html_url: Attribute[str] = NotSet
|
| 90 |
+
self._language: Attribute[str] = NotSet
|
| 91 |
+
self._last_modified_at: Attribute[datetime] = NotSet
|
| 92 |
+
self._license: Attribute[License] = NotSet
|
| 93 |
+
self._line_numbers: Attribute[list[str]] = NotSet
|
| 94 |
+
self._name: Attribute[str] = NotSet
|
| 95 |
+
self._path: Attribute[str] = NotSet
|
| 96 |
+
self._repository: Attribute[Repository] = NotSet
|
| 97 |
+
self._score: Attribute[float] = NotSet
|
| 98 |
+
self._sha: Attribute[str] = NotSet
|
| 99 |
+
self._size: Attribute[int] = NotSet
|
| 100 |
+
self._submodule_git_url: Attribute[str] = NotSet
|
| 101 |
+
self._target: Attribute[str] = NotSet
|
| 102 |
+
self._text_matches: Attribute[str] = NotSet
|
| 103 |
+
self._type: Attribute[str] = NotSet
|
| 104 |
+
self._url: Attribute[str] = NotSet
|
| 105 |
+
|
| 106 |
+
def __repr__(self) -> str:
|
| 107 |
+
return self.get__repr__({"path": self._path.value})
|
| 108 |
+
|
| 109 |
+
@property
|
| 110 |
+
def _links(self) -> dict[str, Any]:
|
| 111 |
+
self._completeIfNotSet(self.__links)
|
| 112 |
+
return self.__links.value
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
def commit(self) -> GitCommit:
|
| 116 |
+
self._completeIfNotSet(self._commit)
|
| 117 |
+
return self._commit.value
|
| 118 |
+
|
| 119 |
+
@property
|
| 120 |
+
def content(self) -> str:
|
| 121 |
+
self._completeIfNotSet(self._content)
|
| 122 |
+
return self._content.value
|
| 123 |
+
|
| 124 |
+
@property
|
| 125 |
+
def decoded_content(self) -> bytes:
|
| 126 |
+
assert self.encoding == "base64", f"unsupported encoding: {self.encoding}"
|
| 127 |
+
return base64.b64decode(bytearray(self.content, "utf-8"))
|
| 128 |
+
|
| 129 |
+
@property
|
| 130 |
+
def download_url(self) -> str:
|
| 131 |
+
self._completeIfNotSet(self._download_url)
|
| 132 |
+
return self._download_url.value
|
| 133 |
+
|
| 134 |
+
@property
|
| 135 |
+
def encoding(self) -> str:
|
| 136 |
+
self._completeIfNotSet(self._encoding)
|
| 137 |
+
return self._encoding.value
|
| 138 |
+
|
| 139 |
+
@property
|
| 140 |
+
def file_size(self) -> int:
|
| 141 |
+
self._completeIfNotSet(self._file_size)
|
| 142 |
+
return self._file_size.value
|
| 143 |
+
|
| 144 |
+
@property
|
| 145 |
+
def git_url(self) -> str:
|
| 146 |
+
self._completeIfNotSet(self._git_url)
|
| 147 |
+
return self._git_url.value
|
| 148 |
+
|
| 149 |
+
@property
|
| 150 |
+
def html_url(self) -> str:
|
| 151 |
+
self._completeIfNotSet(self._html_url)
|
| 152 |
+
return self._html_url.value
|
| 153 |
+
|
| 154 |
+
@property
|
| 155 |
+
def language(self) -> str:
|
| 156 |
+
self._completeIfNotSet(self._language)
|
| 157 |
+
return self._language.value
|
| 158 |
+
|
| 159 |
+
@property
|
| 160 |
+
def last_modified_at(self) -> datetime:
|
| 161 |
+
self._completeIfNotSet(self._last_modified_at)
|
| 162 |
+
return self._last_modified_at.value
|
| 163 |
+
|
| 164 |
+
@property
|
| 165 |
+
def license(self) -> License:
|
| 166 |
+
self._completeIfNotSet(self._license)
|
| 167 |
+
return self._license.value
|
| 168 |
+
|
| 169 |
+
@property
|
| 170 |
+
def line_numbers(self) -> list[str]:
|
| 171 |
+
self._completeIfNotSet(self._line_numbers)
|
| 172 |
+
return self._line_numbers.value
|
| 173 |
+
|
| 174 |
+
@property
|
| 175 |
+
def name(self) -> str:
|
| 176 |
+
self._completeIfNotSet(self._name)
|
| 177 |
+
return self._name.value
|
| 178 |
+
|
| 179 |
+
@property
|
| 180 |
+
def path(self) -> str:
|
| 181 |
+
self._completeIfNotSet(self._path)
|
| 182 |
+
return self._path.value
|
| 183 |
+
|
| 184 |
+
@property
|
| 185 |
+
def repository(self) -> Repository:
|
| 186 |
+
if self._repository is NotSet:
|
| 187 |
+
# The repository was not set automatically, so it must be looked up by url.
|
| 188 |
+
repo_url = "/".join(self.url.split("/")[:6]) # pragma no cover (Should be covered)
|
| 189 |
+
self._repository = _ValuedAttribute(
|
| 190 |
+
github.Repository.Repository(self._requester, self._headers, {"url": repo_url}, completed=False)
|
| 191 |
+
) # pragma no cover (Should be covered)
|
| 192 |
+
return self._repository.value
|
| 193 |
+
|
| 194 |
+
@property
|
| 195 |
+
def score(self) -> float:
|
| 196 |
+
self._completeIfNotSet(self._score)
|
| 197 |
+
return self._score.value
|
| 198 |
+
|
| 199 |
+
@property
|
| 200 |
+
def sha(self) -> str:
|
| 201 |
+
self._completeIfNotSet(self._sha)
|
| 202 |
+
return self._sha.value
|
| 203 |
+
|
| 204 |
+
@property
|
| 205 |
+
def size(self) -> int:
|
| 206 |
+
self._completeIfNotSet(self._size)
|
| 207 |
+
return self._size.value
|
| 208 |
+
|
| 209 |
+
@property
|
| 210 |
+
def submodule_git_url(self) -> str:
|
| 211 |
+
self._completeIfNotSet(self._submodule_git_url)
|
| 212 |
+
return self._submodule_git_url.value
|
| 213 |
+
|
| 214 |
+
@property
|
| 215 |
+
def target(self) -> str:
|
| 216 |
+
self._completeIfNotSet(self._target)
|
| 217 |
+
return self._target.value
|
| 218 |
+
|
| 219 |
+
@property
|
| 220 |
+
def text_matches(self) -> str:
|
| 221 |
+
self._completeIfNotSet(self._text_matches)
|
| 222 |
+
return self._text_matches.value
|
| 223 |
+
|
| 224 |
+
@property
|
| 225 |
+
def type(self) -> str:
|
| 226 |
+
self._completeIfNotSet(self._type)
|
| 227 |
+
return self._type.value
|
| 228 |
+
|
| 229 |
+
@property
|
| 230 |
+
def url(self) -> str:
|
| 231 |
+
self._completeIfNotSet(self._url)
|
| 232 |
+
return self._url.value
|
| 233 |
+
|
| 234 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 235 |
+
if "_links" in attributes: # pragma no branch
|
| 236 |
+
self.__links = self._makeDictAttribute(attributes["_links"])
|
| 237 |
+
if "commit" in attributes: # pragma no branch
|
| 238 |
+
self._commit = self._makeClassAttribute(github.GitCommit.GitCommit, attributes["commit"])
|
| 239 |
+
if "content" in attributes: # pragma no branch
|
| 240 |
+
self._content = self._makeStringAttribute(attributes["content"])
|
| 241 |
+
if "download_url" in attributes: # pragma no branch
|
| 242 |
+
self._download_url = self._makeStringAttribute(attributes["download_url"])
|
| 243 |
+
if "encoding" in attributes: # pragma no branch
|
| 244 |
+
self._encoding = self._makeStringAttribute(attributes["encoding"])
|
| 245 |
+
if "file_size" in attributes: # pragma no branch
|
| 246 |
+
self._file_size = self._makeIntAttribute(attributes["file_size"])
|
| 247 |
+
if "git_url" in attributes: # pragma no branch
|
| 248 |
+
self._git_url = self._makeStringAttribute(attributes["git_url"])
|
| 249 |
+
if "html_url" in attributes: # pragma no branch
|
| 250 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 251 |
+
if "language" in attributes: # pragma no branch
|
| 252 |
+
self._language = self._makeStringAttribute(attributes["language"])
|
| 253 |
+
if "last_modified_at" in attributes: # pragma no branch
|
| 254 |
+
self._last_modified_at = self._makeDatetimeAttribute(attributes["last_modified_at"])
|
| 255 |
+
if "license" in attributes: # pragma no branch
|
| 256 |
+
self._license = self._makeClassAttribute(github.License.License, attributes["license"])
|
| 257 |
+
if "line_numbers" in attributes: # pragma no branch
|
| 258 |
+
self._line_numbers = self._makeListOfStringsAttribute(attributes["line_numbers"])
|
| 259 |
+
if "name" in attributes: # pragma no branch
|
| 260 |
+
self._name = self._makeStringAttribute(attributes["name"])
|
| 261 |
+
if "path" in attributes: # pragma no branch
|
| 262 |
+
self._path = self._makeStringAttribute(attributes["path"])
|
| 263 |
+
if "repository" in attributes: # pragma no branch
|
| 264 |
+
self._repository = self._makeClassAttribute(github.Repository.Repository, attributes["repository"])
|
| 265 |
+
if "score" in attributes: # pragma no branch
|
| 266 |
+
self._score = self._makeFloatAttribute(attributes["score"])
|
| 267 |
+
if "sha" in attributes: # pragma no branch
|
| 268 |
+
self._sha = self._makeStringAttribute(attributes["sha"])
|
| 269 |
+
if "size" in attributes: # pragma no branch
|
| 270 |
+
self._size = self._makeIntAttribute(attributes["size"])
|
| 271 |
+
if "submodule_git_url" in attributes: # pragma no branch
|
| 272 |
+
self._submodule_git_url = self._makeStringAttribute(attributes["submodule_git_url"])
|
| 273 |
+
if "target" in attributes: # pragma no branch
|
| 274 |
+
self._target = self._makeStringAttribute(attributes["target"])
|
| 275 |
+
if "text_matches" in attributes: # pragma no branch
|
| 276 |
+
self._text_matches = self._makeListOfDictsAttribute(attributes["text_matches"])
|
| 277 |
+
if "type" in attributes: # pragma no branch
|
| 278 |
+
self._type = self._makeStringAttribute(attributes["type"])
|
| 279 |
+
if "url" in attributes: # pragma no branch
|
| 280 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/Copilot.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Pasha Fateev <pasha@autokitteh.com> #
|
| 4 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 5 |
+
# #
|
| 6 |
+
# This file is part of PyGithub. #
|
| 7 |
+
# http://pygithub.readthedocs.io/ #
|
| 8 |
+
# #
|
| 9 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 10 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 11 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 12 |
+
# any later version. #
|
| 13 |
+
# #
|
| 14 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 15 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 16 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 17 |
+
# details. #
|
| 18 |
+
# #
|
| 19 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 20 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 21 |
+
# #
|
| 22 |
+
################################################################################
|
| 23 |
+
|
| 24 |
+
from __future__ import annotations
|
| 25 |
+
|
| 26 |
+
from typing import TYPE_CHECKING, Any
|
| 27 |
+
|
| 28 |
+
import github.CopilotSeat
|
| 29 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 30 |
+
from github.PaginatedList import PaginatedList
|
| 31 |
+
|
| 32 |
+
if TYPE_CHECKING:
|
| 33 |
+
from github.CopilotSeat import CopilotSeat
|
| 34 |
+
from github.Requester import Requester
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class Copilot(NonCompletableGithubObject):
|
| 38 |
+
def __init__(self, requester: Requester, org_name: str) -> None:
|
| 39 |
+
super().__init__(requester, {}, {"org_name": org_name})
|
| 40 |
+
|
| 41 |
+
def _initAttributes(self) -> None:
|
| 42 |
+
self._org_name: Attribute[str] = NotSet
|
| 43 |
+
|
| 44 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 45 |
+
if "org_name" in attributes: # pragma no branch
|
| 46 |
+
self._org_name = self._makeStringAttribute(attributes["org_name"])
|
| 47 |
+
|
| 48 |
+
def __repr__(self) -> str:
|
| 49 |
+
return self.get__repr__({"org_name": self._org_name.value if self._org_name is not NotSet else NotSet})
|
| 50 |
+
|
| 51 |
+
@property
|
| 52 |
+
def org_name(self) -> str:
|
| 53 |
+
return self._org_name.value
|
| 54 |
+
|
| 55 |
+
def get_seats(self) -> PaginatedList[CopilotSeat]:
|
| 56 |
+
"""
|
| 57 |
+
:calls: `GET /orgs/{org}/copilot/billing/seats <https://docs.github.com/en/rest/copilot/copilot-business>`_
|
| 58 |
+
"""
|
| 59 |
+
url = f"/orgs/{self._org_name.value}/copilot/billing/seats"
|
| 60 |
+
return PaginatedList(
|
| 61 |
+
github.CopilotSeat.CopilotSeat,
|
| 62 |
+
self._requester,
|
| 63 |
+
url,
|
| 64 |
+
None,
|
| 65 |
+
list_item="seats",
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
def add_seats(self, selected_usernames: list[str]) -> int:
|
| 69 |
+
"""
|
| 70 |
+
:calls: `POST /orgs/{org}/copilot/billing/selected_users <https://docs.github.com/en/rest/copilot/copilot-business>`_
|
| 71 |
+
:param selected_usernames: List of usernames to add Copilot seats for
|
| 72 |
+
:rtype: int
|
| 73 |
+
:return: Number of seats created
|
| 74 |
+
"""
|
| 75 |
+
url = f"/orgs/{self._org_name.value}/copilot/billing/selected_users"
|
| 76 |
+
_, data = self._requester.requestJsonAndCheck(
|
| 77 |
+
"POST",
|
| 78 |
+
url,
|
| 79 |
+
input={"selected_usernames": selected_usernames},
|
| 80 |
+
)
|
| 81 |
+
return data["seats_created"]
|
| 82 |
+
|
| 83 |
+
def remove_seats(self, selected_usernames: list[str]) -> int:
|
| 84 |
+
"""
|
| 85 |
+
:calls: `DELETE /orgs/{org}/copilot/billing/selected_users <https://docs.github.com/en/rest/copilot/copilot-business>`_
|
| 86 |
+
:param selected_usernames: List of usernames to remove Copilot seats for
|
| 87 |
+
:rtype: int
|
| 88 |
+
:return: Number of seats cancelled
|
| 89 |
+
"""
|
| 90 |
+
url = f"/orgs/{self._org_name.value}/copilot/billing/selected_users"
|
| 91 |
+
_, data = self._requester.requestJsonAndCheck(
|
| 92 |
+
"DELETE",
|
| 93 |
+
url,
|
| 94 |
+
input={"selected_usernames": selected_usernames},
|
| 95 |
+
)
|
| 96 |
+
return data["seats_cancelled"]
|
venv/lib/python3.10/site-packages/github/CopilotSeat.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Pasha Fateev <pasha@autokitteh.com> #
|
| 4 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 5 |
+
# #
|
| 6 |
+
# This file is part of PyGithub. #
|
| 7 |
+
# http://pygithub.readthedocs.io/ #
|
| 8 |
+
# #
|
| 9 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 10 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 11 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 12 |
+
# any later version. #
|
| 13 |
+
# #
|
| 14 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 15 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 16 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 17 |
+
# details. #
|
| 18 |
+
# #
|
| 19 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 20 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 21 |
+
# #
|
| 22 |
+
################################################################################
|
| 23 |
+
|
| 24 |
+
from __future__ import annotations
|
| 25 |
+
|
| 26 |
+
from datetime import datetime
|
| 27 |
+
from typing import Any
|
| 28 |
+
|
| 29 |
+
import github.NamedUser
|
| 30 |
+
import github.Team
|
| 31 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet, _NotSetType
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class CopilotSeat(NonCompletableGithubObject):
|
| 35 |
+
def _initAttributes(self) -> None:
|
| 36 |
+
self._created_at: Attribute[datetime] | _NotSetType = NotSet
|
| 37 |
+
self._updated_at: Attribute[datetime] | _NotSetType = NotSet
|
| 38 |
+
self._pending_cancellation_date: Attribute[datetime] | _NotSetType = NotSet
|
| 39 |
+
self._last_activity_at: Attribute[datetime] | _NotSetType = NotSet
|
| 40 |
+
self._last_activity_editor: Attribute[str] | _NotSetType = NotSet
|
| 41 |
+
self._plan_type: Attribute[str] | _NotSetType = NotSet
|
| 42 |
+
self._assignee: Attribute[github.NamedUser.NamedUser] | _NotSetType = NotSet
|
| 43 |
+
self._assigning_team: Attribute[github.Team.Team] | _NotSetType = NotSet
|
| 44 |
+
|
| 45 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 46 |
+
if "created_at" in attributes:
|
| 47 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 48 |
+
if "updated_at" in attributes:
|
| 49 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 50 |
+
if "pending_cancellation_date" in attributes:
|
| 51 |
+
self._pending_cancellation_date = self._makeDatetimeAttribute(attributes["pending_cancellation_date"])
|
| 52 |
+
if "last_activity_at" in attributes:
|
| 53 |
+
self._last_activity_at = self._makeDatetimeAttribute(attributes["last_activity_at"])
|
| 54 |
+
if "last_activity_editor" in attributes:
|
| 55 |
+
self._last_activity_editor = self._makeStringAttribute(attributes["last_activity_editor"])
|
| 56 |
+
if "plan_type" in attributes:
|
| 57 |
+
self._plan_type = self._makeStringAttribute(attributes["plan_type"])
|
| 58 |
+
if "assignee" in attributes:
|
| 59 |
+
self._assignee = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["assignee"])
|
| 60 |
+
if "assigning_team" in attributes:
|
| 61 |
+
self._assigning_team = self._makeClassAttribute(github.Team.Team, attributes["assigning_team"])
|
| 62 |
+
|
| 63 |
+
def __repr__(self) -> str:
|
| 64 |
+
return self.get__repr__({"assignee": self._assignee.value})
|
| 65 |
+
|
| 66 |
+
@property
|
| 67 |
+
def created_at(self) -> datetime:
|
| 68 |
+
return self._created_at.value
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def updated_at(self) -> datetime:
|
| 72 |
+
return self._updated_at.value
|
| 73 |
+
|
| 74 |
+
@property
|
| 75 |
+
def pending_cancellation_date(self) -> datetime:
|
| 76 |
+
return self._pending_cancellation_date.value
|
| 77 |
+
|
| 78 |
+
@property
|
| 79 |
+
def last_activity_at(self) -> datetime:
|
| 80 |
+
return self._last_activity_at.value
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def last_activity_editor(self) -> str:
|
| 84 |
+
return self._last_activity_editor.value
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def plan_type(self) -> str:
|
| 88 |
+
return self._plan_type.value
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def assignee(self) -> github.NamedUser.NamedUser:
|
| 92 |
+
return self._assignee.value
|
| 93 |
+
|
| 94 |
+
@property
|
| 95 |
+
def assigning_team(self) -> github.Team.Team:
|
| 96 |
+
return self._assigning_team.value
|
venv/lib/python3.10/site-packages/github/DefaultCodeSecurityConfig.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Justin Kufro <jkufro@andrew.cmu.edu> #
|
| 11 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 14 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 15 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 19 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 20 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 21 |
+
# Copyright 2025 Bill Napier <napier@pobox.com> #
|
| 22 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 23 |
+
# #
|
| 24 |
+
# This file is part of PyGithub. #
|
| 25 |
+
# http://pygithub.readthedocs.io/ #
|
| 26 |
+
# #
|
| 27 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 28 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 29 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 30 |
+
# any later version. #
|
| 31 |
+
# #
|
| 32 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 33 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 34 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 35 |
+
# details. #
|
| 36 |
+
# #
|
| 37 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 38 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 39 |
+
# #
|
| 40 |
+
################################################################################
|
| 41 |
+
|
| 42 |
+
from __future__ import annotations
|
| 43 |
+
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.CodeSecurityConfig
|
| 47 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class DefaultCodeSecurityConfig(NonCompletableGithubObject):
|
| 51 |
+
"""
|
| 52 |
+
This class represents a Default Configurations for Code Security.
|
| 53 |
+
|
| 54 |
+
The reference can be found here
|
| 55 |
+
https://docs.github.com/en/rest/code-security/configurations.
|
| 56 |
+
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
def _initAttributes(self) -> None:
|
| 60 |
+
self._configuration: Attribute[github.CodeSecurityConfig.CodeSecurityConfig] = NotSet
|
| 61 |
+
self._default_for_new_repos: Attribute[str] = NotSet
|
| 62 |
+
|
| 63 |
+
def __repr__(self) -> str:
|
| 64 |
+
return self.get__repr__(
|
| 65 |
+
{
|
| 66 |
+
"default_for_new_repos": self.default_for_new_repos,
|
| 67 |
+
}
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def configuration(self) -> github.CodeSecurityConfig.CodeSecurityConfig:
|
| 72 |
+
return self._configuration.value
|
| 73 |
+
|
| 74 |
+
@property
|
| 75 |
+
def default_for_new_repos(self) -> str:
|
| 76 |
+
return self._default_for_new_repos.value
|
| 77 |
+
|
| 78 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 79 |
+
if "configuration" in attributes: # pragma no branch
|
| 80 |
+
self._configuration = self._makeClassAttribute(
|
| 81 |
+
github.CodeSecurityConfig.CodeSecurityConfig, attributes["configuration"]
|
| 82 |
+
)
|
| 83 |
+
if "default_for_new_repos" in attributes: # pragma no branch
|
| 84 |
+
self._default_for_new_repos = self._makeStringAttribute(attributes["default_for_new_repos"])
|
venv/lib/python3.10/site-packages/github/DependabotAlert.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 4 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 5 |
+
# Copyright 2024 Thomas Cooper <coopernetes@proton.me> #
|
| 6 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 7 |
+
# #
|
| 8 |
+
# This file is part of PyGithub. #
|
| 9 |
+
# http://pygithub.readthedocs.io/ #
|
| 10 |
+
# #
|
| 11 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 12 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 13 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 14 |
+
# any later version. #
|
| 15 |
+
# #
|
| 16 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 17 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 18 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 19 |
+
# details. #
|
| 20 |
+
# #
|
| 21 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 22 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 23 |
+
# #
|
| 24 |
+
################################################################################
|
| 25 |
+
|
| 26 |
+
from __future__ import annotations
|
| 27 |
+
|
| 28 |
+
from datetime import datetime
|
| 29 |
+
from typing import TYPE_CHECKING, Any
|
| 30 |
+
|
| 31 |
+
import github.AdvisoryVulnerabilityPackage
|
| 32 |
+
import github.DependabotAlertAdvisory
|
| 33 |
+
import github.DependabotAlertDependency
|
| 34 |
+
import github.DependabotAlertVulnerability
|
| 35 |
+
import github.NamedUser
|
| 36 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 37 |
+
|
| 38 |
+
if TYPE_CHECKING:
|
| 39 |
+
from github.DependabotAlertAdvisory import DependabotAlertAdvisory
|
| 40 |
+
from github.DependabotAlertDependency import DependabotAlertDependency
|
| 41 |
+
from github.DependabotAlertVulnerability import DependabotAlertVulnerability
|
| 42 |
+
from github.NamedUser import NamedUser
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class DependabotAlert(NonCompletableGithubObject):
|
| 46 |
+
"""
|
| 47 |
+
This class represents a DependabotAlert.
|
| 48 |
+
|
| 49 |
+
The reference can be found here
|
| 50 |
+
https://docs.github.com/en/rest/dependabot/alerts
|
| 51 |
+
|
| 52 |
+
The OpenAPI schema can be found at
|
| 53 |
+
- /components/schemas/dependabot-alert
|
| 54 |
+
|
| 55 |
+
"""
|
| 56 |
+
|
| 57 |
+
def _initAttributes(self) -> None:
|
| 58 |
+
self._auto_dismissed_at: Attribute[datetime] = NotSet
|
| 59 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 60 |
+
self._dependency: Attribute[DependabotAlertDependency] = NotSet
|
| 61 |
+
self._dismissed_at: Attribute[datetime | None] = NotSet
|
| 62 |
+
self._dismissed_by: Attribute[NamedUser | None] = NotSet
|
| 63 |
+
self._dismissed_comment: Attribute[str | None] = NotSet
|
| 64 |
+
self._dismissed_reason: Attribute[str | None] = NotSet
|
| 65 |
+
self._fixed_at: Attribute[str] = NotSet
|
| 66 |
+
self._html_url: Attribute[str] = NotSet
|
| 67 |
+
self._number: Attribute[int] = NotSet
|
| 68 |
+
self._security_advisory: Attribute[DependabotAlertAdvisory] = NotSet
|
| 69 |
+
self._security_vulnerability: Attribute[DependabotAlertVulnerability] = NotSet
|
| 70 |
+
self._state: Attribute[str] = NotSet
|
| 71 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 72 |
+
self._url: Attribute[str] = NotSet
|
| 73 |
+
|
| 74 |
+
def __repr__(self) -> str:
|
| 75 |
+
return self.get__repr__({"number": self.number, "ghsa_id": self.security_advisory.ghsa_id})
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def auto_dismissed_at(self) -> datetime:
|
| 79 |
+
return self._auto_dismissed_at.value
|
| 80 |
+
|
| 81 |
+
@property
|
| 82 |
+
def created_at(self) -> datetime:
|
| 83 |
+
return self._created_at.value
|
| 84 |
+
|
| 85 |
+
@property
|
| 86 |
+
def dependency(self) -> DependabotAlertDependency:
|
| 87 |
+
return self._dependency.value
|
| 88 |
+
|
| 89 |
+
@property
|
| 90 |
+
def dismissed_at(self) -> datetime | None:
|
| 91 |
+
return self._dismissed_at.value
|
| 92 |
+
|
| 93 |
+
@property
|
| 94 |
+
def dismissed_by(self) -> NamedUser | None:
|
| 95 |
+
return self._dismissed_by.value
|
| 96 |
+
|
| 97 |
+
@property
|
| 98 |
+
def dismissed_comment(self) -> str | None:
|
| 99 |
+
return self._dismissed_comment.value
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def dismissed_reason(self) -> str | None:
|
| 103 |
+
return self._dismissed_reason.value
|
| 104 |
+
|
| 105 |
+
@property
|
| 106 |
+
def fixed_at(self) -> str | None:
|
| 107 |
+
return self._fixed_at.value
|
| 108 |
+
|
| 109 |
+
@property
|
| 110 |
+
def html_url(self) -> str:
|
| 111 |
+
return self._html_url.value
|
| 112 |
+
|
| 113 |
+
@property
|
| 114 |
+
def number(self) -> int:
|
| 115 |
+
return self._number.value
|
| 116 |
+
|
| 117 |
+
@property
|
| 118 |
+
def security_advisory(self) -> DependabotAlertAdvisory:
|
| 119 |
+
return self._security_advisory.value
|
| 120 |
+
|
| 121 |
+
@property
|
| 122 |
+
def security_vulnerability(self) -> DependabotAlertVulnerability:
|
| 123 |
+
return self._security_vulnerability.value
|
| 124 |
+
|
| 125 |
+
@property
|
| 126 |
+
def state(self) -> str:
|
| 127 |
+
return self._state.value
|
| 128 |
+
|
| 129 |
+
@property
|
| 130 |
+
def updated_at(self) -> datetime:
|
| 131 |
+
return self._updated_at.value
|
| 132 |
+
|
| 133 |
+
@property
|
| 134 |
+
def url(self) -> str:
|
| 135 |
+
return self._url.value
|
| 136 |
+
|
| 137 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 138 |
+
if "auto_dismissed_at" in attributes: # pragma no branch
|
| 139 |
+
self._auto_dismissed_at = self._makeDatetimeAttribute(attributes["auto_dismissed_at"])
|
| 140 |
+
if "created_at" in attributes:
|
| 141 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 142 |
+
if "dependency" in attributes:
|
| 143 |
+
self._dependency = self._makeClassAttribute(
|
| 144 |
+
github.DependabotAlertDependency.DependabotAlertDependency, attributes["dependency"]
|
| 145 |
+
)
|
| 146 |
+
if "dismissed_at" in attributes:
|
| 147 |
+
self._dismissed_at = self._makeDatetimeAttribute(attributes["dismissed_at"])
|
| 148 |
+
if "dismissed_by" in attributes:
|
| 149 |
+
self._dismissed_by = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["dismissed_by"])
|
| 150 |
+
if "dismissed_comment" in attributes:
|
| 151 |
+
self._dismissed_comment = self._makeStringAttribute(attributes["dismissed_comment"])
|
| 152 |
+
if "dismissed_reason" in attributes:
|
| 153 |
+
self._dismissed_reason = self._makeStringAttribute(attributes["dismissed_reason"])
|
| 154 |
+
if "fixed_at" in attributes:
|
| 155 |
+
self._fixed_at = self._makeStringAttribute(attributes["fixed_at"])
|
| 156 |
+
if "html_url" in attributes:
|
| 157 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 158 |
+
if "number" in attributes:
|
| 159 |
+
self._number = self._makeIntAttribute(attributes["number"])
|
| 160 |
+
if "security_advisory" in attributes:
|
| 161 |
+
self._security_advisory = self._makeClassAttribute(
|
| 162 |
+
github.DependabotAlertAdvisory.DependabotAlertAdvisory, attributes["security_advisory"]
|
| 163 |
+
)
|
| 164 |
+
if "security_vulnerability" in attributes:
|
| 165 |
+
self._security_vulnerability = self._makeClassAttribute(
|
| 166 |
+
github.DependabotAlertVulnerability.DependabotAlertVulnerability, attributes["security_vulnerability"]
|
| 167 |
+
)
|
| 168 |
+
if "state" in attributes:
|
| 169 |
+
self._state = self._makeStringAttribute(attributes["state"])
|
| 170 |
+
if "updated_at" in attributes:
|
| 171 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 172 |
+
if "url" in attributes:
|
| 173 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/DependabotAlertAdvisory.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 4 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 5 |
+
# Copyright 2024 Thomas Cooper <coopernetes@proton.me> #
|
| 6 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 7 |
+
# #
|
| 8 |
+
# This file is part of PyGithub. #
|
| 9 |
+
# http://pygithub.readthedocs.io/ #
|
| 10 |
+
# #
|
| 11 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 12 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 13 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 14 |
+
# any later version. #
|
| 15 |
+
# #
|
| 16 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 17 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 18 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 19 |
+
# details. #
|
| 20 |
+
# #
|
| 21 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 22 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 23 |
+
# #
|
| 24 |
+
################################################################################
|
| 25 |
+
|
| 26 |
+
from __future__ import annotations
|
| 27 |
+
|
| 28 |
+
from typing import TYPE_CHECKING, Any
|
| 29 |
+
|
| 30 |
+
import github.DependabotAlertVulnerability
|
| 31 |
+
from github.AdvisoryBase import AdvisoryBase
|
| 32 |
+
from github.GithubObject import Attribute, NotSet
|
| 33 |
+
|
| 34 |
+
if TYPE_CHECKING:
|
| 35 |
+
from github.DependabotAlertVulnerability import DependabotAlertVulnerability
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class DependabotAlertAdvisory(AdvisoryBase):
|
| 39 |
+
"""
|
| 40 |
+
This class represents a package flagged by a Dependabot alert that is vulnerable to a parent SecurityAdvisory.
|
| 41 |
+
|
| 42 |
+
The reference can be found here
|
| 43 |
+
https://docs.github.com/en/rest/dependabot/alerts
|
| 44 |
+
|
| 45 |
+
The OpenAPI schema can be found at
|
| 46 |
+
- /components/schemas/dependabot-alert-security-advisory
|
| 47 |
+
|
| 48 |
+
"""
|
| 49 |
+
|
| 50 |
+
def _initAttributes(self) -> None:
|
| 51 |
+
super()._initAttributes()
|
| 52 |
+
self._references: Attribute[list[dict]] = NotSet
|
| 53 |
+
self._vulnerabilities: Attribute[list[DependabotAlertVulnerability]] = NotSet
|
| 54 |
+
|
| 55 |
+
@property
|
| 56 |
+
def references(self) -> list[dict]:
|
| 57 |
+
return self._references.value
|
| 58 |
+
|
| 59 |
+
@property
|
| 60 |
+
def vulnerabilities(self) -> list[DependabotAlertVulnerability]:
|
| 61 |
+
return self._vulnerabilities.value
|
| 62 |
+
|
| 63 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 64 |
+
if "references" in attributes:
|
| 65 |
+
self._references = self._makeListOfDictsAttribute(
|
| 66 |
+
attributes["references"],
|
| 67 |
+
)
|
| 68 |
+
if "vulnerabilities" in attributes:
|
| 69 |
+
self._vulnerabilities = self._makeListOfClassesAttribute(
|
| 70 |
+
github.DependabotAlertVulnerability.DependabotAlertVulnerability,
|
| 71 |
+
attributes["vulnerabilities"],
|
| 72 |
+
)
|
| 73 |
+
super()._useAttributes(attributes)
|
venv/lib/python3.10/site-packages/github/DependabotAlertDependency.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 4 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 5 |
+
# Copyright 2024 Thomas Cooper <coopernetes@proton.me> #
|
| 6 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 7 |
+
# #
|
| 8 |
+
# This file is part of PyGithub. #
|
| 9 |
+
# http://pygithub.readthedocs.io/ #
|
| 10 |
+
# #
|
| 11 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 12 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 13 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 14 |
+
# any later version. #
|
| 15 |
+
# #
|
| 16 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 17 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 18 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 19 |
+
# details. #
|
| 20 |
+
# #
|
| 21 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 22 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 23 |
+
# #
|
| 24 |
+
################################################################################
|
| 25 |
+
|
| 26 |
+
from __future__ import annotations
|
| 27 |
+
|
| 28 |
+
from typing import Any
|
| 29 |
+
|
| 30 |
+
from github.AdvisoryVulnerabilityPackage import AdvisoryVulnerabilityPackage
|
| 31 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class DependabotAlertDependency(NonCompletableGithubObject):
|
| 35 |
+
"""
|
| 36 |
+
This class represents a DependabotAlertDependency.
|
| 37 |
+
|
| 38 |
+
The reference can be found here
|
| 39 |
+
https://docs.github.com/en/rest/dependabot/alerts
|
| 40 |
+
|
| 41 |
+
The OpenAPI schema can be found at
|
| 42 |
+
- /components/schemas/dependabot-alert/properties/dependency
|
| 43 |
+
|
| 44 |
+
"""
|
| 45 |
+
|
| 46 |
+
def _initAttributes(self) -> None:
|
| 47 |
+
self._manifest_path: Attribute[str] = NotSet
|
| 48 |
+
self._package: Attribute[AdvisoryVulnerabilityPackage] = NotSet
|
| 49 |
+
self._scope: Attribute[str] = NotSet
|
| 50 |
+
|
| 51 |
+
def __repr__(self) -> str:
|
| 52 |
+
return self.get__repr__(
|
| 53 |
+
{
|
| 54 |
+
"package": self.package,
|
| 55 |
+
"manifest_path": self.manifest_path,
|
| 56 |
+
}
|
| 57 |
+
)
|
| 58 |
+
|
| 59 |
+
@property
|
| 60 |
+
def manifest_path(self) -> str:
|
| 61 |
+
return self._manifest_path.value
|
| 62 |
+
|
| 63 |
+
@property
|
| 64 |
+
def package(self) -> AdvisoryVulnerabilityPackage:
|
| 65 |
+
return self._package.value
|
| 66 |
+
|
| 67 |
+
@property
|
| 68 |
+
def scope(self) -> str:
|
| 69 |
+
return self._scope.value
|
| 70 |
+
|
| 71 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 72 |
+
if "manifest_path" in attributes:
|
| 73 |
+
self._manifest_path = self._makeStringAttribute(attributes["manifest_path"])
|
| 74 |
+
if "package" in attributes:
|
| 75 |
+
self._package = self._makeClassAttribute(
|
| 76 |
+
AdvisoryVulnerabilityPackage,
|
| 77 |
+
attributes["package"],
|
| 78 |
+
)
|
| 79 |
+
if "scope" in attributes:
|
| 80 |
+
self._scope = self._makeStringAttribute(attributes["scope"])
|
venv/lib/python3.10/site-packages/github/DependabotAlertVulnerability.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 4 |
+
# Copyright 2024 Thomas Cooper <coopernetes@proton.me> #
|
| 5 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 6 |
+
# #
|
| 7 |
+
# This file is part of PyGithub. #
|
| 8 |
+
# http://pygithub.readthedocs.io/ #
|
| 9 |
+
# #
|
| 10 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 11 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 12 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 13 |
+
# any later version. #
|
| 14 |
+
# #
|
| 15 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 16 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 17 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 18 |
+
# details. #
|
| 19 |
+
# #
|
| 20 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 21 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 22 |
+
# #
|
| 23 |
+
################################################################################
|
| 24 |
+
|
| 25 |
+
from __future__ import annotations
|
| 26 |
+
|
| 27 |
+
from typing import TYPE_CHECKING, Any
|
| 28 |
+
|
| 29 |
+
import github.AdvisoryVulnerabilityPackage
|
| 30 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 31 |
+
|
| 32 |
+
if TYPE_CHECKING:
|
| 33 |
+
from github.AdvisoryVulnerabilityPackage import AdvisoryVulnerabilityPackage
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
class DependabotAlertVulnerability(NonCompletableGithubObject):
|
| 37 |
+
"""
|
| 38 |
+
A vulnerability represented in a Dependabot alert.
|
| 39 |
+
|
| 40 |
+
The OpenAPI schema can be found at
|
| 41 |
+
- /components/schemas/dependabot-alert-security-vulnerability
|
| 42 |
+
|
| 43 |
+
"""
|
| 44 |
+
|
| 45 |
+
def _initAttributes(self) -> None:
|
| 46 |
+
self._first_patched_version: Attribute[dict] = NotSet
|
| 47 |
+
self._package: Attribute[AdvisoryVulnerabilityPackage] = NotSet
|
| 48 |
+
self._severity: Attribute[str] = NotSet
|
| 49 |
+
self._vulnerable_version_range: Attribute[str | None] = NotSet
|
| 50 |
+
|
| 51 |
+
def __repr__(self) -> str:
|
| 52 |
+
return self.get__repr__({"package": self.package, "severity": self.severity})
|
| 53 |
+
|
| 54 |
+
@property
|
| 55 |
+
def first_patched_version(self) -> dict:
|
| 56 |
+
return self._first_patched_version.value
|
| 57 |
+
|
| 58 |
+
@property
|
| 59 |
+
def package(self) -> AdvisoryVulnerabilityPackage:
|
| 60 |
+
return self._package.value
|
| 61 |
+
|
| 62 |
+
@property
|
| 63 |
+
def severity(self) -> str:
|
| 64 |
+
return self._severity.value
|
| 65 |
+
|
| 66 |
+
@property
|
| 67 |
+
def vulnerable_version_range(self) -> str | None:
|
| 68 |
+
return self._vulnerable_version_range.value
|
| 69 |
+
|
| 70 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 71 |
+
if "first_patched_version" in attributes:
|
| 72 |
+
self._first_patched_version = self._makeDictAttribute(
|
| 73 |
+
attributes["first_patched_version"],
|
| 74 |
+
)
|
| 75 |
+
if "package" in attributes:
|
| 76 |
+
self._package = self._makeClassAttribute(
|
| 77 |
+
github.AdvisoryVulnerabilityPackage.AdvisoryVulnerabilityPackage,
|
| 78 |
+
attributes["package"],
|
| 79 |
+
)
|
| 80 |
+
if "severity" in attributes:
|
| 81 |
+
self._severity = self._makeStringAttribute(attributes["severity"])
|
| 82 |
+
if "vulnerable_version_range" in attributes:
|
| 83 |
+
self._vulnerable_version_range = self._makeStringAttribute(attributes["vulnerable_version_range"])
|
venv/lib/python3.10/site-packages/github/Deployment.py
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2015 Matt Babineau <mbabineau@dataxu.com> #
|
| 9 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 10 |
+
# Copyright 2016 Martijn Koster <mak-github@greenhills.co.uk> #
|
| 11 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 12 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2020 Colby Gallup <colbygallup@gmail.com> #
|
| 17 |
+
# Copyright 2020 Pascal Hofmann <mail@pascalhofmann.de> #
|
| 18 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 19 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 20 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2023 Nevins <nevins-b@users.noreply.github.com> #
|
| 23 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 24 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 25 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 26 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 27 |
+
# #
|
| 28 |
+
# This file is part of PyGithub. #
|
| 29 |
+
# http://pygithub.readthedocs.io/ #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 32 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 33 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 34 |
+
# any later version. #
|
| 35 |
+
# #
|
| 36 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 37 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 38 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 39 |
+
# details. #
|
| 40 |
+
# #
|
| 41 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 42 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 43 |
+
# #
|
| 44 |
+
################################################################################
|
| 45 |
+
|
| 46 |
+
from __future__ import annotations
|
| 47 |
+
|
| 48 |
+
from datetime import datetime
|
| 49 |
+
from typing import TYPE_CHECKING, Any
|
| 50 |
+
|
| 51 |
+
import github.Consts
|
| 52 |
+
import github.DeploymentStatus
|
| 53 |
+
import github.GithubApp
|
| 54 |
+
import github.NamedUser
|
| 55 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet, Opt
|
| 56 |
+
from github.PaginatedList import PaginatedList
|
| 57 |
+
|
| 58 |
+
if TYPE_CHECKING:
|
| 59 |
+
from github.GithubApp import GithubApp
|
| 60 |
+
from github.NamedUser import NamedUser
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
class Deployment(CompletableGithubObject):
|
| 64 |
+
"""
|
| 65 |
+
This class represents Deployments.
|
| 66 |
+
|
| 67 |
+
The reference can be found here
|
| 68 |
+
https://docs.github.com/en/rest/reference/repos#deployments
|
| 69 |
+
|
| 70 |
+
The OpenAPI schema can be found at
|
| 71 |
+
- /components/schemas/deployment
|
| 72 |
+
- /components/schemas/deployment-simple
|
| 73 |
+
|
| 74 |
+
"""
|
| 75 |
+
|
| 76 |
+
def _initAttributes(self) -> None:
|
| 77 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 78 |
+
self._creator: Attribute[NamedUser] = NotSet
|
| 79 |
+
self._description: Attribute[str] = NotSet
|
| 80 |
+
self._environment: Attribute[str] = NotSet
|
| 81 |
+
self._id: Attribute[int] = NotSet
|
| 82 |
+
self._node_id: Attribute[str] = NotSet
|
| 83 |
+
self._original_environment: Attribute[str] = NotSet
|
| 84 |
+
self._payload: Attribute[dict[str, Any]] = NotSet
|
| 85 |
+
self._performed_via_github_app: Attribute[GithubApp] = NotSet
|
| 86 |
+
self._production_environment: Attribute[bool] = NotSet
|
| 87 |
+
self._ref: Attribute[str] = NotSet
|
| 88 |
+
self._repository_url: Attribute[str] = NotSet
|
| 89 |
+
self._sha: Attribute[str] = NotSet
|
| 90 |
+
self._statuses_url: Attribute[str] = NotSet
|
| 91 |
+
self._task: Attribute[str] = NotSet
|
| 92 |
+
self._transient_environment: Attribute[bool] = NotSet
|
| 93 |
+
self._updated_at: Attribute[datetime | None] = NotSet
|
| 94 |
+
self._url: Attribute[str] = NotSet
|
| 95 |
+
|
| 96 |
+
def __repr__(self) -> str:
|
| 97 |
+
return self.get__repr__({"id": self._id.value, "url": self._url.value})
|
| 98 |
+
|
| 99 |
+
@property
|
| 100 |
+
def created_at(self) -> datetime:
|
| 101 |
+
self._completeIfNotSet(self._created_at)
|
| 102 |
+
return self._created_at.value
|
| 103 |
+
|
| 104 |
+
@property
|
| 105 |
+
def creator(self) -> NamedUser:
|
| 106 |
+
self._completeIfNotSet(self._creator)
|
| 107 |
+
return self._creator.value
|
| 108 |
+
|
| 109 |
+
@property
|
| 110 |
+
def description(self) -> str:
|
| 111 |
+
self._completeIfNotSet(self._description)
|
| 112 |
+
return self._description.value
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
def environment(self) -> str:
|
| 116 |
+
self._completeIfNotSet(self._environment)
|
| 117 |
+
return self._environment.value
|
| 118 |
+
|
| 119 |
+
@property
|
| 120 |
+
def id(self) -> int:
|
| 121 |
+
self._completeIfNotSet(self._id)
|
| 122 |
+
return self._id.value
|
| 123 |
+
|
| 124 |
+
@property
|
| 125 |
+
def node_id(self) -> str:
|
| 126 |
+
self._completeIfNotSet(self._node_id)
|
| 127 |
+
return self._node_id.value
|
| 128 |
+
|
| 129 |
+
@property
|
| 130 |
+
def original_environment(self) -> str:
|
| 131 |
+
self._completeIfNotSet(self._original_environment)
|
| 132 |
+
return self._original_environment.value
|
| 133 |
+
|
| 134 |
+
@property
|
| 135 |
+
def payload(self) -> dict[str, Any]:
|
| 136 |
+
self._completeIfNotSet(self._payload)
|
| 137 |
+
return self._payload.value
|
| 138 |
+
|
| 139 |
+
@property
|
| 140 |
+
def performed_via_github_app(self) -> GithubApp:
|
| 141 |
+
self._completeIfNotSet(self._performed_via_github_app)
|
| 142 |
+
return self._performed_via_github_app.value
|
| 143 |
+
|
| 144 |
+
@property
|
| 145 |
+
def production_environment(self) -> bool:
|
| 146 |
+
self._completeIfNotSet(self._production_environment)
|
| 147 |
+
return self._production_environment.value
|
| 148 |
+
|
| 149 |
+
@property
|
| 150 |
+
def ref(self) -> str:
|
| 151 |
+
self._completeIfNotSet(self._ref)
|
| 152 |
+
return self._ref.value
|
| 153 |
+
|
| 154 |
+
@property
|
| 155 |
+
def repository_url(self) -> str:
|
| 156 |
+
self._completeIfNotSet(self._repository_url)
|
| 157 |
+
return self._repository_url.value
|
| 158 |
+
|
| 159 |
+
@property
|
| 160 |
+
def sha(self) -> str:
|
| 161 |
+
self._completeIfNotSet(self._sha)
|
| 162 |
+
return self._sha.value
|
| 163 |
+
|
| 164 |
+
@property
|
| 165 |
+
def statuses_url(self) -> str:
|
| 166 |
+
self._completeIfNotSet(self._statuses_url)
|
| 167 |
+
return self._statuses_url.value
|
| 168 |
+
|
| 169 |
+
@property
|
| 170 |
+
def task(self) -> str:
|
| 171 |
+
self._completeIfNotSet(self._task)
|
| 172 |
+
return self._task.value
|
| 173 |
+
|
| 174 |
+
@property
|
| 175 |
+
def transient_environment(self) -> bool:
|
| 176 |
+
self._completeIfNotSet(self._transient_environment)
|
| 177 |
+
return self._transient_environment.value
|
| 178 |
+
|
| 179 |
+
@property
|
| 180 |
+
def updated_at(self) -> datetime | None:
|
| 181 |
+
self._completeIfNotSet(self._updated_at)
|
| 182 |
+
return self._updated_at.value
|
| 183 |
+
|
| 184 |
+
@property
|
| 185 |
+
def url(self) -> str:
|
| 186 |
+
self._completeIfNotSet(self._url)
|
| 187 |
+
return self._url.value
|
| 188 |
+
|
| 189 |
+
def get_statuses(self) -> PaginatedList[github.DeploymentStatus.DeploymentStatus]:
|
| 190 |
+
"""
|
| 191 |
+
:calls: `GET /repos/{owner}/deployments/{deployment_id}/statuses <https://docs.github.com/en/rest/reference/repos#list-deployments>`_
|
| 192 |
+
"""
|
| 193 |
+
return PaginatedList(
|
| 194 |
+
github.DeploymentStatus.DeploymentStatus,
|
| 195 |
+
self._requester,
|
| 196 |
+
f"{self.url}/statuses",
|
| 197 |
+
None,
|
| 198 |
+
headers={"Accept": self._get_accept_header()},
|
| 199 |
+
)
|
| 200 |
+
|
| 201 |
+
def get_status(self, id_: int) -> github.DeploymentStatus.DeploymentStatus:
|
| 202 |
+
"""
|
| 203 |
+
:calls: `GET /repos/{owner}/deployments/{deployment_id}/statuses/{status_id} <https://docs.github.com/en/rest/reference/repos#get-a-deployment>`_
|
| 204 |
+
"""
|
| 205 |
+
assert isinstance(id_, int), id_
|
| 206 |
+
headers, data = self._requester.requestJsonAndCheck(
|
| 207 |
+
"GET",
|
| 208 |
+
f"{self.url}/statuses/{id_}",
|
| 209 |
+
headers={"Accept": self._get_accept_header()},
|
| 210 |
+
)
|
| 211 |
+
return github.DeploymentStatus.DeploymentStatus(self._requester, headers, data, completed=True)
|
| 212 |
+
|
| 213 |
+
def create_status(
|
| 214 |
+
self,
|
| 215 |
+
state: str,
|
| 216 |
+
target_url: Opt[str] = NotSet,
|
| 217 |
+
description: Opt[str] = NotSet,
|
| 218 |
+
environment: Opt[str] = NotSet,
|
| 219 |
+
environment_url: Opt[str] = NotSet,
|
| 220 |
+
auto_inactive: Opt[bool] = NotSet,
|
| 221 |
+
) -> github.DeploymentStatus.DeploymentStatus:
|
| 222 |
+
"""
|
| 223 |
+
:calls: `POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses <https://docs.github.com/en/rest/reference/repos#create-a-deployment-status>`_
|
| 224 |
+
"""
|
| 225 |
+
assert isinstance(state, str), state
|
| 226 |
+
assert target_url is NotSet or isinstance(target_url, str), target_url
|
| 227 |
+
assert description is NotSet or isinstance(description, str), description
|
| 228 |
+
assert environment is NotSet or isinstance(environment, str), environment
|
| 229 |
+
assert environment_url is NotSet or isinstance(environment_url, str), environment_url
|
| 230 |
+
assert auto_inactive is NotSet or isinstance(auto_inactive, bool), auto_inactive
|
| 231 |
+
|
| 232 |
+
post_parameters = NotSet.remove_unset_items(
|
| 233 |
+
{
|
| 234 |
+
"state": state,
|
| 235 |
+
"target_url": target_url,
|
| 236 |
+
"description": description,
|
| 237 |
+
"environment": environment,
|
| 238 |
+
"environment_url": environment_url,
|
| 239 |
+
"auto_inactive": auto_inactive,
|
| 240 |
+
}
|
| 241 |
+
)
|
| 242 |
+
|
| 243 |
+
headers, data = self._requester.requestJsonAndCheck(
|
| 244 |
+
"POST",
|
| 245 |
+
f"{self.url}/statuses",
|
| 246 |
+
input=post_parameters,
|
| 247 |
+
headers={"Accept": self._get_accept_header()},
|
| 248 |
+
)
|
| 249 |
+
return github.DeploymentStatus.DeploymentStatus(self._requester, headers, data, completed=True)
|
| 250 |
+
|
| 251 |
+
@staticmethod
|
| 252 |
+
def _get_accept_header() -> str:
|
| 253 |
+
return ", ".join(
|
| 254 |
+
[
|
| 255 |
+
github.Consts.deploymentEnhancementsPreview,
|
| 256 |
+
github.Consts.deploymentStatusEnhancementsPreview,
|
| 257 |
+
]
|
| 258 |
+
)
|
| 259 |
+
|
| 260 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 261 |
+
if "created_at" in attributes: # pragma no branch
|
| 262 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 263 |
+
if "creator" in attributes: # pragma no branch
|
| 264 |
+
self._creator = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["creator"])
|
| 265 |
+
if "description" in attributes: # pragma no branch
|
| 266 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 267 |
+
if "environment" in attributes: # pragma no branch
|
| 268 |
+
self._environment = self._makeStringAttribute(attributes["environment"])
|
| 269 |
+
if "id" in attributes: # pragma no branch
|
| 270 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 271 |
+
if "node_id" in attributes: # pragma no branch
|
| 272 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 273 |
+
if "original_environment" in attributes: # pragma no branch
|
| 274 |
+
self._original_environment = self._makeStringAttribute(attributes["original_environment"])
|
| 275 |
+
if "payload" in attributes: # pragma no branch
|
| 276 |
+
self._payload = self._makeDictAttribute(attributes["payload"])
|
| 277 |
+
if "performed_via_github_app" in attributes: # pragma no branch
|
| 278 |
+
self._performed_via_github_app = self._makeClassAttribute(
|
| 279 |
+
github.GithubApp.GithubApp, attributes["performed_via_github_app"]
|
| 280 |
+
)
|
| 281 |
+
if "production_environment" in attributes: # pragma no branch
|
| 282 |
+
self._production_environment = self._makeBoolAttribute(attributes["production_environment"])
|
| 283 |
+
if "ref" in attributes: # pragma no branch
|
| 284 |
+
self._ref = self._makeStringAttribute(attributes["ref"])
|
| 285 |
+
if "repository_url" in attributes: # pragma no branch
|
| 286 |
+
self._repository_url = self._makeStringAttribute(attributes["repository_url"])
|
| 287 |
+
if "sha" in attributes: # pragma no branch
|
| 288 |
+
self._sha = self._makeStringAttribute(attributes["sha"])
|
| 289 |
+
if "statuses_url" in attributes: # pragma no branch
|
| 290 |
+
self._statuses_url = self._makeStringAttribute(attributes["statuses_url"])
|
| 291 |
+
if "task" in attributes: # pragma no branch
|
| 292 |
+
self._task = self._makeStringAttribute(attributes["task"])
|
| 293 |
+
if "transient_environment" in attributes: # pragma no branch
|
| 294 |
+
self._transient_environment = self._makeBoolAttribute(attributes["transient_environment"])
|
| 295 |
+
if "updated_at" in attributes: # pragma no branch
|
| 296 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 297 |
+
if "url" in attributes: # pragma no branch
|
| 298 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/DeploymentStatus.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2015 Matt Babineau <mbabineau@dataxu.com> #
|
| 9 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 10 |
+
# Copyright 2016 Martijn Koster <mak-github@greenhills.co.uk> #
|
| 11 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 12 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2020 Colby Gallup <colbygallup@gmail.com> #
|
| 17 |
+
# Copyright 2020 Pascal Hofmann <mail@pascalhofmann.de> #
|
| 18 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 19 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 20 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 23 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 24 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 25 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 26 |
+
# #
|
| 27 |
+
# This file is part of PyGithub. #
|
| 28 |
+
# http://pygithub.readthedocs.io/ #
|
| 29 |
+
# #
|
| 30 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 31 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 32 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 33 |
+
# any later version. #
|
| 34 |
+
# #
|
| 35 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 36 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 37 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 38 |
+
# details. #
|
| 39 |
+
# #
|
| 40 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 41 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 42 |
+
# #
|
| 43 |
+
################################################################################
|
| 44 |
+
|
| 45 |
+
from __future__ import annotations
|
| 46 |
+
|
| 47 |
+
from datetime import datetime
|
| 48 |
+
from typing import TYPE_CHECKING, Any
|
| 49 |
+
|
| 50 |
+
import github.GithubApp
|
| 51 |
+
import github.NamedUser
|
| 52 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 53 |
+
|
| 54 |
+
if TYPE_CHECKING:
|
| 55 |
+
from github.GithubApp import GithubApp
|
| 56 |
+
from github.NamedUser import NamedUser
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
class DeploymentStatus(CompletableGithubObject):
|
| 60 |
+
"""
|
| 61 |
+
This class represents Deployment Statuses.
|
| 62 |
+
|
| 63 |
+
The reference can be found here
|
| 64 |
+
https://docs.github.com/en/rest/reference/repos#deployments
|
| 65 |
+
|
| 66 |
+
The OpenAPI schema can be found at
|
| 67 |
+
- /components/schemas/deployment-status
|
| 68 |
+
|
| 69 |
+
"""
|
| 70 |
+
|
| 71 |
+
def _initAttributes(self) -> None:
|
| 72 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 73 |
+
self._creator: Attribute[NamedUser] = NotSet
|
| 74 |
+
self._deployment_url: Attribute[str] = NotSet
|
| 75 |
+
self._description: Attribute[str] = NotSet
|
| 76 |
+
self._environment: Attribute[str] = NotSet
|
| 77 |
+
self._environment_url: Attribute[str] = NotSet
|
| 78 |
+
self._id: Attribute[int] = NotSet
|
| 79 |
+
self._log_url: Attribute[str] = NotSet
|
| 80 |
+
self._node_id: Attribute[str] = NotSet
|
| 81 |
+
self._performed_via_github_app: Attribute[GithubApp] = NotSet
|
| 82 |
+
self._repository_url: Attribute[str] = NotSet
|
| 83 |
+
self._state: Attribute[str] = NotSet
|
| 84 |
+
self._target_url: Attribute[str] = NotSet
|
| 85 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 86 |
+
self._url: Attribute[str] = NotSet
|
| 87 |
+
|
| 88 |
+
def __repr__(self) -> str:
|
| 89 |
+
return self.get__repr__({"id": self._id.value, "url": self._url.value})
|
| 90 |
+
|
| 91 |
+
@property
|
| 92 |
+
def created_at(self) -> datetime:
|
| 93 |
+
self._completeIfNotSet(self._created_at)
|
| 94 |
+
return self._created_at.value
|
| 95 |
+
|
| 96 |
+
@property
|
| 97 |
+
def creator(self) -> NamedUser:
|
| 98 |
+
self._completeIfNotSet(self._creator)
|
| 99 |
+
return self._creator.value
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def deployment_url(self) -> str:
|
| 103 |
+
self._completeIfNotSet(self._deployment_url)
|
| 104 |
+
return self._deployment_url.value
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def description(self) -> str:
|
| 108 |
+
self._completeIfNotSet(self._description)
|
| 109 |
+
return self._description.value
|
| 110 |
+
|
| 111 |
+
@property
|
| 112 |
+
def environment(self) -> str:
|
| 113 |
+
self._completeIfNotSet(self._environment)
|
| 114 |
+
return self._environment.value
|
| 115 |
+
|
| 116 |
+
@property
|
| 117 |
+
def environment_url(self) -> str:
|
| 118 |
+
self._completeIfNotSet(self._environment_url)
|
| 119 |
+
return self._environment_url.value
|
| 120 |
+
|
| 121 |
+
@property
|
| 122 |
+
def id(self) -> int:
|
| 123 |
+
self._completeIfNotSet(self._id)
|
| 124 |
+
return self._id.value
|
| 125 |
+
|
| 126 |
+
@property
|
| 127 |
+
def log_url(self) -> str:
|
| 128 |
+
self._completeIfNotSet(self._log_url)
|
| 129 |
+
return self._log_url.value
|
| 130 |
+
|
| 131 |
+
@property
|
| 132 |
+
def node_id(self) -> str:
|
| 133 |
+
self._completeIfNotSet(self._node_id)
|
| 134 |
+
return self._node_id.value
|
| 135 |
+
|
| 136 |
+
@property
|
| 137 |
+
def performed_via_github_app(self) -> GithubApp:
|
| 138 |
+
self._completeIfNotSet(self._performed_via_github_app)
|
| 139 |
+
return self._performed_via_github_app.value
|
| 140 |
+
|
| 141 |
+
@property
|
| 142 |
+
def repository_url(self) -> str:
|
| 143 |
+
self._completeIfNotSet(self._repository_url)
|
| 144 |
+
return self._repository_url.value
|
| 145 |
+
|
| 146 |
+
@property
|
| 147 |
+
def state(self) -> str:
|
| 148 |
+
self._completeIfNotSet(self._state)
|
| 149 |
+
return self._state.value
|
| 150 |
+
|
| 151 |
+
@property
|
| 152 |
+
def target_url(self) -> str:
|
| 153 |
+
self._completeIfNotSet(self._target_url)
|
| 154 |
+
return self._target_url.value
|
| 155 |
+
|
| 156 |
+
@property
|
| 157 |
+
def updated_at(self) -> datetime:
|
| 158 |
+
self._completeIfNotSet(self._updated_at)
|
| 159 |
+
return self._updated_at.value
|
| 160 |
+
|
| 161 |
+
@property
|
| 162 |
+
def url(self) -> str:
|
| 163 |
+
self._completeIfNotSet(self._url)
|
| 164 |
+
return self._url.value
|
| 165 |
+
|
| 166 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 167 |
+
if "created_at" in attributes: # pragma no branch
|
| 168 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 169 |
+
if "creator" in attributes: # pragma no branch
|
| 170 |
+
self._creator = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["creator"])
|
| 171 |
+
if "deployment_url" in attributes: # pragma no branch
|
| 172 |
+
self._deployment_url = self._makeStringAttribute(attributes["deployment_url"])
|
| 173 |
+
if "description" in attributes: # pragma no branch
|
| 174 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 175 |
+
if "environment" in attributes: # pragma no branch
|
| 176 |
+
self._environment = self._makeStringAttribute(attributes["environment"])
|
| 177 |
+
if "environment_url" in attributes: # pragma no branch
|
| 178 |
+
self._environment_url = self._makeStringAttribute(attributes["environment_url"])
|
| 179 |
+
if "id" in attributes: # pragma no branch
|
| 180 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 181 |
+
if "log_url" in attributes: # pragma no branch
|
| 182 |
+
self._log_url = self._makeStringAttribute(attributes["log_url"])
|
| 183 |
+
if "node_id" in attributes: # pragma no branch
|
| 184 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 185 |
+
if "performed_via_github_app" in attributes: # pragma no branch
|
| 186 |
+
self._performed_via_github_app = self._makeClassAttribute(
|
| 187 |
+
github.GithubApp.GithubApp, attributes["performed_via_github_app"]
|
| 188 |
+
)
|
| 189 |
+
if "repository_url" in attributes: # pragma no branch
|
| 190 |
+
self._repository_url = self._makeStringAttribute(attributes["repository_url"])
|
| 191 |
+
if "state" in attributes: # pragma no branch
|
| 192 |
+
self._state = self._makeStringAttribute(attributes["state"])
|
| 193 |
+
if "target_url" in attributes: # pragma no branch
|
| 194 |
+
self._target_url = self._makeStringAttribute(attributes["target_url"])
|
| 195 |
+
if "updated_at" in attributes: # pragma no branch
|
| 196 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 197 |
+
if "url" in attributes: # pragma no branch
|
| 198 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/DiscussionBase.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Mark Walker <mark.walker@realbuzz.com> #
|
| 16 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
from __future__ import annotations
|
| 42 |
+
|
| 43 |
+
from datetime import datetime
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.GithubObject
|
| 47 |
+
import github.NamedUser
|
| 48 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class DiscussionBase(CompletableGithubObject):
|
| 52 |
+
"""
|
| 53 |
+
This class represents a the shared attributes between RepositoryDiscussion and TeamDiscussion
|
| 54 |
+
https://docs.github.com/en/graphql/reference/objects#discussion
|
| 55 |
+
https://docs.github.com/en/rest/reference/teams#discussions
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
def _initAttributes(self) -> None:
|
| 59 |
+
self._author: Attribute[github.NamedUser.NamedUser | None] = NotSet
|
| 60 |
+
self._body: Attribute[str] = NotSet
|
| 61 |
+
self._body_html: Attribute[str] = NotSet
|
| 62 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 63 |
+
self._last_edited_at: Attribute[datetime] = NotSet
|
| 64 |
+
self._number: Attribute[int] = NotSet
|
| 65 |
+
self._title: Attribute[str] = NotSet
|
| 66 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 67 |
+
self._url: Attribute[str] = NotSet
|
| 68 |
+
|
| 69 |
+
def __repr__(self) -> str:
|
| 70 |
+
return self.get__repr__({"number": self._number.value, "title": self._title.value})
|
| 71 |
+
|
| 72 |
+
@property
|
| 73 |
+
def author(self) -> github.NamedUser.NamedUser | None:
|
| 74 |
+
self._completeIfNotSet(self._author)
|
| 75 |
+
return self._author.value
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def body(self) -> str:
|
| 79 |
+
self._completeIfNotSet(self._body)
|
| 80 |
+
return self._body.value
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def body_html(self) -> str:
|
| 84 |
+
self._completeIfNotSet(self._body_html)
|
| 85 |
+
return self._body_html.value
|
| 86 |
+
|
| 87 |
+
@property
|
| 88 |
+
def created_at(self) -> datetime:
|
| 89 |
+
self._completeIfNotSet(self._created_at)
|
| 90 |
+
return self._created_at.value
|
| 91 |
+
|
| 92 |
+
@property
|
| 93 |
+
def last_edited_at(self) -> datetime:
|
| 94 |
+
self._completeIfNotSet(self._last_edited_at)
|
| 95 |
+
return self._last_edited_at.value
|
| 96 |
+
|
| 97 |
+
@property
|
| 98 |
+
def number(self) -> int:
|
| 99 |
+
self._completeIfNotSet(self._number)
|
| 100 |
+
return self._number.value
|
| 101 |
+
|
| 102 |
+
@property
|
| 103 |
+
def title(self) -> str:
|
| 104 |
+
self._completeIfNotSet(self._title)
|
| 105 |
+
return self._title.value
|
| 106 |
+
|
| 107 |
+
@property
|
| 108 |
+
def updated_at(self) -> datetime:
|
| 109 |
+
self._completeIfNotSet(self._updated_at)
|
| 110 |
+
return self._updated_at.value
|
| 111 |
+
|
| 112 |
+
@property
|
| 113 |
+
def url(self) -> str:
|
| 114 |
+
self._completeIfNotSet(self._url)
|
| 115 |
+
return self._url.value
|
| 116 |
+
|
| 117 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 118 |
+
if "author" in attributes: # pragma no branch
|
| 119 |
+
self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"])
|
| 120 |
+
if "body" in attributes: # pragma no branch
|
| 121 |
+
self._body = self._makeStringAttribute(attributes["body"])
|
| 122 |
+
if "body_html" in attributes: # pragma no branch
|
| 123 |
+
self._body_html = self._makeStringAttribute(attributes["body_html"])
|
| 124 |
+
if "created_at" in attributes: # pragma no branch
|
| 125 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 126 |
+
if "last_edited_at" in attributes: # pragma no branch
|
| 127 |
+
self._last_edited_at = self._makeDatetimeAttribute(attributes["last_edited_at"])
|
| 128 |
+
if "number" in attributes: # pragma no branch
|
| 129 |
+
self._number = self._makeIntAttribute(attributes["number"])
|
| 130 |
+
if "title" in attributes:
|
| 131 |
+
self._title = self._makeStringAttribute(attributes["title"])
|
| 132 |
+
if "updated_at" in attributes: # pragma no branch
|
| 133 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 134 |
+
if "url" in attributes: # pragma no branch
|
| 135 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/DiscussionCommentBase.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Mark Walker <mark.walker@realbuzz.com> #
|
| 16 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
from __future__ import annotations
|
| 42 |
+
|
| 43 |
+
from datetime import datetime
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.GithubObject
|
| 47 |
+
import github.NamedUser
|
| 48 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class DiscussionCommentBase(CompletableGithubObject):
|
| 52 |
+
"""
|
| 53 |
+
This class represents a the shared attributes between RepositoryDiscussionComment and TeamDiscussionComment
|
| 54 |
+
https://docs.github.com/en/graphql/reference/objects#discussioncomment
|
| 55 |
+
https://docs.github.com/de/rest/teams/discussion-comments
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
def _initAttributes(self) -> None:
|
| 59 |
+
self._author: Attribute[github.NamedUser.NamedUser | None] = NotSet
|
| 60 |
+
self._body: Attribute[str] = NotSet
|
| 61 |
+
self._body_html: Attribute[str] = NotSet
|
| 62 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 63 |
+
self._html_url: Attribute[str] = NotSet
|
| 64 |
+
self._last_edited_at: Attribute[datetime] = NotSet
|
| 65 |
+
self._node_id: Attribute[str] = NotSet
|
| 66 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 67 |
+
self._url: Attribute[str] = NotSet
|
| 68 |
+
|
| 69 |
+
def __repr__(self) -> str:
|
| 70 |
+
return self.get__repr__({"node_id": self._node_id.value})
|
| 71 |
+
|
| 72 |
+
@property
|
| 73 |
+
def author(self) -> github.NamedUser.NamedUser | None:
|
| 74 |
+
self._completeIfNotSet(self._author)
|
| 75 |
+
return self._author.value
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def body(self) -> str:
|
| 79 |
+
self._completeIfNotSet(self._body)
|
| 80 |
+
return self._body.value
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def body_html(self) -> str:
|
| 84 |
+
self._completeIfNotSet(self._body_html)
|
| 85 |
+
return self._body_html.value
|
| 86 |
+
|
| 87 |
+
@property
|
| 88 |
+
def created_at(self) -> datetime:
|
| 89 |
+
self._completeIfNotSet(self._created_at)
|
| 90 |
+
return self._created_at.value
|
| 91 |
+
|
| 92 |
+
@property
|
| 93 |
+
def html_url(self) -> str:
|
| 94 |
+
self._completeIfNotSet(self._html_url)
|
| 95 |
+
return self._html_url.value
|
| 96 |
+
|
| 97 |
+
@property
|
| 98 |
+
def last_edited_at(self) -> datetime:
|
| 99 |
+
self._completeIfNotSet(self._last_edited_at)
|
| 100 |
+
return self._last_edited_at.value
|
| 101 |
+
|
| 102 |
+
@property
|
| 103 |
+
def node_id(self) -> str:
|
| 104 |
+
self._completeIfNotSet(self._node_id)
|
| 105 |
+
return self._node_id.value
|
| 106 |
+
|
| 107 |
+
@property
|
| 108 |
+
def updated_at(self) -> datetime:
|
| 109 |
+
self._completeIfNotSet(self._updated_at)
|
| 110 |
+
return self._updated_at.value
|
| 111 |
+
|
| 112 |
+
@property
|
| 113 |
+
def url(self) -> str:
|
| 114 |
+
self._completeIfNotSet(self._url)
|
| 115 |
+
return self._url.value
|
| 116 |
+
|
| 117 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 118 |
+
if "author" in attributes: # pragma no branch
|
| 119 |
+
self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"])
|
| 120 |
+
if "body" in attributes: # pragma no branch
|
| 121 |
+
self._body = self._makeStringAttribute(attributes["body"])
|
| 122 |
+
if "body_html" in attributes: # pragma no branch
|
| 123 |
+
self._body_html = self._makeStringAttribute(attributes["body_html"])
|
| 124 |
+
if "created_at" in attributes: # pragma no branch
|
| 125 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 126 |
+
if "html_url" in attributes: # pragma no branch
|
| 127 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 128 |
+
if "last_edited_at" in attributes: # pragma no branch
|
| 129 |
+
self._last_edited_at = self._makeDatetimeAttribute(attributes["last_edited_at"])
|
| 130 |
+
if "node_id" in attributes: # pragma no branch
|
| 131 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 132 |
+
if "updated_at" in attributes: # pragma no branch
|
| 133 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 134 |
+
if "url" in attributes: # pragma no branch
|
| 135 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/Download.py
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 17 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 18 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 19 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 20 |
+
# #
|
| 21 |
+
# This file is part of PyGithub. #
|
| 22 |
+
# http://pygithub.readthedocs.io/ #
|
| 23 |
+
# #
|
| 24 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 25 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 26 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 27 |
+
# any later version. #
|
| 28 |
+
# #
|
| 29 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 30 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 31 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 32 |
+
# details. #
|
| 33 |
+
# #
|
| 34 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 35 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 36 |
+
# #
|
| 37 |
+
################################################################################
|
| 38 |
+
|
| 39 |
+
from __future__ import annotations
|
| 40 |
+
|
| 41 |
+
from datetime import datetime
|
| 42 |
+
from typing import Any
|
| 43 |
+
|
| 44 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class Download(CompletableGithubObject):
|
| 48 |
+
"""
|
| 49 |
+
This class represents Downloads.
|
| 50 |
+
|
| 51 |
+
The reference can be found here
|
| 52 |
+
https://docs.github.com/en/rest/reference/repos
|
| 53 |
+
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
def _initAttributes(self) -> None:
|
| 57 |
+
self._accesskeyid: Attribute[str] = NotSet
|
| 58 |
+
self._acl: Attribute[str] = NotSet
|
| 59 |
+
self._bucket: Attribute[str] = NotSet
|
| 60 |
+
self._content_type: Attribute[str] = NotSet
|
| 61 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 62 |
+
self._description: Attribute[str] = NotSet
|
| 63 |
+
self._download_count: Attribute[int] = NotSet
|
| 64 |
+
self._expirationdate: Attribute[datetime] = NotSet
|
| 65 |
+
self._html_url: Attribute[str] = NotSet
|
| 66 |
+
self._id: Attribute[int] = NotSet
|
| 67 |
+
self._mime_type: Attribute[str] = NotSet
|
| 68 |
+
self._name: Attribute[str] = NotSet
|
| 69 |
+
self._path: Attribute[str] = NotSet
|
| 70 |
+
self._policy: Attribute[str] = NotSet
|
| 71 |
+
self._prefix: Attribute[str] = NotSet
|
| 72 |
+
self._redirect: Attribute[bool] = NotSet
|
| 73 |
+
self._s3_url: Attribute[str] = NotSet
|
| 74 |
+
self._signature: Attribute[str] = NotSet
|
| 75 |
+
self._size: Attribute[int] = NotSet
|
| 76 |
+
self._url: Attribute[str] = NotSet
|
| 77 |
+
|
| 78 |
+
def __repr__(self) -> str:
|
| 79 |
+
return self.get__repr__({"id": self._id.value})
|
| 80 |
+
|
| 81 |
+
@property
|
| 82 |
+
def accesskeyid(self) -> str:
|
| 83 |
+
self._completeIfNotSet(self._accesskeyid)
|
| 84 |
+
return self._accesskeyid.value
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def acl(self) -> str:
|
| 88 |
+
self._completeIfNotSet(self._acl)
|
| 89 |
+
return self._acl.value
|
| 90 |
+
|
| 91 |
+
@property
|
| 92 |
+
def bucket(self) -> str:
|
| 93 |
+
self._completeIfNotSet(self._bucket)
|
| 94 |
+
return self._bucket.value
|
| 95 |
+
|
| 96 |
+
@property
|
| 97 |
+
def content_type(self) -> str:
|
| 98 |
+
self._completeIfNotSet(self._content_type)
|
| 99 |
+
return self._content_type.value
|
| 100 |
+
|
| 101 |
+
@property
|
| 102 |
+
def created_at(self) -> datetime:
|
| 103 |
+
self._completeIfNotSet(self._created_at)
|
| 104 |
+
return self._created_at.value
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def description(self) -> str:
|
| 108 |
+
self._completeIfNotSet(self._description)
|
| 109 |
+
return self._description.value
|
| 110 |
+
|
| 111 |
+
@property
|
| 112 |
+
def download_count(self) -> int:
|
| 113 |
+
self._completeIfNotSet(self._download_count)
|
| 114 |
+
return self._download_count.value
|
| 115 |
+
|
| 116 |
+
@property
|
| 117 |
+
def expirationdate(self) -> datetime:
|
| 118 |
+
self._completeIfNotSet(self._expirationdate)
|
| 119 |
+
return self._expirationdate.value
|
| 120 |
+
|
| 121 |
+
@property
|
| 122 |
+
def html_url(self) -> str:
|
| 123 |
+
self._completeIfNotSet(self._html_url)
|
| 124 |
+
return self._html_url.value
|
| 125 |
+
|
| 126 |
+
@property
|
| 127 |
+
def id(self) -> int:
|
| 128 |
+
self._completeIfNotSet(self._id)
|
| 129 |
+
return self._id.value
|
| 130 |
+
|
| 131 |
+
@property
|
| 132 |
+
def mime_type(self) -> str:
|
| 133 |
+
self._completeIfNotSet(self._mime_type)
|
| 134 |
+
return self._mime_type.value
|
| 135 |
+
|
| 136 |
+
@property
|
| 137 |
+
def name(self) -> str:
|
| 138 |
+
self._completeIfNotSet(self._name)
|
| 139 |
+
return self._name.value
|
| 140 |
+
|
| 141 |
+
@property
|
| 142 |
+
def path(self) -> str:
|
| 143 |
+
self._completeIfNotSet(self._path)
|
| 144 |
+
return self._path.value
|
| 145 |
+
|
| 146 |
+
@property
|
| 147 |
+
def policy(self) -> str:
|
| 148 |
+
self._completeIfNotSet(self._policy)
|
| 149 |
+
return self._policy.value
|
| 150 |
+
|
| 151 |
+
@property
|
| 152 |
+
def prefix(self) -> str:
|
| 153 |
+
self._completeIfNotSet(self._prefix)
|
| 154 |
+
return self._prefix.value
|
| 155 |
+
|
| 156 |
+
@property
|
| 157 |
+
def redirect(self) -> bool:
|
| 158 |
+
self._completeIfNotSet(self._redirect)
|
| 159 |
+
return self._redirect.value
|
| 160 |
+
|
| 161 |
+
@property
|
| 162 |
+
def s3_url(self) -> str:
|
| 163 |
+
self._completeIfNotSet(self._s3_url)
|
| 164 |
+
return self._s3_url.value
|
| 165 |
+
|
| 166 |
+
@property
|
| 167 |
+
def signature(self) -> str:
|
| 168 |
+
self._completeIfNotSet(self._signature)
|
| 169 |
+
return self._signature.value
|
| 170 |
+
|
| 171 |
+
@property
|
| 172 |
+
def size(self) -> int:
|
| 173 |
+
self._completeIfNotSet(self._size)
|
| 174 |
+
return self._size.value
|
| 175 |
+
|
| 176 |
+
@property
|
| 177 |
+
def url(self) -> str:
|
| 178 |
+
self._completeIfNotSet(self._url)
|
| 179 |
+
return self._url.value
|
| 180 |
+
|
| 181 |
+
def delete(self) -> None:
|
| 182 |
+
"""
|
| 183 |
+
:calls: `DELETE /repos/{owner}/{repo}/downloads/{id} <https://docs.github.com/en/rest/reference/repos>`_
|
| 184 |
+
"""
|
| 185 |
+
headers, data = self._requester.requestJsonAndCheck("DELETE", self.url)
|
| 186 |
+
|
| 187 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 188 |
+
if "accesskeyid" in attributes: # pragma no branch
|
| 189 |
+
self._accesskeyid = self._makeStringAttribute(
|
| 190 |
+
attributes["accesskeyid"]
|
| 191 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 192 |
+
if "acl" in attributes: # pragma no branch
|
| 193 |
+
self._acl = self._makeStringAttribute(
|
| 194 |
+
attributes["acl"]
|
| 195 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 196 |
+
if "bucket" in attributes: # pragma no branch
|
| 197 |
+
self._bucket = self._makeStringAttribute(
|
| 198 |
+
attributes["bucket"]
|
| 199 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 200 |
+
if "content_type" in attributes: # pragma no branch
|
| 201 |
+
self._content_type = self._makeStringAttribute(attributes["content_type"])
|
| 202 |
+
if "created_at" in attributes: # pragma no branch
|
| 203 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 204 |
+
if "description" in attributes: # pragma no branch
|
| 205 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 206 |
+
if "download_count" in attributes: # pragma no branch
|
| 207 |
+
self._download_count = self._makeIntAttribute(attributes["download_count"])
|
| 208 |
+
if "expirationdate" in attributes: # pragma no branch
|
| 209 |
+
self._expirationdate = self._makeDatetimeAttribute(
|
| 210 |
+
attributes["expirationdate"]
|
| 211 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 212 |
+
if "html_url" in attributes: # pragma no branch
|
| 213 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 214 |
+
if "id" in attributes: # pragma no branch
|
| 215 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 216 |
+
if "mime_type" in attributes: # pragma no branch
|
| 217 |
+
self._mime_type = self._makeStringAttribute(
|
| 218 |
+
attributes["mime_type"]
|
| 219 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 220 |
+
if "name" in attributes: # pragma no branch
|
| 221 |
+
self._name = self._makeStringAttribute(attributes["name"])
|
| 222 |
+
if "path" in attributes: # pragma no branch
|
| 223 |
+
self._path = self._makeStringAttribute(
|
| 224 |
+
attributes["path"]
|
| 225 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 226 |
+
if "policy" in attributes: # pragma no branch
|
| 227 |
+
self._policy = self._makeStringAttribute(
|
| 228 |
+
attributes["policy"]
|
| 229 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 230 |
+
if "prefix" in attributes: # pragma no branch
|
| 231 |
+
self._prefix = self._makeStringAttribute(
|
| 232 |
+
attributes["prefix"]
|
| 233 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 234 |
+
if "redirect" in attributes: # pragma no branch
|
| 235 |
+
self._redirect = self._makeBoolAttribute(
|
| 236 |
+
attributes["redirect"]
|
| 237 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 238 |
+
if "s3_url" in attributes: # pragma no branch
|
| 239 |
+
self._s3_url = self._makeStringAttribute(
|
| 240 |
+
attributes["s3_url"]
|
| 241 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 242 |
+
if "signature" in attributes: # pragma no branch
|
| 243 |
+
self._signature = self._makeStringAttribute(
|
| 244 |
+
attributes["signature"]
|
| 245 |
+
) # pragma no cover (was covered only by create_download, which has been removed)
|
| 246 |
+
if "size" in attributes: # pragma no branch
|
| 247 |
+
self._size = self._makeIntAttribute(attributes["size"])
|
| 248 |
+
if "url" in attributes: # pragma no branch
|
| 249 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/Enterprise.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 16 |
+
# Copyright 2023 Mark Amery <markamery@btinternet.com> #
|
| 17 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 18 |
+
# Copyright 2023 YugoHino <henom06@gmail.com> #
|
| 19 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 20 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 21 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
import urllib.parse
|
| 42 |
+
from typing import Any, Dict
|
| 43 |
+
|
| 44 |
+
from github.EnterpriseConsumedLicenses import EnterpriseConsumedLicenses
|
| 45 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 46 |
+
from github.Requester import Requester
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class Enterprise(NonCompletableGithubObject):
|
| 50 |
+
"""
|
| 51 |
+
This class represents Enterprises.
|
| 52 |
+
|
| 53 |
+
Such objects do not exist in the Github API, so this class merely collects all endpoints the start with
|
| 54 |
+
/enterprises/{enterprise}/. See methods below for specific endpoints and docs.
|
| 55 |
+
https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin?apiVersion=2022-11-28
|
| 56 |
+
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
def _initAttributes(self) -> None:
|
| 60 |
+
self._enterprise: Attribute[str] = NotSet
|
| 61 |
+
self._url: Attribute[str] = NotSet
|
| 62 |
+
|
| 63 |
+
def __init__(
|
| 64 |
+
self,
|
| 65 |
+
requester: Requester,
|
| 66 |
+
enterprise: str,
|
| 67 |
+
):
|
| 68 |
+
enterprise = urllib.parse.quote(enterprise)
|
| 69 |
+
super().__init__(requester, {}, {"enterprise": enterprise, "url": f"/enterprises/{enterprise}"})
|
| 70 |
+
|
| 71 |
+
def __repr__(self) -> str:
|
| 72 |
+
return self.get__repr__({"enterprise": self._enterprise.value})
|
| 73 |
+
|
| 74 |
+
@property
|
| 75 |
+
def enterprise(self) -> str:
|
| 76 |
+
return self._enterprise.value
|
| 77 |
+
|
| 78 |
+
@property
|
| 79 |
+
def url(self) -> str:
|
| 80 |
+
return self._url.value
|
| 81 |
+
|
| 82 |
+
def get_consumed_licenses(self) -> EnterpriseConsumedLicenses:
|
| 83 |
+
"""
|
| 84 |
+
:calls: `GET /enterprises/{enterprise}/consumed-licenses <https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/license#list-enterprise-consumed-licenses>`_
|
| 85 |
+
"""
|
| 86 |
+
headers, data = self._requester.requestJsonAndCheck("GET", self.url + "/consumed-licenses")
|
| 87 |
+
if "url" not in data:
|
| 88 |
+
data["url"] = self.url + "/consumed-licenses"
|
| 89 |
+
|
| 90 |
+
return EnterpriseConsumedLicenses(self._requester, headers, data, completed=True)
|
| 91 |
+
|
| 92 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 93 |
+
if "enterprise" in attributes: # pragma no branch
|
| 94 |
+
self._enterprise = self._makeStringAttribute(attributes["enterprise"])
|
| 95 |
+
if "url" in attributes: # pragma no branch
|
| 96 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/EnterpriseConsumedLicenses.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 17 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 18 |
+
# Copyright 2023 YugoHino <henom06@gmail.com> #
|
| 19 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 20 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 21 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
from typing import Any, Dict
|
| 42 |
+
|
| 43 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 44 |
+
from github.NamedEnterpriseUser import NamedEnterpriseUser
|
| 45 |
+
from github.PaginatedList import PaginatedList
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
class EnterpriseConsumedLicenses(CompletableGithubObject):
|
| 49 |
+
"""
|
| 50 |
+
This class represents license consumed by enterprises.
|
| 51 |
+
|
| 52 |
+
The reference can be found here
|
| 53 |
+
https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/license#list-enterprise-consumed-licenses
|
| 54 |
+
|
| 55 |
+
"""
|
| 56 |
+
|
| 57 |
+
def _initAttributes(self) -> None:
|
| 58 |
+
self._enterprise: Attribute[str] = NotSet
|
| 59 |
+
self._total_seats_consumed: Attribute[int] = NotSet
|
| 60 |
+
self._total_seats_purchased: Attribute[int] = NotSet
|
| 61 |
+
self._url: Attribute[str] = NotSet
|
| 62 |
+
|
| 63 |
+
def __repr__(self) -> str:
|
| 64 |
+
return self.get__repr__({"enterprise": self._enterprise.value})
|
| 65 |
+
|
| 66 |
+
@property
|
| 67 |
+
def enterprise(self) -> str:
|
| 68 |
+
self._completeIfNotSet(self._enterprise)
|
| 69 |
+
return self._enterprise.value
|
| 70 |
+
|
| 71 |
+
@property
|
| 72 |
+
def total_seats_consumed(self) -> int:
|
| 73 |
+
return self._total_seats_consumed.value
|
| 74 |
+
|
| 75 |
+
@property
|
| 76 |
+
def total_seats_purchased(self) -> int:
|
| 77 |
+
return self._total_seats_purchased.value
|
| 78 |
+
|
| 79 |
+
@property
|
| 80 |
+
def url(self) -> str:
|
| 81 |
+
self._completeIfNotSet(self._url)
|
| 82 |
+
return self._url.value
|
| 83 |
+
|
| 84 |
+
def get_users(self) -> PaginatedList[NamedEnterpriseUser]:
|
| 85 |
+
"""
|
| 86 |
+
:calls: `GET /enterprises/{enterprise}/consumed-licenses <https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/license#list-enterprise-consumed-licenses>`_
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
url_parameters: Dict[str, Any] = {}
|
| 90 |
+
return PaginatedList(
|
| 91 |
+
NamedEnterpriseUser,
|
| 92 |
+
self._requester,
|
| 93 |
+
self.url,
|
| 94 |
+
url_parameters,
|
| 95 |
+
headers=None,
|
| 96 |
+
list_item="users",
|
| 97 |
+
firstData=self.raw_data,
|
| 98 |
+
firstHeaders=self.raw_headers,
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 102 |
+
if "enterprise" in attributes: # pragma no branch
|
| 103 |
+
self._enterprise = self._makeStringAttribute(attributes["enterprise"])
|
| 104 |
+
if "total_seats_consumed" in attributes: # pragma no branch
|
| 105 |
+
self._total_seats_consumed = self._makeIntAttribute(attributes["total_seats_consumed"])
|
| 106 |
+
if "total_seats_purchased" in attributes: # pragma no branch
|
| 107 |
+
self._total_seats_purchased = self._makeIntAttribute(attributes["total_seats_purchased"])
|
| 108 |
+
if "url" in attributes: # pragma no branch
|
| 109 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/Environment.py
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2017 Jannis Gebauer <ja.geb@me.com> #
|
| 11 |
+
# Copyright 2017 Simon <spam@esemi.ru> #
|
| 12 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 14 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 15 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Andrew Dawes <53574062+AndrewJDawes@users.noreply.github.com> #
|
| 18 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2023 alson <git@alm.nufan.net> #
|
| 21 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 23 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 24 |
+
# #
|
| 25 |
+
# This file is part of PyGithub. #
|
| 26 |
+
# http://pygithub.readthedocs.io/ #
|
| 27 |
+
# #
|
| 28 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 29 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 30 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 31 |
+
# any later version. #
|
| 32 |
+
# #
|
| 33 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 34 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 35 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 36 |
+
# details. #
|
| 37 |
+
# #
|
| 38 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 39 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 40 |
+
# #
|
| 41 |
+
################################################################################
|
| 42 |
+
|
| 43 |
+
from __future__ import annotations
|
| 44 |
+
|
| 45 |
+
from datetime import datetime
|
| 46 |
+
from typing import TYPE_CHECKING, Any
|
| 47 |
+
|
| 48 |
+
import github.EnvironmentDeploymentBranchPolicy
|
| 49 |
+
import github.EnvironmentProtectionRule
|
| 50 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 51 |
+
from github.PaginatedList import PaginatedList
|
| 52 |
+
from github.PublicKey import PublicKey
|
| 53 |
+
from github.Secret import Secret
|
| 54 |
+
from github.Variable import Variable
|
| 55 |
+
|
| 56 |
+
if TYPE_CHECKING:
|
| 57 |
+
from github.EnvironmentDeploymentBranchPolicy import EnvironmentDeploymentBranchPolicy
|
| 58 |
+
from github.EnvironmentProtectionRule import EnvironmentProtectionRule
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
class Environment(CompletableGithubObject):
|
| 62 |
+
"""
|
| 63 |
+
This class represents Environment.
|
| 64 |
+
|
| 65 |
+
The reference can be found here
|
| 66 |
+
https://docs.github.com/en/rest/reference/deployments#environments
|
| 67 |
+
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
def _initAttributes(self) -> None:
|
| 71 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 72 |
+
self._deployment_branch_policy: Attribute[EnvironmentDeploymentBranchPolicy] = NotSet
|
| 73 |
+
self._environments_url: Attribute[str] = NotSet
|
| 74 |
+
self._html_url: Attribute[str] = NotSet
|
| 75 |
+
self._id: Attribute[int] = NotSet
|
| 76 |
+
self._name: Attribute[str] = NotSet
|
| 77 |
+
self._node_id: Attribute[str] = NotSet
|
| 78 |
+
self._protection_rules: Attribute[list[EnvironmentProtectionRule]] = NotSet
|
| 79 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 80 |
+
self._url: Attribute[str] = NotSet
|
| 81 |
+
|
| 82 |
+
def __repr__(self) -> str:
|
| 83 |
+
return self.get__repr__({"name": self._name.value})
|
| 84 |
+
|
| 85 |
+
@property
|
| 86 |
+
def created_at(self) -> datetime:
|
| 87 |
+
self._completeIfNotSet(self._created_at)
|
| 88 |
+
return self._created_at.value
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def deployment_branch_policy(
|
| 92 |
+
self,
|
| 93 |
+
) -> EnvironmentDeploymentBranchPolicy:
|
| 94 |
+
self._completeIfNotSet(self._deployment_branch_policy)
|
| 95 |
+
return self._deployment_branch_policy.value
|
| 96 |
+
|
| 97 |
+
@property
|
| 98 |
+
def environments_url(self) -> str:
|
| 99 |
+
"""
|
| 100 |
+
:type: string
|
| 101 |
+
"""
|
| 102 |
+
return self._environments_url.value
|
| 103 |
+
|
| 104 |
+
@property
|
| 105 |
+
def html_url(self) -> str:
|
| 106 |
+
self._completeIfNotSet(self._html_url)
|
| 107 |
+
return self._html_url.value
|
| 108 |
+
|
| 109 |
+
@property
|
| 110 |
+
def id(self) -> int:
|
| 111 |
+
self._completeIfNotSet(self._id)
|
| 112 |
+
return self._id.value
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
def name(self) -> str:
|
| 116 |
+
self._completeIfNotSet(self._name)
|
| 117 |
+
return self._name.value
|
| 118 |
+
|
| 119 |
+
@property
|
| 120 |
+
def node_id(self) -> str:
|
| 121 |
+
self._completeIfNotSet(self._node_id)
|
| 122 |
+
return self._node_id.value
|
| 123 |
+
|
| 124 |
+
@property
|
| 125 |
+
def protection_rules(
|
| 126 |
+
self,
|
| 127 |
+
) -> list[EnvironmentProtectionRule]:
|
| 128 |
+
self._completeIfNotSet(self._protection_rules)
|
| 129 |
+
return self._protection_rules.value
|
| 130 |
+
|
| 131 |
+
@property
|
| 132 |
+
def updated_at(self) -> datetime:
|
| 133 |
+
self._completeIfNotSet(self._updated_at)
|
| 134 |
+
return self._updated_at.value
|
| 135 |
+
|
| 136 |
+
@property
|
| 137 |
+
def url(self) -> str:
|
| 138 |
+
"""
|
| 139 |
+
:type: string
|
| 140 |
+
"""
|
| 141 |
+
# Construct url from environments_url and name, if self._url. is not set
|
| 142 |
+
if self._url is NotSet:
|
| 143 |
+
self._url = self._makeStringAttribute(self.environments_url + "/" + self.name)
|
| 144 |
+
return self._url.value
|
| 145 |
+
|
| 146 |
+
def get_public_key(self) -> PublicKey:
|
| 147 |
+
"""
|
| 148 |
+
:calls: `GET /repositories/{repository_id}/environments/{environment_name}/secrets/public-key <https://docs.github.com/en/rest/reference#get-a-repository-public-key>`_
|
| 149 |
+
:rtype: :class:`PublicKey`
|
| 150 |
+
"""
|
| 151 |
+
# https://stackoverflow.com/a/76474814
|
| 152 |
+
# https://docs.github.com/en/rest/secrets?apiVersion=2022-11-28#get-an-environment-public-key
|
| 153 |
+
headers, data = self._requester.requestJsonAndCheck("GET", f"{self.url}/secrets/public-key")
|
| 154 |
+
return PublicKey(self._requester, headers, data, completed=True)
|
| 155 |
+
|
| 156 |
+
def create_secret(self, secret_name: str, unencrypted_value: str) -> Secret:
|
| 157 |
+
"""
|
| 158 |
+
:calls: `PUT /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name} <https://docs.github.com/en/rest/secrets#get-a-repository-secret>`_
|
| 159 |
+
"""
|
| 160 |
+
assert isinstance(secret_name, str), secret_name
|
| 161 |
+
assert isinstance(unencrypted_value, str), unencrypted_value
|
| 162 |
+
public_key = self.get_public_key()
|
| 163 |
+
payload = public_key.encrypt(unencrypted_value)
|
| 164 |
+
put_parameters = {
|
| 165 |
+
"key_id": public_key.key_id,
|
| 166 |
+
"encrypted_value": payload,
|
| 167 |
+
}
|
| 168 |
+
self._requester.requestJsonAndCheck("PUT", f"{self.url}/secrets/{secret_name}", input=put_parameters)
|
| 169 |
+
return Secret(
|
| 170 |
+
requester=self._requester,
|
| 171 |
+
headers={},
|
| 172 |
+
attributes={
|
| 173 |
+
"name": secret_name,
|
| 174 |
+
"url": f"{self.url}/secrets/{secret_name}",
|
| 175 |
+
},
|
| 176 |
+
completed=False,
|
| 177 |
+
)
|
| 178 |
+
|
| 179 |
+
def get_secrets(self) -> PaginatedList[Secret]:
|
| 180 |
+
"""
|
| 181 |
+
Gets all repository secrets.
|
| 182 |
+
"""
|
| 183 |
+
return PaginatedList(
|
| 184 |
+
Secret,
|
| 185 |
+
self._requester,
|
| 186 |
+
f"{self.url}/secrets",
|
| 187 |
+
None,
|
| 188 |
+
attributesTransformer=PaginatedList.override_attributes({"secrets_url": f"{self.url}/secrets"}),
|
| 189 |
+
list_item="secrets",
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
+
def get_secret(self, secret_name: str) -> Secret:
|
| 193 |
+
"""
|
| 194 |
+
:calls: 'GET /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name} <https://docs.github.com/en/rest/secrets#get-an-organization-secret>`_
|
| 195 |
+
"""
|
| 196 |
+
assert isinstance(secret_name, str), secret_name
|
| 197 |
+
return Secret(
|
| 198 |
+
requester=self._requester,
|
| 199 |
+
headers={},
|
| 200 |
+
attributes={"url": f"{self.url}/secrets/{secret_name}"},
|
| 201 |
+
completed=False,
|
| 202 |
+
)
|
| 203 |
+
|
| 204 |
+
def create_variable(self, variable_name: str, value: str) -> Variable:
|
| 205 |
+
"""
|
| 206 |
+
:calls: `POST /repositories/{repository_id}/environments/{environment_name}/variables/{variable_name} <https://docs.github.com/en/rest/variables#create-a-repository-variable>`_
|
| 207 |
+
"""
|
| 208 |
+
assert isinstance(variable_name, str), variable_name
|
| 209 |
+
assert isinstance(value, str), value
|
| 210 |
+
post_parameters = {
|
| 211 |
+
"name": variable_name,
|
| 212 |
+
"value": value,
|
| 213 |
+
}
|
| 214 |
+
self._requester.requestJsonAndCheck("POST", f"{self.url}/variables", input=post_parameters)
|
| 215 |
+
return Variable(
|
| 216 |
+
self._requester,
|
| 217 |
+
headers={},
|
| 218 |
+
attributes={
|
| 219 |
+
"name": variable_name,
|
| 220 |
+
"value": value,
|
| 221 |
+
"url": f"{self.url}/variables/{variable_name}",
|
| 222 |
+
},
|
| 223 |
+
completed=False,
|
| 224 |
+
)
|
| 225 |
+
|
| 226 |
+
def get_variables(self) -> PaginatedList[Variable]:
|
| 227 |
+
"""
|
| 228 |
+
Gets all repository variables :rtype: :class:`PaginatedList` of :class:`Variable`
|
| 229 |
+
"""
|
| 230 |
+
return PaginatedList(
|
| 231 |
+
Variable,
|
| 232 |
+
self._requester,
|
| 233 |
+
f"{self.url}/variables",
|
| 234 |
+
None,
|
| 235 |
+
attributesTransformer=PaginatedList.override_attributes({"variables_url": f"{self.url}/variables"}),
|
| 236 |
+
list_item="variables",
|
| 237 |
+
)
|
| 238 |
+
|
| 239 |
+
def get_variable(self, variable_name: str) -> Variable:
|
| 240 |
+
"""
|
| 241 |
+
:calls: 'GET /orgs/{org}/variables/{variable_name} <https://docs.github.com/en/rest/variables#get-an-organization-variable>`_
|
| 242 |
+
:param variable_name: string
|
| 243 |
+
:rtype: Variable
|
| 244 |
+
"""
|
| 245 |
+
assert isinstance(variable_name, str), variable_name
|
| 246 |
+
return Variable(
|
| 247 |
+
requester=self._requester,
|
| 248 |
+
headers={},
|
| 249 |
+
attributes={"url": f"{self.url}/variables/{variable_name}"},
|
| 250 |
+
completed=False,
|
| 251 |
+
)
|
| 252 |
+
|
| 253 |
+
def delete_secret(self, secret_name: str) -> bool:
|
| 254 |
+
"""
|
| 255 |
+
:calls: `DELETE /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name} <https://docs.github.com/en/rest/reference#delete-a-repository-secret>`_
|
| 256 |
+
:param secret_name: string
|
| 257 |
+
:rtype: bool
|
| 258 |
+
"""
|
| 259 |
+
assert isinstance(secret_name, str), secret_name
|
| 260 |
+
status, headers, data = self._requester.requestJson("DELETE", f"{self.url}/secrets/{secret_name}")
|
| 261 |
+
return status == 204
|
| 262 |
+
|
| 263 |
+
def delete_variable(self, variable_name: str) -> bool:
|
| 264 |
+
"""
|
| 265 |
+
:calls: `DELETE /repositories/{repository_id}/environments/{environment_name}/variables/{variable_name} <https://docs.github.com/en/rest/reference#delete-a-repository-variable>`_
|
| 266 |
+
:param variable_name: string
|
| 267 |
+
:rtype: bool
|
| 268 |
+
"""
|
| 269 |
+
assert isinstance(variable_name, str), variable_name
|
| 270 |
+
status, headers, data = self._requester.requestJson("DELETE", f"{self.url}/variables/{variable_name}")
|
| 271 |
+
return status == 204
|
| 272 |
+
|
| 273 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 274 |
+
if "created_at" in attributes: # pragma no branch
|
| 275 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 276 |
+
if "deployment_branch_policy" in attributes: # pragma no branch
|
| 277 |
+
self._deployment_branch_policy = self._makeClassAttribute(
|
| 278 |
+
github.EnvironmentDeploymentBranchPolicy.EnvironmentDeploymentBranchPolicy,
|
| 279 |
+
attributes["deployment_branch_policy"],
|
| 280 |
+
)
|
| 281 |
+
if "environments_url" in attributes:
|
| 282 |
+
self._environments_url = self._makeStringAttribute(attributes["environments_url"])
|
| 283 |
+
if "html_url" in attributes: # pragma no branch
|
| 284 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 285 |
+
if "id" in attributes: # pragma no branch
|
| 286 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 287 |
+
if "name" in attributes: # pragma no branch
|
| 288 |
+
self._name = self._makeStringAttribute(attributes["name"])
|
| 289 |
+
if "node_id" in attributes: # pragma no branch
|
| 290 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 291 |
+
if "protection_rules" in attributes: # pragma no branch
|
| 292 |
+
self._protection_rules = self._makeListOfClassesAttribute(
|
| 293 |
+
github.EnvironmentProtectionRule.EnvironmentProtectionRule,
|
| 294 |
+
attributes["protection_rules"],
|
| 295 |
+
)
|
| 296 |
+
if "updated_at" in attributes: # pragma no branch
|
| 297 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 298 |
+
if "url" in attributes: # pragma no branch
|
| 299 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
venv/lib/python3.10/site-packages/github/EnvironmentDeploymentBranchPolicy.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 4 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 5 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 6 |
+
# Copyright 2023 alson <git@alm.nufan.net> #
|
| 7 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 8 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 9 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 10 |
+
# #
|
| 11 |
+
# This file is part of PyGithub. #
|
| 12 |
+
# http://pygithub.readthedocs.io/ #
|
| 13 |
+
# #
|
| 14 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 15 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 16 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 17 |
+
# any later version. #
|
| 18 |
+
# #
|
| 19 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 20 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 21 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 22 |
+
# details. #
|
| 23 |
+
# #
|
| 24 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 25 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 26 |
+
# #
|
| 27 |
+
################################################################################
|
| 28 |
+
|
| 29 |
+
from typing import Any, Dict
|
| 30 |
+
|
| 31 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class EnvironmentDeploymentBranchPolicy(NonCompletableGithubObject):
|
| 35 |
+
"""
|
| 36 |
+
This class represents a deployment branch policy for an environment.
|
| 37 |
+
|
| 38 |
+
The reference can be found here
|
| 39 |
+
https://docs.github.com/en/rest/reference/deployments#environments
|
| 40 |
+
|
| 41 |
+
"""
|
| 42 |
+
|
| 43 |
+
def _initAttributes(self) -> None:
|
| 44 |
+
self._custom_branch_policies: Attribute[bool] = NotSet
|
| 45 |
+
self._protected_branches: Attribute[bool] = NotSet
|
| 46 |
+
|
| 47 |
+
def __repr__(self) -> str:
|
| 48 |
+
return self.get__repr__({})
|
| 49 |
+
|
| 50 |
+
@property
|
| 51 |
+
def custom_branch_policies(self) -> bool:
|
| 52 |
+
return self._custom_branch_policies.value
|
| 53 |
+
|
| 54 |
+
@property
|
| 55 |
+
def protected_branches(self) -> bool:
|
| 56 |
+
return self._protected_branches.value
|
| 57 |
+
|
| 58 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 59 |
+
if "custom_branch_policies" in attributes: # pragma no branch
|
| 60 |
+
self._custom_branch_policies = self._makeBoolAttribute(attributes["custom_branch_policies"])
|
| 61 |
+
if "protected_branches" in attributes: # pragma no branch
|
| 62 |
+
self._protected_branches = self._makeBoolAttribute(attributes["protected_branches"])
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class EnvironmentDeploymentBranchPolicyParams:
|
| 66 |
+
"""
|
| 67 |
+
This class presents the deployment branch policy parameters as can be configured for an Environment.
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
def __init__(self, protected_branches: bool = False, custom_branch_policies: bool = False):
|
| 71 |
+
assert isinstance(protected_branches, bool)
|
| 72 |
+
assert isinstance(custom_branch_policies, bool)
|
| 73 |
+
self.protected_branches = protected_branches
|
| 74 |
+
self.custom_branch_policies = custom_branch_policies
|
| 75 |
+
|
| 76 |
+
def _asdict(self) -> dict:
|
| 77 |
+
return {
|
| 78 |
+
"protected_branches": self.protected_branches,
|
| 79 |
+
"custom_branch_policies": self.custom_branch_policies,
|
| 80 |
+
}
|
venv/lib/python3.10/site-packages/github/EnvironmentProtectionRule.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 6 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 8 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 9 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 10 |
+
# Copyright 2019 Adam Baratz <adam.baratz@gmail.com> #
|
| 11 |
+
# Copyright 2019 Nick Campbell <nicholas.j.campbell@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2022 Marco Köpcke <hello@parakoopa.de> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2023 alson <git@alm.nufan.net> #
|
| 21 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 23 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 24 |
+
# #
|
| 25 |
+
# This file is part of PyGithub. #
|
| 26 |
+
# http://pygithub.readthedocs.io/ #
|
| 27 |
+
# #
|
| 28 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 29 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 30 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 31 |
+
# any later version. #
|
| 32 |
+
# #
|
| 33 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 34 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 35 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 36 |
+
# details. #
|
| 37 |
+
# #
|
| 38 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 39 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 40 |
+
# #
|
| 41 |
+
################################################################################
|
| 42 |
+
|
| 43 |
+
from __future__ import annotations
|
| 44 |
+
|
| 45 |
+
from typing import TYPE_CHECKING, Any
|
| 46 |
+
|
| 47 |
+
import github.EnvironmentProtectionRuleReviewer
|
| 48 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 49 |
+
|
| 50 |
+
if TYPE_CHECKING:
|
| 51 |
+
from github.EnvironmentProtectionRuleReviewer import EnvironmentProtectionRuleReviewer
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
class EnvironmentProtectionRule(NonCompletableGithubObject):
|
| 55 |
+
"""
|
| 56 |
+
This class represents a protection rule for an environment.
|
| 57 |
+
|
| 58 |
+
The reference can be found here
|
| 59 |
+
https://docs.github.com/en/rest/reference/deployments#environments
|
| 60 |
+
|
| 61 |
+
"""
|
| 62 |
+
|
| 63 |
+
def _initAttributes(self) -> None:
|
| 64 |
+
self._id: Attribute[int] = NotSet
|
| 65 |
+
self._node_id: Attribute[str] = NotSet
|
| 66 |
+
self._reviewers: Attribute[list[EnvironmentProtectionRuleReviewer]] = NotSet
|
| 67 |
+
self._type: Attribute[str] = NotSet
|
| 68 |
+
self._wait_timer: Attribute[int] = NotSet
|
| 69 |
+
|
| 70 |
+
def __repr__(self) -> str:
|
| 71 |
+
return self.get__repr__({"id": self._id.value})
|
| 72 |
+
|
| 73 |
+
@property
|
| 74 |
+
def id(self) -> int:
|
| 75 |
+
return self._id.value
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def node_id(self) -> str:
|
| 79 |
+
return self._node_id.value
|
| 80 |
+
|
| 81 |
+
@property
|
| 82 |
+
def reviewers(
|
| 83 |
+
self,
|
| 84 |
+
) -> list[EnvironmentProtectionRuleReviewer]:
|
| 85 |
+
return self._reviewers.value
|
| 86 |
+
|
| 87 |
+
@property
|
| 88 |
+
def type(self) -> str:
|
| 89 |
+
return self._type.value
|
| 90 |
+
|
| 91 |
+
@property
|
| 92 |
+
def wait_timer(self) -> int:
|
| 93 |
+
return self._wait_timer.value
|
| 94 |
+
|
| 95 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 96 |
+
if "id" in attributes: # pragma no branch
|
| 97 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 98 |
+
if "node_id" in attributes: # pragma no branch
|
| 99 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 100 |
+
if "reviewers" in attributes: # pragma no branch
|
| 101 |
+
self._reviewers = self._makeListOfClassesAttribute(
|
| 102 |
+
github.EnvironmentProtectionRuleReviewer.EnvironmentProtectionRuleReviewer,
|
| 103 |
+
attributes["reviewers"],
|
| 104 |
+
)
|
| 105 |
+
if "type" in attributes: # pragma no branch
|
| 106 |
+
self._type = self._makeStringAttribute(attributes["type"])
|
| 107 |
+
if "wait_timer" in attributes: # pragma no branch
|
| 108 |
+
self._wait_timer = self._makeIntAttribute(attributes["wait_timer"])
|
venv/lib/python3.10/site-packages/github/EnvironmentProtectionRuleReviewer.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 6 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 8 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 9 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 10 |
+
# Copyright 2019 Adam Baratz <adam.baratz@gmail.com> #
|
| 11 |
+
# Copyright 2019 Nick Campbell <nicholas.j.campbell@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 17 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 18 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 19 |
+
# Copyright 2023 alson <git@alm.nufan.net> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 23 |
+
# #
|
| 24 |
+
# This file is part of PyGithub. #
|
| 25 |
+
# http://pygithub.readthedocs.io/ #
|
| 26 |
+
# #
|
| 27 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 28 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 29 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 30 |
+
# any later version. #
|
| 31 |
+
# #
|
| 32 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 33 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 34 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 35 |
+
# details. #
|
| 36 |
+
# #
|
| 37 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 38 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 39 |
+
# #
|
| 40 |
+
################################################################################
|
| 41 |
+
|
| 42 |
+
from __future__ import annotations
|
| 43 |
+
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.NamedUser
|
| 47 |
+
import github.Team
|
| 48 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class EnvironmentProtectionRuleReviewer(NonCompletableGithubObject):
|
| 52 |
+
"""
|
| 53 |
+
This class represents a reviewer for an EnvironmentProtectionRule.
|
| 54 |
+
|
| 55 |
+
The reference can be found here
|
| 56 |
+
https://docs.github.com/en/rest/reference/deployments#environments
|
| 57 |
+
|
| 58 |
+
"""
|
| 59 |
+
|
| 60 |
+
def _initAttributes(self) -> None:
|
| 61 |
+
self._reviewer: Attribute[github.NamedUser.NamedUser | github.Team.Team] = NotSet
|
| 62 |
+
self._type: Attribute[str] = NotSet
|
| 63 |
+
|
| 64 |
+
def __repr__(self) -> str:
|
| 65 |
+
return self.get__repr__({"type": self._type.value})
|
| 66 |
+
|
| 67 |
+
@property
|
| 68 |
+
def reviewer(self) -> github.NamedUser.NamedUser | github.Team.Team:
|
| 69 |
+
return self._reviewer.value
|
| 70 |
+
|
| 71 |
+
@property
|
| 72 |
+
def type(self) -> str:
|
| 73 |
+
return self._type.value
|
| 74 |
+
|
| 75 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 76 |
+
if "reviewer" in attributes and "type" in attributes: # pragma no branch
|
| 77 |
+
assert attributes["type"] in ("User", "Team")
|
| 78 |
+
if attributes["type"] == "User":
|
| 79 |
+
self._reviewer = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["reviewer"])
|
| 80 |
+
elif attributes["type"] == "Team":
|
| 81 |
+
self._reviewer = self._makeClassAttribute(github.Team.Team, attributes["reviewer"])
|
| 82 |
+
if "type" in attributes: # pragma no branch
|
| 83 |
+
self._type = self._makeStringAttribute(attributes["type"])
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
class ReviewerParams:
|
| 87 |
+
"""
|
| 88 |
+
This class presents reviewers as can be configured for an Environment.
|
| 89 |
+
"""
|
| 90 |
+
|
| 91 |
+
def __init__(self, type_: str, id_: int):
|
| 92 |
+
assert isinstance(type_, str) and type_ in ("User", "Team")
|
| 93 |
+
assert isinstance(id_, int)
|
| 94 |
+
self.type = type_
|
| 95 |
+
self.id = id_
|
| 96 |
+
|
| 97 |
+
def _asdict(self) -> dict:
|
| 98 |
+
return {
|
| 99 |
+
"type": self.type,
|
| 100 |
+
"id": self.id,
|
| 101 |
+
}
|
venv/lib/python3.10/site-packages/github/Event.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2013 martinqt <m.ki2@laposte.net> #
|
| 8 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 9 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 10 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 16 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 17 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 18 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 19 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 20 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 21 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# #
|
| 23 |
+
# This file is part of PyGithub. #
|
| 24 |
+
# http://pygithub.readthedocs.io/ #
|
| 25 |
+
# #
|
| 26 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 27 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 28 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 29 |
+
# any later version. #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 32 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 33 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 34 |
+
# details. #
|
| 35 |
+
# #
|
| 36 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 37 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 38 |
+
# #
|
| 39 |
+
################################################################################
|
| 40 |
+
|
| 41 |
+
from __future__ import annotations
|
| 42 |
+
|
| 43 |
+
from datetime import datetime
|
| 44 |
+
from typing import Any
|
| 45 |
+
|
| 46 |
+
import github.GithubObject
|
| 47 |
+
import github.NamedUser
|
| 48 |
+
import github.Organization
|
| 49 |
+
import github.Repository
|
| 50 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
class Event(NonCompletableGithubObject):
|
| 54 |
+
"""
|
| 55 |
+
This class represents Events.
|
| 56 |
+
|
| 57 |
+
The reference can be found here
|
| 58 |
+
https://docs.github.com/en/rest/reference/activity#events
|
| 59 |
+
|
| 60 |
+
The OpenAPI schema can be found at
|
| 61 |
+
- /components/schemas/event
|
| 62 |
+
|
| 63 |
+
"""
|
| 64 |
+
|
| 65 |
+
def _initAttributes(self) -> None:
|
| 66 |
+
self._actor: Attribute[github.NamedUser.NamedUser] = NotSet
|
| 67 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 68 |
+
self._id: Attribute[str] = NotSet
|
| 69 |
+
self._org: Attribute[github.Organization.Organization] = NotSet
|
| 70 |
+
self._payload: Attribute[dict[str, Any]] = NotSet
|
| 71 |
+
self._public: Attribute[bool] = NotSet
|
| 72 |
+
self._repo: Attribute[github.Repository.Repository] = NotSet
|
| 73 |
+
self._type: Attribute[str] = NotSet
|
| 74 |
+
|
| 75 |
+
def __repr__(self) -> str:
|
| 76 |
+
return self.get__repr__({"id": self._id.value, "type": self._type.value})
|
| 77 |
+
|
| 78 |
+
@property
|
| 79 |
+
def actor(self) -> github.NamedUser.NamedUser:
|
| 80 |
+
return self._actor.value
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def created_at(self) -> datetime:
|
| 84 |
+
return self._created_at.value
|
| 85 |
+
|
| 86 |
+
@property
|
| 87 |
+
def id(self) -> str:
|
| 88 |
+
return self._id.value
|
| 89 |
+
|
| 90 |
+
@property
|
| 91 |
+
def org(self) -> github.Organization.Organization:
|
| 92 |
+
return self._org.value
|
| 93 |
+
|
| 94 |
+
@property
|
| 95 |
+
def payload(self) -> dict[str, Any]:
|
| 96 |
+
return self._payload.value
|
| 97 |
+
|
| 98 |
+
@property
|
| 99 |
+
def public(self) -> bool:
|
| 100 |
+
return self._public.value
|
| 101 |
+
|
| 102 |
+
@property
|
| 103 |
+
def repo(self) -> github.Repository.Repository:
|
| 104 |
+
return self._repo.value
|
| 105 |
+
|
| 106 |
+
@property
|
| 107 |
+
def type(self) -> str:
|
| 108 |
+
return self._type.value
|
| 109 |
+
|
| 110 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 111 |
+
if "actor" in attributes: # pragma no branch
|
| 112 |
+
self._actor = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["actor"])
|
| 113 |
+
if "created_at" in attributes: # pragma no branch
|
| 114 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 115 |
+
if "id" in attributes: # pragma no branch
|
| 116 |
+
self._id = self._makeStringAttribute(attributes["id"])
|
| 117 |
+
if "org" in attributes: # pragma no branch
|
| 118 |
+
self._org = self._makeClassAttribute(github.Organization.Organization, attributes["org"])
|
| 119 |
+
if "payload" in attributes: # pragma no branch
|
| 120 |
+
self._payload = self._makeDictAttribute(attributes["payload"])
|
| 121 |
+
if "public" in attributes: # pragma no branch
|
| 122 |
+
self._public = self._makeBoolAttribute(attributes["public"])
|
| 123 |
+
if "repo" in attributes: # pragma no branch
|
| 124 |
+
self._repo = self._makeClassAttribute(github.Repository.Repository, attributes["repo"])
|
| 125 |
+
if "type" in attributes: # pragma no branch
|
| 126 |
+
self._type = self._makeStringAttribute(attributes["type"])
|
venv/lib/python3.10/site-packages/github/File.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Jeffrey Melvin <jeffrey.melvin@workiva.com> #
|
| 10 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 11 |
+
# Copyright 2017 Simon <spam@esemi.ru> #
|
| 12 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 16 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 23 |
+
# #
|
| 24 |
+
# This file is part of PyGithub. #
|
| 25 |
+
# http://pygithub.readthedocs.io/ #
|
| 26 |
+
# #
|
| 27 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 28 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 29 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 30 |
+
# any later version. #
|
| 31 |
+
# #
|
| 32 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 33 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 34 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 35 |
+
# details. #
|
| 36 |
+
# #
|
| 37 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 38 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 39 |
+
# #
|
| 40 |
+
################################################################################
|
| 41 |
+
|
| 42 |
+
from typing import Any, Dict
|
| 43 |
+
|
| 44 |
+
from github.GithubObject import Attribute, NonCompletableGithubObject, NotSet
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class File(NonCompletableGithubObject):
|
| 48 |
+
"""
|
| 49 |
+
This class represents Files.
|
| 50 |
+
|
| 51 |
+
The OpenAPI schema can be found at
|
| 52 |
+
- /components/schemas/diff-entry
|
| 53 |
+
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
def _initAttributes(self) -> None:
|
| 57 |
+
self._additions: Attribute[int] = NotSet
|
| 58 |
+
self._blob_url: Attribute[str] = NotSet
|
| 59 |
+
self._changes: Attribute[int] = NotSet
|
| 60 |
+
self._contents_url: Attribute[str] = NotSet
|
| 61 |
+
self._deletions: Attribute[int] = NotSet
|
| 62 |
+
self._filename: Attribute[str] = NotSet
|
| 63 |
+
self._patch: Attribute[str] = NotSet
|
| 64 |
+
self._previous_filename: Attribute[str] = NotSet
|
| 65 |
+
self._raw_url: Attribute[str] = NotSet
|
| 66 |
+
self._sha: Attribute[str] = NotSet
|
| 67 |
+
self._status: Attribute[str] = NotSet
|
| 68 |
+
|
| 69 |
+
def __repr__(self) -> str:
|
| 70 |
+
return self.get__repr__({"sha": self._sha.value, "filename": self._filename.value})
|
| 71 |
+
|
| 72 |
+
@property
|
| 73 |
+
def additions(self) -> int:
|
| 74 |
+
return self._additions.value
|
| 75 |
+
|
| 76 |
+
@property
|
| 77 |
+
def blob_url(self) -> str:
|
| 78 |
+
return self._blob_url.value
|
| 79 |
+
|
| 80 |
+
@property
|
| 81 |
+
def changes(self) -> int:
|
| 82 |
+
return self._changes.value
|
| 83 |
+
|
| 84 |
+
@property
|
| 85 |
+
def contents_url(self) -> str:
|
| 86 |
+
return self._contents_url.value
|
| 87 |
+
|
| 88 |
+
@property
|
| 89 |
+
def deletions(self) -> int:
|
| 90 |
+
return self._deletions.value
|
| 91 |
+
|
| 92 |
+
@property
|
| 93 |
+
def filename(self) -> str:
|
| 94 |
+
return self._filename.value
|
| 95 |
+
|
| 96 |
+
@property
|
| 97 |
+
def patch(self) -> str:
|
| 98 |
+
return self._patch.value
|
| 99 |
+
|
| 100 |
+
@property
|
| 101 |
+
def previous_filename(self) -> str:
|
| 102 |
+
return self._previous_filename.value
|
| 103 |
+
|
| 104 |
+
@property
|
| 105 |
+
def raw_url(self) -> str:
|
| 106 |
+
return self._raw_url.value
|
| 107 |
+
|
| 108 |
+
@property
|
| 109 |
+
def sha(self) -> str:
|
| 110 |
+
return self._sha.value
|
| 111 |
+
|
| 112 |
+
@property
|
| 113 |
+
def status(self) -> str:
|
| 114 |
+
return self._status.value
|
| 115 |
+
|
| 116 |
+
def _useAttributes(self, attributes: Dict[str, Any]) -> None:
|
| 117 |
+
if "additions" in attributes: # pragma no branch
|
| 118 |
+
self._additions = self._makeIntAttribute(attributes["additions"])
|
| 119 |
+
if "blob_url" in attributes: # pragma no branch
|
| 120 |
+
self._blob_url = self._makeStringAttribute(attributes["blob_url"])
|
| 121 |
+
if "changes" in attributes: # pragma no branch
|
| 122 |
+
self._changes = self._makeIntAttribute(attributes["changes"])
|
| 123 |
+
if "contents_url" in attributes: # pragma no branch
|
| 124 |
+
self._contents_url = self._makeStringAttribute(attributes["contents_url"])
|
| 125 |
+
if "deletions" in attributes: # pragma no branch
|
| 126 |
+
self._deletions = self._makeIntAttribute(attributes["deletions"])
|
| 127 |
+
if "filename" in attributes: # pragma no branch
|
| 128 |
+
self._filename = self._makeStringAttribute(attributes["filename"])
|
| 129 |
+
if "patch" in attributes: # pragma no branch
|
| 130 |
+
self._patch = self._makeStringAttribute(attributes["patch"])
|
| 131 |
+
if "previous_filename" in attributes: # pragma no branch
|
| 132 |
+
self._previous_filename = self._makeStringAttribute(attributes["previous_filename"])
|
| 133 |
+
if "raw_url" in attributes: # pragma no branch
|
| 134 |
+
self._raw_url = self._makeStringAttribute(attributes["raw_url"])
|
| 135 |
+
if "sha" in attributes: # pragma no branch
|
| 136 |
+
self._sha = self._makeStringAttribute(attributes["sha"])
|
| 137 |
+
if "status" in attributes: # pragma no branch
|
| 138 |
+
self._status = self._makeStringAttribute(attributes["status"])
|
venv/lib/python3.10/site-packages/github/Gist.py
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Steve English <steve.english@navetas.com> #
|
| 4 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 5 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 6 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 7 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2014 Dale Jung <dale@dalejung.com> #
|
| 9 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 10 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 11 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 12 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 13 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2018 羽 <Just4test@users.noreply.github.com> #
|
| 15 |
+
# Copyright 2019 Jon Dufresne <jon.dufresne@gmail.com> #
|
| 16 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 18 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 19 |
+
# Copyright 2021 Mark Walker <mark.walker@realbuzz.com> #
|
| 20 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 21 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 22 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 23 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 24 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 25 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 26 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 27 |
+
# #
|
| 28 |
+
# This file is part of PyGithub. #
|
| 29 |
+
# http://pygithub.readthedocs.io/ #
|
| 30 |
+
# #
|
| 31 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 32 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 33 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 34 |
+
# any later version. #
|
| 35 |
+
# #
|
| 36 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 37 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 38 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 39 |
+
# details. #
|
| 40 |
+
# #
|
| 41 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 42 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 43 |
+
# #
|
| 44 |
+
################################################################################
|
| 45 |
+
|
| 46 |
+
from __future__ import annotations
|
| 47 |
+
|
| 48 |
+
from datetime import datetime
|
| 49 |
+
from typing import TYPE_CHECKING, Any
|
| 50 |
+
|
| 51 |
+
import github.GistComment
|
| 52 |
+
import github.GistFile
|
| 53 |
+
import github.GistHistoryState
|
| 54 |
+
import github.GithubObject
|
| 55 |
+
import github.NamedUser
|
| 56 |
+
import github.PaginatedList
|
| 57 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet, Opt, _NotSetType, is_defined, is_optional
|
| 58 |
+
from github.PaginatedList import PaginatedList
|
| 59 |
+
|
| 60 |
+
if TYPE_CHECKING:
|
| 61 |
+
from github.GistComment import GistComment
|
| 62 |
+
from github.GistHistoryState import GistHistoryState
|
| 63 |
+
from github.InputFileContent import InputFileContent
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
class Gist(CompletableGithubObject):
|
| 67 |
+
"""
|
| 68 |
+
This class represents Gists.
|
| 69 |
+
|
| 70 |
+
The reference can be found here
|
| 71 |
+
https://docs.github.com/en/rest/reference/gists
|
| 72 |
+
|
| 73 |
+
The OpenAPI schema can be found at
|
| 74 |
+
- /components/schemas/base-gist
|
| 75 |
+
- /components/schemas/gist-simple
|
| 76 |
+
- /components/schemas/gist-simple/properties/fork_of
|
| 77 |
+
- /components/schemas/gist-simple/properties/forks/items
|
| 78 |
+
|
| 79 |
+
"""
|
| 80 |
+
|
| 81 |
+
def _initAttributes(self) -> None:
|
| 82 |
+
self._comments: Attribute[int] = NotSet
|
| 83 |
+
self._comments_url: Attribute[str] = NotSet
|
| 84 |
+
self._commits_url: Attribute[str] = NotSet
|
| 85 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 86 |
+
self._description: Attribute[str] = NotSet
|
| 87 |
+
self._files: Attribute[dict[str, github.GistFile.GistFile]] = NotSet
|
| 88 |
+
self._fork_of: Attribute[Gist] = NotSet
|
| 89 |
+
self._forks: Attribute[list[Gist]] = NotSet
|
| 90 |
+
self._forks_url: Attribute[str] = NotSet
|
| 91 |
+
self._git_pull_url: Attribute[str] = NotSet
|
| 92 |
+
self._git_push_url: Attribute[str] = NotSet
|
| 93 |
+
self._history: Attribute[list[GistHistoryState]] = NotSet
|
| 94 |
+
self._html_url: Attribute[str] = NotSet
|
| 95 |
+
self._id: Attribute[str] = NotSet
|
| 96 |
+
self._node_id: Attribute[str] = NotSet
|
| 97 |
+
self._owner: Attribute[github.NamedUser.NamedUser] = NotSet
|
| 98 |
+
self._public: Attribute[bool] = NotSet
|
| 99 |
+
self._truncated: Attribute[bool] = NotSet
|
| 100 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 101 |
+
self._url: Attribute[str] = NotSet
|
| 102 |
+
self._user: Attribute[github.NamedUser.NamedUser] = NotSet
|
| 103 |
+
|
| 104 |
+
def __repr__(self) -> str:
|
| 105 |
+
return self.get__repr__({"id": self._id.value})
|
| 106 |
+
|
| 107 |
+
@property
|
| 108 |
+
def comments(self) -> int:
|
| 109 |
+
self._completeIfNotSet(self._comments)
|
| 110 |
+
return self._comments.value
|
| 111 |
+
|
| 112 |
+
@property
|
| 113 |
+
def comments_url(self) -> str:
|
| 114 |
+
self._completeIfNotSet(self._comments_url)
|
| 115 |
+
return self._comments_url.value
|
| 116 |
+
|
| 117 |
+
@property
|
| 118 |
+
def commits_url(self) -> str:
|
| 119 |
+
self._completeIfNotSet(self._commits_url)
|
| 120 |
+
return self._commits_url.value
|
| 121 |
+
|
| 122 |
+
@property
|
| 123 |
+
def created_at(self) -> datetime:
|
| 124 |
+
self._completeIfNotSet(self._created_at)
|
| 125 |
+
return self._created_at.value
|
| 126 |
+
|
| 127 |
+
@property
|
| 128 |
+
def description(self) -> str:
|
| 129 |
+
self._completeIfNotSet(self._description)
|
| 130 |
+
return self._description.value
|
| 131 |
+
|
| 132 |
+
@property
|
| 133 |
+
def files(self) -> dict[str, github.GistFile.GistFile]:
|
| 134 |
+
self._completeIfNeeded()
|
| 135 |
+
return self._files.value
|
| 136 |
+
|
| 137 |
+
@property
|
| 138 |
+
def fork_of(self) -> github.Gist.Gist:
|
| 139 |
+
self._completeIfNotSet(self._fork_of)
|
| 140 |
+
return self._fork_of.value
|
| 141 |
+
|
| 142 |
+
@property
|
| 143 |
+
def forks(self) -> list[Gist]:
|
| 144 |
+
self._completeIfNotSet(self._forks)
|
| 145 |
+
return self._forks.value
|
| 146 |
+
|
| 147 |
+
@property
|
| 148 |
+
def forks_url(self) -> str:
|
| 149 |
+
self._completeIfNotSet(self._forks_url)
|
| 150 |
+
return self._forks_url.value
|
| 151 |
+
|
| 152 |
+
@property
|
| 153 |
+
def git_pull_url(self) -> str:
|
| 154 |
+
self._completeIfNotSet(self._git_pull_url)
|
| 155 |
+
return self._git_pull_url.value
|
| 156 |
+
|
| 157 |
+
@property
|
| 158 |
+
def git_push_url(self) -> str:
|
| 159 |
+
self._completeIfNotSet(self._git_push_url)
|
| 160 |
+
return self._git_push_url.value
|
| 161 |
+
|
| 162 |
+
@property
|
| 163 |
+
def history(self) -> list[GistHistoryState]:
|
| 164 |
+
self._completeIfNotSet(self._history)
|
| 165 |
+
return self._history.value
|
| 166 |
+
|
| 167 |
+
@property
|
| 168 |
+
def html_url(self) -> str:
|
| 169 |
+
self._completeIfNotSet(self._html_url)
|
| 170 |
+
return self._html_url.value
|
| 171 |
+
|
| 172 |
+
@property
|
| 173 |
+
def id(self) -> str:
|
| 174 |
+
self._completeIfNotSet(self._id)
|
| 175 |
+
return self._id.value
|
| 176 |
+
|
| 177 |
+
@property
|
| 178 |
+
def node_id(self) -> str:
|
| 179 |
+
self._completeIfNotSet(self._node_id)
|
| 180 |
+
return self._node_id.value
|
| 181 |
+
|
| 182 |
+
@property
|
| 183 |
+
def owner(self) -> github.NamedUser.NamedUser:
|
| 184 |
+
self._completeIfNotSet(self._owner)
|
| 185 |
+
return self._owner.value
|
| 186 |
+
|
| 187 |
+
@property
|
| 188 |
+
def public(self) -> bool:
|
| 189 |
+
self._completeIfNotSet(self._public)
|
| 190 |
+
return self._public.value
|
| 191 |
+
|
| 192 |
+
@property
|
| 193 |
+
def truncated(self) -> bool:
|
| 194 |
+
self._completeIfNotSet(self._truncated)
|
| 195 |
+
return self._truncated.value
|
| 196 |
+
|
| 197 |
+
@property
|
| 198 |
+
def updated_at(self) -> datetime:
|
| 199 |
+
self._completeIfNotSet(self._updated_at)
|
| 200 |
+
return self._updated_at.value
|
| 201 |
+
|
| 202 |
+
@property
|
| 203 |
+
def url(self) -> str:
|
| 204 |
+
self._completeIfNotSet(self._url)
|
| 205 |
+
return self._url.value
|
| 206 |
+
|
| 207 |
+
@property
|
| 208 |
+
def user(self) -> github.NamedUser.NamedUser:
|
| 209 |
+
self._completeIfNotSet(self._user)
|
| 210 |
+
return self._user.value
|
| 211 |
+
|
| 212 |
+
def create_comment(self, body: str) -> GistComment:
|
| 213 |
+
"""
|
| 214 |
+
:calls: `POST /gists/{gist_id}/comments <https://docs.github.com/en/rest/reference/gists#comments>`_
|
| 215 |
+
"""
|
| 216 |
+
assert isinstance(body, str), body
|
| 217 |
+
post_parameters = {
|
| 218 |
+
"body": body,
|
| 219 |
+
}
|
| 220 |
+
headers, data = self._requester.requestJsonAndCheck("POST", f"{self.url}/comments", input=post_parameters)
|
| 221 |
+
return github.GistComment.GistComment(self._requester, headers, data, completed=True)
|
| 222 |
+
|
| 223 |
+
def create_fork(self) -> Gist:
|
| 224 |
+
"""
|
| 225 |
+
:calls: `POST /gists/{id}/forks <https://docs.github.com/en/rest/reference/gists>`_
|
| 226 |
+
"""
|
| 227 |
+
headers, data = self._requester.requestJsonAndCheck("POST", f"{self.url}/forks")
|
| 228 |
+
return Gist(self._requester, headers, data, completed=True)
|
| 229 |
+
|
| 230 |
+
def delete(self) -> None:
|
| 231 |
+
"""
|
| 232 |
+
:calls: `DELETE /gists/{id} <https://docs.github.com/en/rest/reference/gists>`_
|
| 233 |
+
"""
|
| 234 |
+
headers, data = self._requester.requestJsonAndCheck("DELETE", self.url)
|
| 235 |
+
|
| 236 |
+
def edit(self, description: Opt[str] = NotSet, files: Opt[dict[str, InputFileContent | None]] = NotSet) -> None:
|
| 237 |
+
"""
|
| 238 |
+
:calls: `PATCH /gists/{id} <https://docs.github.com/en/rest/reference/gists>`_
|
| 239 |
+
"""
|
| 240 |
+
assert is_optional(description, str), description
|
| 241 |
+
# limitation of `TypeGuard`
|
| 242 |
+
assert isinstance(files, _NotSetType) or all(
|
| 243 |
+
element is None or isinstance(element, github.InputFileContent) for element in files.values()
|
| 244 |
+
), files
|
| 245 |
+
post_parameters: dict[str, Any] = {}
|
| 246 |
+
if is_defined(description):
|
| 247 |
+
post_parameters["description"] = description
|
| 248 |
+
if is_defined(files):
|
| 249 |
+
post_parameters["files"] = {key: None if value is None else value._identity for key, value in files.items()}
|
| 250 |
+
headers, data = self._requester.requestJsonAndCheck("PATCH", self.url, input=post_parameters)
|
| 251 |
+
self._useAttributes(data)
|
| 252 |
+
|
| 253 |
+
def get_comment(self, id: int) -> GistComment:
|
| 254 |
+
"""
|
| 255 |
+
:calls: `GET /gists/{gist_id}/comments/{id} <https://docs.github.com/en/rest/reference/gists#comments>`_
|
| 256 |
+
"""
|
| 257 |
+
assert isinstance(id, int), id
|
| 258 |
+
headers, data = self._requester.requestJsonAndCheck("GET", f"{self.url}/comments/{id}")
|
| 259 |
+
return github.GistComment.GistComment(self._requester, headers, data, completed=True)
|
| 260 |
+
|
| 261 |
+
def get_comments(self) -> PaginatedList[GistComment]:
|
| 262 |
+
"""
|
| 263 |
+
:calls: `GET /gists/{gist_id}/comments <https://docs.github.com/en/rest/reference/gists#comments>`_
|
| 264 |
+
"""
|
| 265 |
+
return PaginatedList(
|
| 266 |
+
github.GistComment.GistComment,
|
| 267 |
+
self._requester,
|
| 268 |
+
f"{self.url}/comments",
|
| 269 |
+
None,
|
| 270 |
+
)
|
| 271 |
+
|
| 272 |
+
def is_starred(self) -> bool:
|
| 273 |
+
"""
|
| 274 |
+
:calls: `GET /gists/{id}/star <https://docs.github.com/en/rest/reference/gists>`_
|
| 275 |
+
"""
|
| 276 |
+
status, headers, data = self._requester.requestJson("GET", f"{self.url}/star")
|
| 277 |
+
return status == 204
|
| 278 |
+
|
| 279 |
+
def reset_starred(self) -> None:
|
| 280 |
+
"""
|
| 281 |
+
:calls: `DELETE /gists/{id}/star <https://docs.github.com/en/rest/reference/gists>`_
|
| 282 |
+
"""
|
| 283 |
+
headers, data = self._requester.requestJsonAndCheck("DELETE", f"{self.url}/star")
|
| 284 |
+
|
| 285 |
+
def set_starred(self) -> None:
|
| 286 |
+
"""
|
| 287 |
+
:calls: `PUT /gists/{id}/star <https://docs.github.com/en/rest/reference/gists>`_
|
| 288 |
+
"""
|
| 289 |
+
headers, data = self._requester.requestJsonAndCheck("PUT", f"{self.url}/star")
|
| 290 |
+
|
| 291 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 292 |
+
if "comments" in attributes: # pragma no branch
|
| 293 |
+
self._comments = self._makeIntAttribute(attributes["comments"])
|
| 294 |
+
if "comments_url" in attributes: # pragma no branch
|
| 295 |
+
self._comments_url = self._makeStringAttribute(attributes["comments_url"])
|
| 296 |
+
if "commits_url" in attributes: # pragma no branch
|
| 297 |
+
self._commits_url = self._makeStringAttribute(attributes["commits_url"])
|
| 298 |
+
if "created_at" in attributes: # pragma no branch
|
| 299 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 300 |
+
if "description" in attributes: # pragma no branch
|
| 301 |
+
self._description = self._makeStringAttribute(attributes["description"])
|
| 302 |
+
if "files" in attributes: # pragma no branch
|
| 303 |
+
self._files = self._makeDictOfStringsToClassesAttribute(github.GistFile.GistFile, attributes["files"])
|
| 304 |
+
if "fork_of" in attributes: # pragma no branch
|
| 305 |
+
self._fork_of = self._makeClassAttribute(Gist, attributes["fork_of"])
|
| 306 |
+
if "forks" in attributes: # pragma no branch
|
| 307 |
+
self._forks = self._makeListOfClassesAttribute(Gist, attributes["forks"])
|
| 308 |
+
if "forks_url" in attributes: # pragma no branch
|
| 309 |
+
self._forks_url = self._makeStringAttribute(attributes["forks_url"])
|
| 310 |
+
if "git_pull_url" in attributes: # pragma no branch
|
| 311 |
+
self._git_pull_url = self._makeStringAttribute(attributes["git_pull_url"])
|
| 312 |
+
if "git_push_url" in attributes: # pragma no branch
|
| 313 |
+
self._git_push_url = self._makeStringAttribute(attributes["git_push_url"])
|
| 314 |
+
if "history" in attributes: # pragma no branch
|
| 315 |
+
self._history = self._makeListOfClassesAttribute(
|
| 316 |
+
github.GistHistoryState.GistHistoryState, attributes["history"]
|
| 317 |
+
)
|
| 318 |
+
if "html_url" in attributes: # pragma no branch
|
| 319 |
+
self._html_url = self._makeStringAttribute(attributes["html_url"])
|
| 320 |
+
if "id" in attributes: # pragma no branch
|
| 321 |
+
self._id = self._makeStringAttribute(attributes["id"])
|
| 322 |
+
if "node_id" in attributes: # pragma no branch
|
| 323 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 324 |
+
if "owner" in attributes: # pragma no branch
|
| 325 |
+
self._owner = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["owner"])
|
| 326 |
+
if "public" in attributes: # pragma no branch
|
| 327 |
+
self._public = self._makeBoolAttribute(attributes["public"])
|
| 328 |
+
if "truncated" in attributes: # pragma no branch
|
| 329 |
+
self._truncated = self._makeBoolAttribute(attributes["truncated"])
|
| 330 |
+
if "updated_at" in attributes: # pragma no branch
|
| 331 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 332 |
+
if "url" in attributes: # pragma no branch
|
| 333 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
| 334 |
+
if "user" in attributes: # pragma no branch
|
| 335 |
+
self._user = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["user"])
|
venv/lib/python3.10/site-packages/github/GistComment.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
############################ Copyrights and license ############################
|
| 2 |
+
# #
|
| 3 |
+
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 4 |
+
# Copyright 2012 Zearin <zearin@gonk.net> #
|
| 5 |
+
# Copyright 2013 AKFish <akfish@gmail.com> #
|
| 6 |
+
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 7 |
+
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
|
| 8 |
+
# Copyright 2016 Jannis Gebauer <ja.geb@me.com> #
|
| 9 |
+
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
| 10 |
+
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
| 11 |
+
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
| 12 |
+
# Copyright 2019 Steve Kowalik <steven@wedontsleep.org> #
|
| 13 |
+
# Copyright 2019 Wan Liuyang <tsfdye@gmail.com> #
|
| 14 |
+
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
|
| 15 |
+
# Copyright 2021 Mark Walker <mark.walker@realbuzz.com> #
|
| 16 |
+
# Copyright 2021 Steve Kowalik <steven@wedontsleep.org> #
|
| 17 |
+
# Copyright 2023 Enrico Minack <github@enrico.minack.dev> #
|
| 18 |
+
# Copyright 2023 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 19 |
+
# Copyright 2023 Trim21 <trim21.me@gmail.com> #
|
| 20 |
+
# Copyright 2024 Enrico Minack <github@enrico.minack.dev> #
|
| 21 |
+
# Copyright 2024 Jirka Borovec <6035284+Borda@users.noreply.github.com> #
|
| 22 |
+
# Copyright 2025 Enrico Minack <github@enrico.minack.dev> #
|
| 23 |
+
# #
|
| 24 |
+
# This file is part of PyGithub. #
|
| 25 |
+
# http://pygithub.readthedocs.io/ #
|
| 26 |
+
# #
|
| 27 |
+
# PyGithub is free software: you can redistribute it and/or modify it under #
|
| 28 |
+
# the terms of the GNU Lesser General Public License as published by the Free #
|
| 29 |
+
# Software Foundation, either version 3 of the License, or (at your option) #
|
| 30 |
+
# any later version. #
|
| 31 |
+
# #
|
| 32 |
+
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
|
| 33 |
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
| 34 |
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
|
| 35 |
+
# details. #
|
| 36 |
+
# #
|
| 37 |
+
# You should have received a copy of the GNU Lesser General Public License #
|
| 38 |
+
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
|
| 39 |
+
# #
|
| 40 |
+
################################################################################
|
| 41 |
+
|
| 42 |
+
from __future__ import annotations
|
| 43 |
+
|
| 44 |
+
from datetime import datetime
|
| 45 |
+
from typing import Any
|
| 46 |
+
|
| 47 |
+
import github.GithubObject
|
| 48 |
+
import github.NamedUser
|
| 49 |
+
from github.GithubObject import Attribute, CompletableGithubObject, NotSet
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class GistComment(CompletableGithubObject):
|
| 53 |
+
"""
|
| 54 |
+
This class represents GistComments.
|
| 55 |
+
|
| 56 |
+
The reference can be found here
|
| 57 |
+
https://docs.github.com/en/rest/reference/gists#comments
|
| 58 |
+
|
| 59 |
+
The OpenAPI schema can be found at
|
| 60 |
+
- /components/schemas/gist-comment
|
| 61 |
+
|
| 62 |
+
"""
|
| 63 |
+
|
| 64 |
+
def _initAttributes(self) -> None:
|
| 65 |
+
self._author_association: Attribute[str] = NotSet
|
| 66 |
+
self._body: Attribute[str] = NotSet
|
| 67 |
+
self._created_at: Attribute[datetime] = NotSet
|
| 68 |
+
self._id: Attribute[int] = NotSet
|
| 69 |
+
self._node_id: Attribute[str] = NotSet
|
| 70 |
+
self._updated_at: Attribute[datetime] = NotSet
|
| 71 |
+
self._url: Attribute[str] = NotSet
|
| 72 |
+
self._user: Attribute[github.NamedUser.NamedUser] = NotSet
|
| 73 |
+
|
| 74 |
+
def __repr__(self) -> str:
|
| 75 |
+
return self.get__repr__({"id": self._id.value, "user": self._user.value})
|
| 76 |
+
|
| 77 |
+
@property
|
| 78 |
+
def author_association(self) -> str:
|
| 79 |
+
self._completeIfNotSet(self._author_association)
|
| 80 |
+
return self._author_association.value
|
| 81 |
+
|
| 82 |
+
@property
|
| 83 |
+
def body(self) -> str:
|
| 84 |
+
self._completeIfNotSet(self._body)
|
| 85 |
+
return self._body.value
|
| 86 |
+
|
| 87 |
+
@property
|
| 88 |
+
def created_at(self) -> datetime:
|
| 89 |
+
self._completeIfNotSet(self._created_at)
|
| 90 |
+
return self._created_at.value
|
| 91 |
+
|
| 92 |
+
@property
|
| 93 |
+
def id(self) -> int:
|
| 94 |
+
self._completeIfNotSet(self._id)
|
| 95 |
+
return self._id.value
|
| 96 |
+
|
| 97 |
+
@property
|
| 98 |
+
def node_id(self) -> str:
|
| 99 |
+
self._completeIfNotSet(self._node_id)
|
| 100 |
+
return self._node_id.value
|
| 101 |
+
|
| 102 |
+
@property
|
| 103 |
+
def updated_at(self) -> datetime:
|
| 104 |
+
self._completeIfNotSet(self._updated_at)
|
| 105 |
+
return self._updated_at.value
|
| 106 |
+
|
| 107 |
+
@property
|
| 108 |
+
def url(self) -> str:
|
| 109 |
+
self._completeIfNotSet(self._url)
|
| 110 |
+
return self._url.value
|
| 111 |
+
|
| 112 |
+
@property
|
| 113 |
+
def user(self) -> github.NamedUser.NamedUser:
|
| 114 |
+
self._completeIfNotSet(self._user)
|
| 115 |
+
return self._user.value
|
| 116 |
+
|
| 117 |
+
def delete(self) -> None:
|
| 118 |
+
"""
|
| 119 |
+
:calls: `DELETE /gists/{gist_id}/comments/{id} <https://docs.github.com/en/rest/reference/gists#comments>`_
|
| 120 |
+
"""
|
| 121 |
+
headers, data = self._requester.requestJsonAndCheck("DELETE", self.url)
|
| 122 |
+
|
| 123 |
+
def edit(self, body: str) -> None:
|
| 124 |
+
"""
|
| 125 |
+
:calls: `PATCH /gists/{gist_id}/comments/{id} <https://docs.github.com/en/rest/reference/gists#comments>`_
|
| 126 |
+
"""
|
| 127 |
+
assert isinstance(body, str), body
|
| 128 |
+
post_parameters = {
|
| 129 |
+
"body": body,
|
| 130 |
+
}
|
| 131 |
+
headers, data = self._requester.requestJsonAndCheck("PATCH", self.url, input=post_parameters)
|
| 132 |
+
self._useAttributes(data)
|
| 133 |
+
|
| 134 |
+
def _useAttributes(self, attributes: dict[str, Any]) -> None:
|
| 135 |
+
if "author_association" in attributes: # pragma no branch
|
| 136 |
+
self._author_association = self._makeStringAttribute(attributes["author_association"])
|
| 137 |
+
if "body" in attributes: # pragma no branch
|
| 138 |
+
self._body = self._makeStringAttribute(attributes["body"])
|
| 139 |
+
if "created_at" in attributes: # pragma no branch
|
| 140 |
+
self._created_at = self._makeDatetimeAttribute(attributes["created_at"])
|
| 141 |
+
if "id" in attributes: # pragma no branch
|
| 142 |
+
self._id = self._makeIntAttribute(attributes["id"])
|
| 143 |
+
if "node_id" in attributes: # pragma no branch
|
| 144 |
+
self._node_id = self._makeStringAttribute(attributes["node_id"])
|
| 145 |
+
if "updated_at" in attributes: # pragma no branch
|
| 146 |
+
self._updated_at = self._makeDatetimeAttribute(attributes["updated_at"])
|
| 147 |
+
if "url" in attributes: # pragma no branch
|
| 148 |
+
self._url = self._makeStringAttribute(attributes["url"])
|
| 149 |
+
if "user" in attributes: # pragma no branch
|
| 150 |
+
self._user = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["user"])
|
venv/lib/python3.10/site-packages/github/__pycache__/AccessToken.cpython-310.pyc
ADDED
|
Binary file (3.4 kB). View file
|
|
|
venv/lib/python3.10/site-packages/github/__pycache__/AdvisoryBase.cpython-310.pyc
ADDED
|
Binary file (4.6 kB). View file
|
|
|