# Contributor handoff — ytdl-org/youtube-dl

> Canonical page: https://codevetter.com/unpack/youtube-dl/agent-handoff

# Contributor handoff — ytdl-org/youtube-dl

Scanned commit 956b8c585591b401a543e409accb163eeaaa1193 (2025-11-26). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

For an agent working in this repo: read CONTRIBUTING.md's developer instructions and extractor/common.py's giant docstring first; the info-dict contract and the 'first suitable() wins' ordering are the two invariants that matter most. Python 2.6-compatible style (unicode_literals, compat_* aliases, no f-strings, %-formatting) is mandatory and enforced by CI. Tests are nosetests; extractor changes get a live _TEST; run flake8 with the repo's setup.cfg ignores. Generated files (lazy_extractors.py, README.md, completions, man page) are produced by Makefile/devscripts — edit sources, not artifacts.
- Read first: youtube_dl/extractor/common.py's InfoExtractor docstring (the entire info-dict schema), CONTRIBUTING.md 'DEVELOPER INSTRUCTIONS' + 'youtube-dl coding conventions', youtube_dl/YoutubeDL.py's options docstring, and youtube_dl/__init__.py _real_main for how params map to CLI flags. — [youtube_dl/extractor/common.py#L98-417](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/common.py#L98-L417) [CONTRIBUTING.md#L71-188](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/CONTRIBUTING.md#L71-L188) [youtube_dl/YoutubeDL.py#L148-356](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/YoutubeDL.py#L148-L356) [youtube_dl/__init__.py#L49-488](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/__init__.py#L49-L488)
- Adding an extractor: new file in youtube_dl/extractor/, class name must end in 'IE', _VALID_URL with a named (?P<id>...) group is conventional, import the class in extractors.py (order = precedence), include a _TEST dict with a real URL; commit style is '[name] Add new extractor'. — [CONTRIBUTING.md#L111-166](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/CONTRIBUTING.md#L111-L166) [youtube_dl/extractor/common.py#L386-395](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/common.py#L386-L395) [youtube_dl/extractor/extractors.py](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/extractors.py)
- Mandatory info-dict fields are id and title plus either url or formats; everything else must be extracted defensively (helpers: _search_regex with default=, try_get, traverse_obj, int_or_none/float_or_none) because extractors must tolerate missing optional data. — [youtube_dl/extractor/common.py#L113-121](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/common.py#L113-L121) [CONTRIBUTING.md#L180-188](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/CONTRIBUTING.md#L180-L188) [test/helper.py#L209-217](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/test/helper.py#L209-L217)
- Run tests with `python test/test_download.py TestDownload.test_<Name>` for a single extractor; `make offlinetest` (or nosetests with the exclusion list) for network-free checks; full `make test` requires live network access and will fail on sites that changed since the pinned commit. — [CONTRIBUTING.md#L154](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/CONTRIBUTING.md#L154) [Makefile#L35-52](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/Makefile#L35-L52) [devscripts/run_tests.sh](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/devscripts/run_tests.sh)
- Lint with `flake8 .` honoring setup.cfg (ignores E402/E501/E731/E741/W503, excludes generated files); style is %-formatting, `from __future__ import unicode_literals` at top of every file, compat_* imports from youtube_dl/compat.py instead of py3-only stdlib paths. — [setup.cfg](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/setup.cfg) [.github/workflows/ci.yml#L469-481](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/.github/workflows/ci.yml#L469-L481) [youtube_dl/compat.py](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/compat.py)
- Lazy-extractor constraint is a known trap: if you override suitable() or reference _VALID_URL oddly, devscripts/make_lazy_extractors.py output can break — keep suitable() self-importing and prefer plain _VALID_URL regexes; regenerate via `make lazy-extractors` or `python setup.py build_lazy_extractors`. — [youtube_dl/extractor/common.py#L391-395](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/common.py#L391-L395) [devscripts/make_lazy_extractors.py](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/devscripts/make_lazy_extractors.py) [setup.py#L86-100](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/setup.py#L86-L100) [Makefile#L114-118](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/Makefile#L114-L118)
- GenericIE must remain the last resort: _ALL_CLASSES appends it explicitly and many extractors emit url_result(ie=GenericIE.ie_key()) delegates; do not reorder extractors casually — the first regex match wins. — [youtube_dl/extractor/__init__.py#L11-16](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/__init__.py#L11-L16) [youtube_dl/extractor/generic.py#L137](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/generic.py#L137) [youtube_dl/extractor/generic.py#L3762](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/generic.py#L3762)
- Generated artifacts to not hand-edit: youtube_dl/extractor/lazy_extractors.py (devscripts/make_lazy_extractors.py), README.md/CONTRIBUTING.md (devscripts/make_readme.py/make_contributing.py), docs/supportedsites.md (make_supportedsites.py), completions and man page (Makefile targets). — [Makefile#L75-118](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/Makefile#L75-L118) [devscripts/make_lazy_extractors.py](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/devscripts/make_lazy_extractors.py) [devscripts/make_supportedsites.py](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/devscripts/make_supportedsites.py)
- Safe edit boundaries: adding a new extractor file + extractors.py import is low-blast-radius; editing extractor/common.py, utils.py, YoutubeDL.py or downloader/common.py affects every site — keep changes additive, preserve py2.6 compatibility, and remember `_real_main` mutates the global std_headers dict and params dicts are shared references. (inferred) — [youtube_dl/__init__.py#L59-75](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/__init__.py#L59-L75) [youtube_dl/downloader/__init__.py#L8-11](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/downloader/__init__.py#L8-L11) [youtube_dl/compat.py](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/compat.py)
- Debugging support built in: --verbose prints the debug header (version, git HEAD, Python, exe versions, proxy map), --write-pages/--dump-pages dump raw server responses, --print-traffic logs HTTP, and --youtube-print-sig-code prints the extracted signature function — use these before touching extractor code. — [youtube_dl/YoutubeDL.py#L2497-2576](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/YoutubeDL.py#L2497-L2576) [youtube_dl/extractor/youtube.py#L1863-1903](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/youtube_dl/extractor/youtube.py#L1863-L1903) [CONTRIBUTING.md#L1-40](https://github.com/ytdl-org/youtube-dl/blob/956b8c585591b401a543e409accb163eeaaa1193/CONTRIBUTING.md#L1-L40)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
