mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 14:45:14 +00:00 
			
		
		
		
	
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/1_broken_site.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/1_broken_site.yml
									
									
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ body: | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | ||||||
|           required: true |           required: true | ||||||
|   - type: checkboxes |   - type: checkboxes | ||||||
|     id: checklist |     id: checklist | ||||||
| @@ -24,7 +24,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) |         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ body: | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | ||||||
|           required: true |           required: true | ||||||
|   - type: checkboxes |   - type: checkboxes | ||||||
|     id: checklist |     id: checklist | ||||||
| @@ -24,7 +24,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that none of provided URLs [violate any copyrights](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-website-primarily-used-for-piracy) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge |         - label: I've checked that none of provided URLs [violate any copyrights](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-website-primarily-used-for-piracy) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ body: | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | ||||||
|           required: true |           required: true | ||||||
|   - type: checkboxes |   - type: checkboxes | ||||||
|     id: checklist |     id: checklist | ||||||
| @@ -22,7 +22,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that all provided URLs are playable in a browser with the same IP and same login details |         - label: I've checked that all provided URLs are playable in a browser with the same IP and same login details | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/4_bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/4_bug_report.yml
									
									
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ body: | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | ||||||
|           required: true |           required: true | ||||||
|   - type: checkboxes |   - type: checkboxes | ||||||
|     id: checklist |     id: checklist | ||||||
| @@ -24,7 +24,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) |         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/5_feature_request.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/5_feature_request.yml
									
									
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ body: | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | ||||||
|           required: true |           required: true | ||||||
|   - type: checkboxes |   - type: checkboxes | ||||||
|     id: checklist |     id: checklist | ||||||
| @@ -22,7 +22,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've verified that I'm running yt-dlp version **2023.01.06** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) |         - label: I've verified that I'm running yt-dlp version **2023.01.06** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.github/ISSUE_TEMPLATE/6_question.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/ISSUE_TEMPLATE/6_question.yml
									
									
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ body: | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\* field | ||||||
|           required: true |           required: true | ||||||
|   - type: markdown |   - type: markdown | ||||||
|     attributes: |     attributes: | ||||||
| @@ -28,7 +28,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've verified that I'm running yt-dlp version **2023.01.06** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) |         - label: I've verified that I'm running yt-dlp version **2023.01.06** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar questions **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar questions **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) |         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that none of provided URLs [violate any copyrights](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-website-primarily-used-for-piracy) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge |         - label: I've checked that none of provided URLs [violate any copyrights](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-website-primarily-used-for-piracy) or contain any [DRM](https://en.wikipedia.org/wiki/Digital_rights_management) to the best of my knowledge | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that all provided URLs are playable in a browser with the same IP and same login details |         - label: I've checked that all provided URLs are playable in a browser with the same IP and same login details | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE_tmpl/4_bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE_tmpl/4_bug_report.yml
									
									
									
									
										vendored
									
									
								
							| @@ -18,7 +18,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) |         - label: I've checked that all URLs and arguments with special characters are [properly quoted or escaped](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#video-url-contains-an-ampersand--and-im-getting-some-strange-output-1-2839-or-v-is-not-recognized-as-an-internal-or-external-command) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've verified that I'm running yt-dlp version **%(version)s** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) |         - label: I've verified that I'm running yt-dlp version **%(version)s** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar issues **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE_tmpl/6_question.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE_tmpl/6_question.yml
									
									
									
									
										vendored
									
									
								
							| @@ -22,7 +22,7 @@ body: | |||||||
|           required: true |           required: true | ||||||
|         - label: I've verified that I'm running yt-dlp version **%(version)s** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) |         - label: I've verified that I'm running yt-dlp version **%(version)s** ([update instructions](https://github.com/yt-dlp/yt-dlp#update)) or later (specify commit) | ||||||
|           required: true |           required: true | ||||||
|         - label: I've searched the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar questions **including closed ones**. DO NOT post duplicates |         - label: I've searched [known issues](https://github.com/yt-dlp/yt-dlp/issues/3766) and the [bugtracker](https://github.com/yt-dlp/yt-dlp/issues?q=) for similar questions **including closed ones**. DO NOT post duplicates | ||||||
|           required: true |           required: true | ||||||
|         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) |         - label: I've read the [guidelines for opening an issue](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#opening-an-issue) | ||||||
|           required: true |           required: true | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/PULL_REQUEST_TEMPLATE.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/PULL_REQUEST_TEMPLATE.md
									
									
									
									
										vendored
									
									
								
							| @@ -30,7 +30,7 @@ Fixes # | |||||||
| - [ ] [Searched](https://github.com/yt-dlp/yt-dlp/search?q=is%3Apr&type=Issues) the bugtracker for similar pull requests | - [ ] [Searched](https://github.com/yt-dlp/yt-dlp/search?q=is%3Apr&type=Issues) the bugtracker for similar pull requests | ||||||
| - [ ] Checked the code with [flake8](https://pypi.python.org/pypi/flake8) and [ran relevant tests](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#developer-instructions) | - [ ] Checked the code with [flake8](https://pypi.python.org/pypi/flake8) and [ran relevant tests](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#developer-instructions) | ||||||
| 
 | 
 | ||||||
| ### In order to be accepted and merged into yt-dlp each piece of code must be in public domain or released under [Unlicense](http://unlicense.org/). Check one of the following options: | ### In order to be accepted and merged into yt-dlp each piece of code must be in public domain or released under [Unlicense](http://unlicense.org/). Check all of the following options that apply: | ||||||
| - [ ] I am the original author of this code and I am willing to release it under [Unlicense](http://unlicense.org/) | - [ ] I am the original author of this code and I am willing to release it under [Unlicense](http://unlicense.org/) | ||||||
| - [ ] I am not the original author of this code but it is in public domain or released under [Unlicense](http://unlicense.org/) (provide reliable evidence) | - [ ] I am not the original author of this code but it is in public domain or released under [Unlicense](http://unlicense.org/) (provide reliable evidence) | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ coletdjnz/colethedj (collaborator) | |||||||
| Ashish0804 (collaborator) | Ashish0804 (collaborator) | ||||||
| nao20010128nao/Lesmiscore (collaborator) | nao20010128nao/Lesmiscore (collaborator) | ||||||
| bashonly (collaborator) | bashonly (collaborator) | ||||||
|  | Grub4K (collaborator) | ||||||
| h-h-h-h | h-h-h-h | ||||||
| pauldubois98 | pauldubois98 | ||||||
| nixxo | nixxo | ||||||
| @@ -319,7 +320,6 @@ columndeeply | |||||||
| DoubleCouponDay | DoubleCouponDay | ||||||
| Fabi019 | Fabi019 | ||||||
| GautamMKGarg | GautamMKGarg | ||||||
| Grub4K |  | ||||||
| itachi-19 | itachi-19 | ||||||
| jeroenj | jeroenj | ||||||
| josanabr | josanabr | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ You can also find lists of all [contributors of yt-dlp](CONTRIBUTORS) and [autho | |||||||
| ## [pukkandan](https://github.com/pukkandan) | ## [pukkandan](https://github.com/pukkandan) | ||||||
| 
 | 
 | ||||||
| [](https://ko-fi.com/pukkandan) | [](https://ko-fi.com/pukkandan) | ||||||
|  | [](https://github.com/sponsors/pukkandan) | ||||||
| 
 | 
 | ||||||
| * Owner of the fork | * Owner of the fork | ||||||
| 
 | 
 | ||||||
| @@ -25,8 +26,9 @@ You can also find lists of all [contributors of yt-dlp](CONTRIBUTORS) and [autho | |||||||
| 
 | 
 | ||||||
| ## [coletdjnz](https://github.com/coletdjnz) | ## [coletdjnz](https://github.com/coletdjnz) | ||||||
| 
 | 
 | ||||||
| [](https://github.com/sponsors/coletdjnz) | [](https://github.com/sponsors/coletdjnz) | ||||||
| 
 | 
 | ||||||
|  | * Improved plugin architecture | ||||||
| * YouTube improvements including: age-gate bypass, private playlists, multiple-clients (to avoid throttling) and a lot of under-the-hood improvements | * YouTube improvements including: age-gate bypass, private playlists, multiple-clients (to avoid throttling) and a lot of under-the-hood improvements | ||||||
| * Added support for new websites YoutubeWebArchive, MainStreaming, PRX, nzherald, Mediaklikk, StarTV etc | * Added support for new websites YoutubeWebArchive, MainStreaming, PRX, nzherald, Mediaklikk, StarTV etc | ||||||
| * Improved/fixed support for Patreon, panopto, gfycat, itv, pbs, SouthParkDE etc | * Improved/fixed support for Patreon, panopto, gfycat, itv, pbs, SouthParkDE etc | ||||||
|   | |||||||
| @@ -788,7 +788,7 @@ You can also fork the project on GitHub and run your fork's [build workflow](.gi | |||||||
|     --prefer-insecure               Use an unencrypted connection to retrieve |     --prefer-insecure               Use an unencrypted connection to retrieve | ||||||
|                                     information about the video (Currently |                                     information about the video (Currently | ||||||
|                                     supported only for YouTube) |                                     supported only for YouTube) | ||||||
|     --add-header FIELD:VALUE        Specify a custom HTTP header and its value, |     --add-headers FIELD:VALUE       Specify a custom HTTP header and its value, | ||||||
|                                     separated by a colon ":". You can use this |                                     separated by a colon ":". You can use this | ||||||
|                                     option multiple times |                                     option multiple times | ||||||
|     --bidi-workaround               Work around terminals that lack |     --bidi-workaround               Work around terminals that lack | ||||||
| @@ -1511,7 +1511,7 @@ The available fields are: | |||||||
|  - `source`: The preference of the source |  - `source`: The preference of the source | ||||||
|  - `proto`: Protocol used for download (`https`/`ftps` > `http`/`ftp` > `m3u8_native`/`m3u8` > `http_dash_segments`> `websocket_frag` > `mms`/`rtsp` > `f4f`/`f4m`) |  - `proto`: Protocol used for download (`https`/`ftps` > `http`/`ftp` > `m3u8_native`/`m3u8` > `http_dash_segments`> `websocket_frag` > `mms`/`rtsp` > `f4f`/`f4m`) | ||||||
|  - `vcodec`: Video Codec (`av01` > `vp9.2` > `vp9` > `h265` > `h264` > `vp8` > `h263` > `theora` > other) |  - `vcodec`: Video Codec (`av01` > `vp9.2` > `vp9` > `h265` > `h264` > `vp8` > `h263` > `theora` > other) | ||||||
|  - `acodec`: Audio Codec (`flac`/`alac` > `wav`/`aiff` > `opus` > `vorbis` > `aac` > `mp4a` > `mp3` `ac4` > > `eac3` > `ac3` > `dts` > other) |  - `acodec`: Audio Codec (`flac`/`alac` > `wav`/`aiff` > `opus` > `vorbis` > `aac` > `mp4a` > `mp3` > `ac4` > `eac3` > `ac3` > `dts` > other) | ||||||
|  - `codec`: Equivalent to `vcodec,acodec` |  - `codec`: Equivalent to `vcodec,acodec` | ||||||
|  - `vext`: Video Extension (`mp4` > `mov` > `webm` > `flv` > other). If `--prefer-free-formats` is used, `webm` is preferred. |  - `vext`: Video Extension (`mp4` > `mov` > `webm` > `flv` > other). If `--prefer-free-formats` is used, `webm` is preferred. | ||||||
|  - `aext`: Audio Extension (`m4a` > `aac` > `mp3` > `ogg` > `opus` > `webm` > other). If `--prefer-free-formats` is used, the order changes to `ogg` > `opus` > `webm` > `mp3` > `m4a` > `aac` |  - `aext`: Audio Extension (`m4a` > `aac` > `mp3` > `ogg` > `opus` > `webm` > other). If `--prefer-free-formats` is used, the order changes to `ogg` > `opus` > `webm` > `mp3` > `m4a` > `aac` | ||||||
| @@ -1741,6 +1741,8 @@ $ yt-dlp --replace-in-metadata "title,uploader" "[ _]" "-" | |||||||
| 
 | 
 | ||||||
| Some extractors accept additional arguments which can be passed using `--extractor-args KEY:ARGS`. `ARGS` is a `;` (semicolon) separated string of `ARG=VAL1,VAL2`. E.g. `--extractor-args "youtube:player-client=android_embedded,web;include_live_dash" --extractor-args "funimation:version=uncut"` | Some extractors accept additional arguments which can be passed using `--extractor-args KEY:ARGS`. `ARGS` is a `;` (semicolon) separated string of `ARG=VAL1,VAL2`. E.g. `--extractor-args "youtube:player-client=android_embedded,web;include_live_dash" --extractor-args "funimation:version=uncut"` | ||||||
| 
 | 
 | ||||||
|  | Note: In CLI, `ARG` can use `-` instead of `_`; e.g. `youtube:player-client"` becomes `youtube:player_client"` | ||||||
|  | 
 | ||||||
| The following extractors use this feature: | The following extractors use this feature: | ||||||
| 
 | 
 | ||||||
| #### youtube | #### youtube | ||||||
| @@ -1887,7 +1889,7 @@ with YoutubeDL() as ydl: | |||||||
|     ydl.download(URLS) |     ydl.download(URLS) | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Most likely, you'll want to use various options. For a list of options available, have a look at [`yt_dlp/YoutubeDL.py`](yt_dlp/YoutubeDL.py#L180). | Most likely, you'll want to use various options. For a list of options available, have a look at [`yt_dlp/YoutubeDL.py`](yt_dlp/YoutubeDL.py#L184). | ||||||
| 
 | 
 | ||||||
| **Tip**: If you are porting your code from youtube-dl to yt-dlp, one important point to look out for is that we do not guarantee the return value of `YoutubeDL.extract_info` to be json serializable, or even be a dictionary. It will be dictionary-like, but if you want to ensure it is a serializable dictionary, pass it through `YoutubeDL.sanitize_info` as shown in the [example below](#extracting-information) | **Tip**: If you are porting your code from youtube-dl to yt-dlp, one important point to look out for is that we do not guarantee the return value of `YoutubeDL.extract_info` to be json serializable, or even be a dictionary. It will be dictionary-like, but if you want to ensure it is a serializable dictionary, pass it through `YoutubeDL.sanitize_info` as shown in the [example below](#extracting-information) | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ NO_SKIP = ''' | |||||||
|       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE |       label: DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE | ||||||
|       description: Fill all fields even if you think it is irrelevant for the issue |       description: Fill all fields even if you think it is irrelevant for the issue | ||||||
|       options: |       options: | ||||||
|         - label: I understand that I will be **blocked** if I remove or skip any mandatory\\* field |         - label: I understand that I will be **blocked** if I *intentionally* remove or skip any mandatory\\* field | ||||||
|           required: true |           required: true | ||||||
| '''.strip() | '''.strip() | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -3665,6 +3665,7 @@ class YoutubeDL: | |||||||
|                 format_field(f, 'asr', '\t%s', func=format_decimal_suffix), |                 format_field(f, 'asr', '\t%s', func=format_decimal_suffix), | ||||||
|                 join_nonempty( |                 join_nonempty( | ||||||
|                     self._format_out('UNSUPPORTED', 'light red') if f.get('ext') in ('f4f', 'f4m') else None, |                     self._format_out('UNSUPPORTED', 'light red') if f.get('ext') in ('f4f', 'f4m') else None, | ||||||
|  |                     self._format_out('DRM', 'light red') if f.get('has_drm') else None, | ||||||
|                     format_field(f, 'language', '[%s]'), |                     format_field(f, 'language', '[%s]'), | ||||||
|                     join_nonempty(format_field(f, 'format_note'), |                     join_nonempty(format_field(f, 'format_note'), | ||||||
|                                   format_field(f, 'container', ignore=(None, f.get('ext'))), |                                   format_field(f, 'container', ignore=(None, f.get('ext'))), | ||||||
| @@ -3764,12 +3765,13 @@ class YoutubeDL: | |||||||
|         source = detect_variant() |         source = detect_variant() | ||||||
|         if VARIANT not in (None, 'pip'): |         if VARIANT not in (None, 'pip'): | ||||||
|             source += '*' |             source += '*' | ||||||
|  |         klass = type(self) | ||||||
|         write_debug(join_nonempty( |         write_debug(join_nonempty( | ||||||
|             f'{"yt-dlp" if REPOSITORY == "yt-dlp/yt-dlp" else REPOSITORY} version', |             f'{"yt-dlp" if REPOSITORY == "yt-dlp/yt-dlp" else REPOSITORY} version', | ||||||
|             __version__, |             __version__, | ||||||
|             f'[{RELEASE_GIT_HEAD}]' if RELEASE_GIT_HEAD else '', |             f'[{RELEASE_GIT_HEAD}]' if RELEASE_GIT_HEAD else '', | ||||||
|             '' if source == 'unknown' else f'({source})', |             '' if source == 'unknown' else f'({source})', | ||||||
|             '' if _IN_CLI else 'API', |             '' if _IN_CLI else 'API' if klass == YoutubeDL else f'API:{self.__module__}.{klass.__qualname__}', | ||||||
|             delim=' ')) |             delim=' ')) | ||||||
| 
 | 
 | ||||||
|         if not _IN_CLI: |         if not _IN_CLI: | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| import contextlib | import contextlib | ||||||
| import errno |  | ||||||
| import json | import json | ||||||
| import os | import os | ||||||
| import re | import re | ||||||
|   | |||||||
| @@ -191,7 +191,7 @@ query content($sessionIdToken: String!, $deviceLocale: String, $contentId: ID!, | |||||||
| class AmazonMiniTVSeasonIE(AmazonMiniTVBaseIE): | class AmazonMiniTVSeasonIE(AmazonMiniTVBaseIE): | ||||||
|     IE_NAME = 'amazonminitv:season' |     IE_NAME = 'amazonminitv:season' | ||||||
|     _VALID_URL = r'amazonminitv:season:(?:amzn1\.dv\.gti\.)?(?P<id>[a-f0-9-]+)' |     _VALID_URL = r'amazonminitv:season:(?:amzn1\.dv\.gti\.)?(?P<id>[a-f0-9-]+)' | ||||||
|     IE_DESC = 'Amazon MiniTV Series, "minitv:season:" prefix' |     IE_DESC = 'Amazon MiniTV Season, "minitv:season:" prefix' | ||||||
|     _TESTS = [{ |     _TESTS = [{ | ||||||
|         'url': 'amazonminitv:season:amzn1.dv.gti.0aa996eb-6a1b-4886-a342-387fbd2f1db0', |         'url': 'amazonminitv:season:amzn1.dv.gti.0aa996eb-6a1b-4886-a342-387fbd2f1db0', | ||||||
|         'playlist_mincount': 6, |         'playlist_mincount': 6, | ||||||
| @@ -250,6 +250,7 @@ query getEpisodes($sessionIdToken: String!, $clientId: String, $episodeOrSeasonI | |||||||
| class AmazonMiniTVSeriesIE(AmazonMiniTVBaseIE): | class AmazonMiniTVSeriesIE(AmazonMiniTVBaseIE): | ||||||
|     IE_NAME = 'amazonminitv:series' |     IE_NAME = 'amazonminitv:series' | ||||||
|     _VALID_URL = r'amazonminitv:series:(?:amzn1\.dv\.gti\.)?(?P<id>[a-f0-9-]+)' |     _VALID_URL = r'amazonminitv:series:(?:amzn1\.dv\.gti\.)?(?P<id>[a-f0-9-]+)' | ||||||
|  |     IE_DESC = 'Amazon MiniTV Series, "minitv:series:" prefix' | ||||||
|     _TESTS = [{ |     _TESTS = [{ | ||||||
|         'url': 'amazonminitv:series:amzn1.dv.gti.56521d46-b040-4fd5-872e-3e70476a04b0', |         'url': 'amazonminitv:series:amzn1.dv.gti.56521d46-b040-4fd5-872e-3e70476a04b0', | ||||||
|         'playlist_mincount': 3, |         'playlist_mincount': 3, | ||||||
|   | |||||||
| @@ -61,6 +61,35 @@ class EmbedlyIE(InfoExtractor): | |||||||
|         'only_matching': True, |         'only_matching': True, | ||||||
|     }] |     }] | ||||||
| 
 | 
 | ||||||
|  |     _WEBPAGE_TESTS = [{ | ||||||
|  |         'url': 'http://www.permacultureetc.com/2022/12/comment-greffer-facilement-les-arbres-fruitiers.html', | ||||||
|  |         'info_dict': { | ||||||
|  |             'id': 'pfUK_ADTvgY', | ||||||
|  |             'ext': 'mp4', | ||||||
|  |             'title': 'Comment greffer facilement les arbres fruitiers ? (mois par mois)', | ||||||
|  |             'description': 'md5:d3a876995e522f138aabb48e040bfb4c', | ||||||
|  |             'view_count': int, | ||||||
|  |             'upload_date': '20221210', | ||||||
|  |             'comment_count': int, | ||||||
|  |             'live_status': 'not_live', | ||||||
|  |             'channel_id': 'UCsM4_jihNFYe4CtSkXvDR-Q', | ||||||
|  |             'channel_follower_count': int, | ||||||
|  |             'tags': ['permaculture', 'jardinage', 'dekarz', 'autonomie', 'greffe', 'fruitiers', 'arbres', 'jardin forêt', 'forêt comestible', 'damien'], | ||||||
|  |             'playable_in_embed': True, | ||||||
|  |             'uploader': 'permaculture agroécologie etc...', | ||||||
|  |             'channel': 'permaculture agroécologie etc...', | ||||||
|  |             'thumbnail': 'https://i.ytimg.com/vi/pfUK_ADTvgY/sddefault.jpg', | ||||||
|  |             'duration': 1526, | ||||||
|  |             'channel_url': 'https://www.youtube.com/channel/UCsM4_jihNFYe4CtSkXvDR-Q', | ||||||
|  |             'age_limit': 0, | ||||||
|  |             'uploader_id': 'permacultureetc', | ||||||
|  |             'like_count': int, | ||||||
|  |             'uploader_url': 'http://www.youtube.com/user/permacultureetc', | ||||||
|  |             'categories': ['Education'], | ||||||
|  |             'availability': 'public', | ||||||
|  |         }, | ||||||
|  |     }] | ||||||
|  | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def _extract_from_webpage(cls, url, webpage): |     def _extract_from_webpage(cls, url, webpage): | ||||||
|         # Bypass "ie=cls" and suitable check |         # Bypass "ie=cls" and suitable check | ||||||
|   | |||||||
| @@ -133,9 +133,9 @@ class RadikoBaseIE(InfoExtractor): | |||||||
|                     'X-Radiko-AreaId': area_id, |                     'X-Radiko-AreaId': area_id, | ||||||
|                     'X-Radiko-AuthToken': auth_token, |                     'X-Radiko-AuthToken': auth_token, | ||||||
|                 }) |                 }) | ||||||
|             not_preferred = is_onair and not pcu.startswith(self._HOSTS_FOR_LIVE) or (not is_onair and (pcu.startswith(self._HOSTS_FOR_TIME_FREE_FFMPEG_UNSUPPORTED) or pcu.startswith(self._HOSTS_FOR_LIVE))) |  | ||||||
|             for sf in subformats: |             for sf in subformats: | ||||||
|                 if not_preferred: |                 if (is_onair ^ pcu.startswith(self._HOSTS_FOR_LIVE)) or ( | ||||||
|  |                         not is_onair and pcu.startswith(self._HOSTS_FOR_TIME_FREE_FFMPEG_UNSUPPORTED)): | ||||||
|                     sf['preference'] = -100 |                     sf['preference'] = -100 | ||||||
|                     sf['format_note'] = 'not preferred' |                     sf['format_note'] = 'not preferred' | ||||||
|                 if not is_onair and url_attrib['timefree'] == '1' and time_to_skip: |                 if not is_onair and url_attrib['timefree'] == '1' and time_to_skip: | ||||||
|   | |||||||
| @@ -4459,19 +4459,6 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor): | |||||||
|             return info_dict |             return info_dict | ||||||
|         return wrapper |         return wrapper | ||||||
| 
 | 
 | ||||||
|     def _extract_channel_id(self, webpage): |  | ||||||
|         channel_id = self._html_search_meta( |  | ||||||
|             'channelId', webpage, 'channel id', default=None) |  | ||||||
|         if channel_id: |  | ||||||
|             return channel_id |  | ||||||
|         channel_url = self._html_search_meta( |  | ||||||
|             ('og:url', 'al:ios:url', 'al:android:url', 'al:web:url', |  | ||||||
|              'twitter:url', 'twitter:app:url:iphone', 'twitter:app:url:ipad', |  | ||||||
|              'twitter:app:url:googleplay'), webpage, 'channel url') |  | ||||||
|         return self._search_regex( |  | ||||||
|             r'https?://(?:www\.)?youtube\.com/channel/([^/?#&])+', |  | ||||||
|             channel_url, 'channel id') |  | ||||||
| 
 |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def _extract_basic_item_renderer(item): |     def _extract_basic_item_renderer(item): | ||||||
|         # Modified from _extract_grid_item_renderer |         # Modified from _extract_grid_item_renderer | ||||||
|   | |||||||
| @@ -1031,7 +1031,7 @@ def create_parser(): | |||||||
|         metavar='URL', dest='referer', default=None, |         metavar='URL', dest='referer', default=None, | ||||||
|         help=optparse.SUPPRESS_HELP) |         help=optparse.SUPPRESS_HELP) | ||||||
|     workarounds.add_option( |     workarounds.add_option( | ||||||
|         '--add-header', |         '--add-headers', | ||||||
|         metavar='FIELD:VALUE', dest='headers', default={}, type='str', |         metavar='FIELD:VALUE', dest='headers', default={}, type='str', | ||||||
|         action='callback', callback=_dict_from_options_callback, |         action='callback', callback=_dict_from_options_callback, | ||||||
|         callback_kwargs={'multiple_keys': False}, |         callback_kwargs={'multiple_keys': False}, | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import re | import re | ||||||
| 
 | 
 | ||||||
| from .common import PostProcessor | from .common import PostProcessor | ||||||
| from ..utils import Namespace, filter_dict | from ..utils import Namespace, filter_dict, function_with_repr | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class MetadataParserPP(PostProcessor): | class MetadataParserPP(PostProcessor): | ||||||
| @@ -60,6 +60,7 @@ class MetadataParserPP(PostProcessor): | |||||||
|             f(info) |             f(info) | ||||||
|         return [], info |         return [], info | ||||||
| 
 | 
 | ||||||
|  |     @function_with_repr | ||||||
|     def interpretter(self, inp, out): |     def interpretter(self, inp, out): | ||||||
|         def f(info): |         def f(info): | ||||||
|             data_to_parse = self._downloader.evaluate_outtmpl(template, info) |             data_to_parse = self._downloader.evaluate_outtmpl(template, info) | ||||||
| @@ -76,6 +77,7 @@ class MetadataParserPP(PostProcessor): | |||||||
|         out_re = re.compile(self.format_to_regex(out)) |         out_re = re.compile(self.format_to_regex(out)) | ||||||
|         return f |         return f | ||||||
| 
 | 
 | ||||||
|  |     @function_with_repr | ||||||
|     def replacer(self, field, search, replace): |     def replacer(self, field, search, replace): | ||||||
|         def f(info): |         def f(info): | ||||||
|             val = info.get(field) |             val = info.get(field) | ||||||
|   | |||||||
| @@ -3650,7 +3650,8 @@ def get_compatible_ext(*, vcodecs, acodecs, vexts, aexts, preferences=None): | |||||||
|         }, |         }, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     sanitize_codec = functools.partial(try_get, getter=lambda x: x[0].split('.')[0].replace('0', '')) |     sanitize_codec = functools.partial( | ||||||
|  |         try_get, getter=lambda x: x[0].split('.')[0].replace('0', '').lower()) | ||||||
|     vcodec, acodec = sanitize_codec(vcodecs), sanitize_codec(acodecs) |     vcodec, acodec = sanitize_codec(vcodecs), sanitize_codec(acodecs) | ||||||
| 
 | 
 | ||||||
|     for ext in preferences or COMPATIBLE_CODECS.keys(): |     for ext in preferences or COMPATIBLE_CODECS.keys(): | ||||||
| @@ -3915,7 +3916,7 @@ class download_range_func: | |||||||
|                 and self.chapters == other.chapters and self.ranges == other.ranges) |                 and self.chapters == other.chapters and self.ranges == other.ranges) | ||||||
| 
 | 
 | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return f'{type(self).__name__}({self.chapters}, {self.ranges})' |         return f'{__name__}.{type(self).__name__}({self.chapters}, {self.ranges})' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def parse_dfxp_time_expr(time_expr): | def parse_dfxp_time_expr(time_expr): | ||||||
| @@ -6018,6 +6019,18 @@ class classproperty: | |||||||
|         return self._cache[cls] |         return self._cache[cls] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class function_with_repr: | ||||||
|  |     def __init__(self, func): | ||||||
|  |         functools.update_wrapper(self, func) | ||||||
|  |         self.func = func | ||||||
|  | 
 | ||||||
|  |     def __call__(self, *args, **kwargs): | ||||||
|  |         return self.func(*args, **kwargs) | ||||||
|  | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         return f'{self.func.__module__}.{self.func.__qualname__}' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class Namespace(types.SimpleNamespace): | class Namespace(types.SimpleNamespace): | ||||||
|     """Immutable namespace""" |     """Immutable namespace""" | ||||||
| 
 | 
 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 pukkandan
					pukkandan