{"id":90246,"date":"2026-08-04T22:32:40","date_gmt":"2026-08-04T14:32:40","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/90246.html"},"modified":"2026-08-04T22:32:40","modified_gmt":"2026-08-04T14:32:40","slug":"%e5%ae%9e%e6%88%98%e6%a8%aa%e8%af%84%e3%80%91%e4%b8%bb%e6%b5%81-ai-%e7%bc%96%e7%a8%8b%e5%b7%a5%e5%85%b7%e5%ae%9e%e6%b5%8b%e5%af%b9%e6%af%94%ef%bc%8c%e7%9c%8b%e5%ae%8c%e4%b8%8d%e5%86%8d%e7%9b%b2","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/90246.html","title":{"rendered":"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b"},"content":{"rendered":"<h2>AI \u7f16\u7a0b\u5de5\u5177\u6a2a\u8bc4\u5b9e\u6d4b\u62a5\u544a&#xff08;2026-08-04&#xff09;<\/h2>\n<p>7 \u6b3e AI \u7f16\u7a0b\u5de5\u5177&#xff0c;\u540c\u4e00\u6a21\u578b&#xff08;deepseek-v4-flash&#xff09;\u3001\u540c\u4e00\u6d4b\u8bd5\u9898\u3001\u540c\u4e00\u7f51\u5173\u5e76\u884c\u5b9e\u6d4b\u3002 \u9644\u5e26 token \u6d88\u8017\u5bf9\u6bd4 &#043; \u4ee3\u7801\u8d28\u91cf &#043; \u901f\u5ea6 &#043; \u6613\u7528\u6027 &#043; \u5df2\u77e5 bug \u5168\u8bb0\u5f55\u3002<\/p>\n<hr \/>\n<h3>\u76ee\u5f55<\/h3>\n<ul>\n<li>\u5feb\u901f\u7ed3\u8bba&#xff08;30 \u79d2\u7248&#xff09;<\/li>\n<li>\u6d4b\u8bd5\u65b9\u6cd5&#xff08;\u5b8c\u6574\u7248&#xff09;\n<ul>\n<li>\u6d4b\u8bd5\u9898\u539f\u6587 \/ \u7edf\u4e00\u73af\u5883 \/ \u6267\u884c\u547d\u4ee4 \/ \u5224\u5b9a\u6807\u51c6 \/ \u5c40\u9650\u4e0e\u504f\u5dee \/ \u9009\u578b\u51b3\u7b56<\/li>\n<\/ul>\n<\/li>\n<li>\u7ed3\u679c\u603b\u8868<\/li>\n<li>\u5206\u5de5\u5177\u8be6\u89e3&#xff08;7 \u6b3e\u9010\u4e00\u5206\u6790&#xff09;<\/li>\n<li>\u6a21\u578b\u5bf9\u6bd4&#xff1a;glm_for_coding vs deepseek-v4-flash<\/li>\n<li>\u6700\u7ec8\u63a8\u8350<\/li>\n<li>\u90e8\u7f72\u4e0e\u914d\u7f6e\u5751&#xff08;\u8be6\u7248&#xff09;<\/li>\n<li>Token \u6570\u636e\u8bc1\u636e\u94fe<\/li>\n<li>\u6d4b\u8bd5\u4ea7\u7269\u5168\u96c6&#xff08;7 \u4efd\u5b8c\u6574\u4ee3\u7801 &#043; pytest \u8f93\u51fa&#xff09;<\/li>\n<\/ul>\n<hr \/>\n<h3>\u5feb\u901f\u7ed3\u8bba&#xff08;30 \u79d2\u7248&#xff09;<\/h3>\n<table>\n<tr>\u7ed3\u8bba\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>&#x1f3c6; \u6700\u4f73\u5de5\u5177<\/td>\n<td>OpenCode \u2014 \u6700\u5feb&#xff08;32s&#xff09;&#043; \u6700\u7701 token&#xff08;11.7K&#xff09;&#xff0c;\u8d28\u91cf\u8fc7\u5173<\/td>\n<\/tr>\n<tr>\n<td>\u8d28\u91cf\u5929\u82b1\u677f<\/td>\n<td>Claude Code \u2014 22\/22 \u6d4b\u8bd5\u6700\u5168\u6700\u4e25\u8c28&#xff0c;\u4f46 token \u6d88\u8017\u6700\u5927<\/td>\n<\/tr>\n<tr>\n<td>\u610f\u5916\u4e4b\u559c<\/td>\n<td>Codex \u2014 \u6362 deepseek \u540e\u4ece\u5931\u8d25\u00d74 \u53d8 13\/13&#xff08;\u4e4b\u524d\u662f\u6a21\u578b\u95ee\u9898&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u914d\u7f6e\u6700\u5751<\/td>\n<td>Goose \/ Crush \u2014 \u4fee\u597d\u914d\u7f6e\u540e\u90fd\u80fd\u7528&#xff0c;\u4f46\u8fc7\u7a0b\u66f2\u6298&#xff08;\u8be6\u89c1\u90e8\u7f72\u5751&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u4e0d\u63a8\u8350<\/td>\n<td>Kilo&#xff08;OpenCode \u52a3\u5316\u7248&#xff09;\u3001Cline CLI&#xff08;team_status \u5d29\u6e83 bug&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u901a\u7528\u7ed3\u8bba<\/td>\n<td>deepseek-v4-flash \u662f\u5f53\u524d\u7f51\u5173\u4e0b\u6700\u4f73\u7f16\u7801\u6a21\u578b&#xff08;\u6bd4 glm_for_coding \u5feb 5-15 \u500d&#xff09;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u9605\u8bfb\u5bfc\u822a&#xff1a;\u60f3\u590d\u73b0\u6d4b\u8bd5\u770b \u6d4b\u8bd5\u65b9\u6cd5&#xff1b;\u60f3\u6311\u5de5\u5177\u770b \u6700\u7ec8\u63a8\u8350&#xff1b;\u60f3\u770b\u5404\u5de5\u5177\u5b9e\u9645\u5199\u7684\u4ee3\u7801\u770b \u6d4b\u8bd5\u4ea7\u7269\u5168\u96c6&#xff1b;\u60f3\u907f\u5751\u770b \u90e8\u7f72\u4e0e\u914d\u7f6e\u5751&#xff1b;\u60f3\u6838\u5bf9\u6570\u5b57\u770b Token \u8bc1\u636e\u94fe\u3002<\/p>\n<hr \/>\n<h3>\u6d4b\u8bd5\u65b9\u6cd5&#xff08;\u5b8c\u6574\u7248&#xff09;<\/h3>\n<h4>1. \u6d4b\u8bd5\u9898&#xff08;\u9010\u5b57\u539f\u6587&#xff0c;\u6240\u6709\u5de5\u5177\u6536\u5230\u7684 prompt \u5b8c\u5168\u76f8\u540c&#xff09;<\/h4>\n<p>Create todo.py (Python CLI todo app with add\/list\/done\/delete commands and JSON persistence) and test_todo.py (pytest unit tests). Run the tests and make sure they pass.<\/p>\n<p>\u4e2d\u6587\u7ffb\u8bd1&#xff1a;\u521b\u5efa todo.py&#xff08;\u5e26 add\/list\/done\/delete \u547d\u4ee4\u548c JSON \u6301\u4e45\u5316\u7684 Python CLI \u5f85\u529e\u5e94\u7528&#xff09;\u548c test_todo.py&#xff08;pytest \u5355\u5143\u6d4b\u8bd5&#xff09;\u3002\u8fd0\u884c\u6d4b\u8bd5\u5e76\u786e\u4fdd\u5168\u90e8\u901a\u8fc7\u3002<\/p>\n<p>\u8fd9\u4e2a\u6d4b\u8bd5\u9898\u8003\u5bdf\u7684\u80fd\u529b&#xff1a;<\/p>\n<ul>\n<li>\u7406\u89e3\u9700\u6c42\u5e76\u62c6\u89e3&#xff08;CLI \u547d\u4ee4\u8bbe\u8ba1\u3001JSON \u5b58\u50a8\u8bbe\u8ba1&#xff09;<\/li>\n<li>\u5199\u51fa\u53ef\u6d4b\u8bd5\u7684\u4ee3\u7801&#xff08;\u51fd\u6570\/\u7c7b\u7ed3\u6784\u53ef\u88ab pytest \u5f15\u7528&#xff09;<\/li>\n<li>\u81ea\u5df1\u5199\u6d4b\u8bd5\u7528\u4f8b\u8986\u76d6\u529f\u80fd<\/li>\n<li>\u6267\u884c\u6d4b\u8bd5\u3001\u53d1\u73b0\u5931\u8d25\u3001\u4fee\u590d\u5230\u5168\u8fc7&#xff08;\u81ea\u6211\u9a8c\u8bc1\u95ed\u73af&#xff09;<\/li>\n<li>\u5de5\u5177\u94fe\u4f7f\u7528&#xff08;argparse\u3001json\u3001pytest\u3001\u6587\u4ef6\u8bfb\u5199&#xff09;<\/li>\n<\/ul>\n<h4>2. \u7edf\u4e00\u73af\u5883<\/h4>\n<table>\n<tr>\u9879\u503c<\/tr>\n<tbody>\n<tr>\n<td>\u6d4b\u8bd5\u65e5\u671f<\/td>\n<td>2026-08-04<\/td>\n<\/tr>\n<tr>\n<td>\u6a21\u578b<\/td>\n<td>deepseek-v4-flash&#xff08;\u7edf\u4e00&#xff0c;\u901a\u8fc7\u7f51\u5173 https:\/\/api.myagentlab.homes\/v1&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>API key<\/td>\n<td>\u540c\u4e00\u628a\u7f51\u5173 key&#xff08;\u7528\u6237\u63d0\u4f9b&#xff0c;\u89c1 credentials&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u7cfb\u7edf<\/td>\n<td>root \u7528\u6237&#xff0c;Linux<\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td>3.13.5<\/td>\n<\/tr>\n<tr>\n<td>pytest<\/td>\n<td>9.1.1&#xff08;venv: \/tmp\/bench-venv&#xff0c;\u7cfb\u7edf\u65e0 pip \u6545\u7528 uv \u5efa venv \u88c5&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u4f5c\u76ee\u5f55<\/td>\n<td>\/home\/agent\/coding-benchmark\/test-&lt;\u5de5\u5177\u540d&gt;\/&#xff08;\u6bcf\u5de5\u5177\u72ec\u7acb\u76ee\u5f55&#xff0c;\u4e92\u4e0d\u5e72\u6270&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u6267\u884c\u65b9\u5f0f<\/td>\n<td>7 \u5de5\u5177\u5e76\u884c\u540e\u53f0\u8fd0\u884c&#xff08;\u540c\u6a21\u578b\u540c key \u540c\u65f6\u8dd1&#xff0c;\u7f51\u5173\u7ade\u4e89\u73af\u5883\u4e00\u81f4&#xff09;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>3. \u6bcf\u4e2a\u5de5\u5177\u7684\u5177\u4f53\u6267\u884c\u547d\u4ee4&#xff08;\u5b9e\u6d4b\u7528\u7684\u771f\u5b9e\u547d\u4ee4&#xff09;<\/h4>\n<table>\n<tr>\u5de5\u5177\u542f\u52a8\u547d\u4ee4\u5907\u6ce8<\/tr>\n<tbody>\n<tr>\n<td>Claude Code<\/td>\n<td>claude -p &#034;&lt;\u6d4b\u8bd5\u9898&gt;&#034; &#8211;model deepseek-v4-flash &#8211;allowedTools &#039;Bash,Write,Read,Edit&#039; &#8211;output-format stream-json &#8211;verbose<\/td>\n<td>root \u4e0d\u80fd\u7528 &#8211;dangerously-skip-permissions<\/td>\n<\/tr>\n<tr>\n<td>OpenCode<\/td>\n<td>opencode run &#034;&lt;\u6d4b\u8bd5\u9898&gt;&#034;<\/td>\n<td>\u9879\u76ee\u7ea7 opencode.json \u914d myagentlab provider<\/td>\n<\/tr>\n<tr>\n<td>Codex<\/td>\n<td>codex exec &#8211;dangerously-bypass-approvals-and-sandbox &#8211;skip-git-repo-check &#8211;json &#039;&lt;\u6d4b\u8bd5\u9898&gt;&#039;<\/td>\n<td>config.toml \u914d wire_api&#061;chat<\/td>\n<\/tr>\n<tr>\n<td>Cline<\/td>\n<td>cline &#8211;json &#034;&lt;\u6d4b\u8bd5\u9898&gt;&#034;<\/td>\n<td>cline auth openai \u914d\u597d&#xff1b;team_status bug \u9700 enableTeams:false \u7f13\u89e3<\/td>\n<\/tr>\n<tr>\n<td>Kilo<\/td>\n<td>kilo run -m myagentlab\/deepseek-v4-flash &#034;&lt;\u6d4b\u8bd5\u9898&gt;&#034;<\/td>\n<td>kilo.jsonc \u914d myagentlab provider<\/td>\n<\/tr>\n<tr>\n<td>Crush<\/td>\n<td>crush run -m myagentlab\/deepseek-v4-flash &#034;&lt;\u6d4b\u8bd5\u9898&gt;&#034;<\/td>\n<td>crush.json \u914d myagentlab provider<\/td>\n<\/tr>\n<tr>\n<td>Goose<\/td>\n<td>goose run -t &#039;&lt;\u6d4b\u8bd5\u9898&gt;&#039; &#8211;provider myagentlab &#8211;model deepseek-v4-flash<\/td>\n<td>\u9700\u81ea\u5b9a\u4e49 provider &#043; supports_streaming:false<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>4. \u5224\u5b9a\u6807\u51c6<\/h4>\n<ul>\n<li>\u901a\u8fc7 &#061; \u8be5\u5de5\u5177\u81ea\u5df1\u751f\u6210\u7684 test_todo.py \u7528 pytest \u8dd1\u901a&#xff08;\/tmp\/bench-venv\/bin\/python -m pytest test_todo.py&#xff09;&#xff0c;\u6d4b\u8bd5\u6570\u91cf\u7531\u5de5\u5177\u81ea\u5df1\u51b3\u5b9a&#xff08;22\/12\/13\/24\/10\/13\/17 \u5404\u4e0d\u76f8\u540c&#xff09;<\/li>\n<li>\u8017\u65f6 &#061; \u4ece\u542f\u52a8\u547d\u4ee4\u5230\u8fdb\u7a0b\u9000\u51fa&#xff08;\u542b\u6a21\u578b\u9996 token \u5ef6\u8fdf &#043; \u5de5\u5177\u81ea\u6211\u8fed\u4ee3&#xff09;<\/li>\n<li>token \u6570\u636e &#061; \u5404\u5de5\u5177\u672c\u5730\u8bb0\u5f55&#xff08;\u6765\u6e90\u89c1&#034;Token \u6570\u636e\u8bc1\u636e\u94fe&#034;\u7ae0\u8282&#xff09;<\/li>\n<li>\u4ee3\u7801\u8d28\u91cf &#061; \u4eba\u5de5\u68c0\u67e5\u4ea7\u7269&#xff08;\u6d4b\u8bd5\u8986\u76d6\u3001\u8fb9\u754c\u5904\u7406\u3001\u53ef\u8bfb\u6027&#xff09;<\/li>\n<\/ul>\n<h4>5. \u6d4b\u8bd5\u7684\u5c40\u9650\u4e0e\u5df2\u77e5\u504f\u5dee&#xff08;\u8bda\u5b9e\u58f0\u660e&#xff09;<\/h4>\n<li>Cline \u7684 24\/24 \u662f\u4fee\u590d\u540e\u7684&#xff1a;\u539f\u59cb 22\/24&#xff08;2 \u4e2a\u4ee3\u7801 bug&#xff09;&#xff0c;\u6211\u624b\u52a8\u4fee\u590d\u4e86\u8fd9 2 \u4e2a bug \u540e\u590d\u9a8c 24\/24\u3002\u7eaf\u5de5\u5177\u4ea7\u51fa\u662f 22\/24\u3002<\/li>\n<li>Codex token \u662f\u4f30\u7b97\u503c&#xff1a;\u672c\u5730\u4e0d\u8bb0\u5f55 usage&#xff0c;\u7f51\u5173\u65e0\u5206 key \u660e\u7ec6&#xff0c;\u6309 6 \u8f6e\u8bf7\u6c42 \u00d7 \u7d2f\u79ef\u4e0a\u4e0b\u6587\u4f30\u7b97\u3002\u6210\u672c ~$0.027 \u662f\u6309 deepseek \u5b9a\u4ef7\u5012\u63a8\u3002<\/li>\n<li>Crush \u7684 completion_tokens&#061;40 \u7591\u4f3c\u8bb0\u5f55 bug&#xff1a;\u5b9e\u9645\u751f\u6210\u4e86 124 \u884c\u4ee3\u7801&#xff0c;40 token \u4e0d\u53ef\u80fd&#xff0c;\u7591\u4f3c\u53ea\u8bb0\u672b\u6b21\u8bf7\u6c42\u3002<\/li>\n<li>\u5e76\u884c\u6d4b\u8bd5\u7684\u7ade\u4e89\u5f71\u54cd&#xff1a;7 \u5de5\u5177\u540c\u65f6\u8dd1&#xff0c;\u5171\u4eab\u7f51\u5173 key\u3002\u9996\u8f6e glm_for_coding \u6d4b\u8bd5\u65f6\u540e\u53f0\u8fd8\u6709 MRS refactor \u4efb\u52a1&#xff08;PID 636956&#xff09;\u5e76\u53d1\u6d88\u8017\u540c key&#xff0c;\u5bfc\u81f4\u7f51\u5173 GLM \u6e20\u9053\u9996 token 40-70s \u5ef6\u8fdf&#xff0c;\u95f4\u63a5\u5bfc\u81f4 Codex \u5728 glm \u4e0b 4 \u6b21\u8d85\u65f6\u5931\u8d25\u2014\u2014\u6362 deepseek \u540e 1.7s \u9996 token&#xff0c;\u8be5\u5e72\u6270\u6d88\u5931\u3002<\/li>\n<li>\u6d4b\u8bd5\u9898\u504f\u7b80\u5355&#xff1a;todo.py \u662f\u5e38\u89c4 CRUD \u5e94\u7528&#xff0c;\u8003\u5bdf\u7684\u662f&#034;\u5de5\u5177\u80fd\u5426\u5b8c\u6210\u6807\u51c6\u5de5\u7a0b\u4efb\u52a1&#034;&#xff0c;\u4e0d\u6d89\u53ca\u5927\u578b\u4ee3\u7801\u5e93\u5bfc\u822a\u3001\u591a\u6587\u4ef6\u91cd\u6784\u3001\u590d\u6742\u8c03\u8bd5\u7b49\u9ad8\u7ea7\u573a\u666f\u3002<\/li>\n<li>CLI \u6a21\u5f0f vs \u771f\u5b9e\u573a\u666f&#xff1a;Cline\/Kilo \u7684\u771f\u5b9e\u5f62\u6001\u662f VS Code \u6269\u5c55&#xff0c;\u6b64\u5904\u6d4b\u7684\u662f\u5b83\u4eec\u7684 CLI \u7248&#xff1b;Goose\/Crush \u662f CLI \u539f\u751f\u3002Claude Code\/Codex\/OpenCode \u4e5f\u4e3b\u8981\u662f\u7ec8\u7aef\u5de5\u5177\u3002<\/li>\n<h4>6. \u4e3a\u4ec0\u4e48\u9009 deepseek-v4-flash&#xff08;\u51b3\u7b56\u8fc7\u7a0b&#xff09;<\/h4>\n<ul>\n<li>\u9996\u8f6e\u7528 glm_for_coding&#xff08;\u7f51\u5173 GLM \u6e20\u9053&#xff09;&#xff1a;\u9996 token 40-70 \u79d2&#xff0c;\u6bcf\u5de5\u5177 7-9 \u5206\u949f&#xff0c;\u4e14 Codex heredoc \u8f6c\u4e49\u9519\u4e71\u3001Crush \u6709 DEFAULT_FILE bug<\/li>\n<li>\u7528\u6237\u5efa\u8bae\u6d4b\u8bd5 deepseek \u6a21\u578b \u2192 \u5b9e\u6d4b 1.7s \u9996 token&#xff0c;\u4e14 Codex\/Crush \u7684\u95ee\u9898\u81ea\u52a8\u6d88\u5931<\/li>\n<li>\u6700\u7ec8\u7edf\u4e00\u7528 deepseek-v4-flash \u91cd\u6d4b\u5168\u90e8 7 \u5de5\u5177&#xff08;\u7b2c\u4e8c\u8f6e&#xff09;&#xff0c;\u4fdd\u8bc1\u516c\u5e73<\/li>\n<li>\u9996\u8f6e glm \u6570\u636e\u4ec5\u4f5c\u5bf9\u7167\u53c2\u8003&#xff0c;\u6392\u540d\u4ee5 deepseek \u8f6e\u4e3a\u51c6<\/li>\n<\/ul>\n<h3>\u7ed3\u679c\u603b\u8868<\/h3>\n<table>\n<tr>\u6392\u540d\u5de5\u5177\u7248\u672c\u6d4b\u8bd5\u7ed3\u679c\u8017\u65f6Input tokensCache readOutput tokens\u4ee3\u7801\u91cf<\/tr>\n<tbody>\n<tr>\n<td>&#x1f947;<\/td>\n<td>OpenCode<\/td>\n<td>1.18.12<\/td>\n<td>\u2705 12\/12<\/td>\n<td>32s<\/td>\n<td>11,749<\/td>\n<td>40,576<\/td>\n<td>1,992<\/td>\n<td>115&#043;94 \u884c<\/td>\n<\/tr>\n<tr>\n<td>&#x1f948;<\/td>\n<td>Claude Code<\/td>\n<td>2.1.220<\/td>\n<td>\u2705 22\/22<\/td>\n<td>134s<\/td>\n<td>227,467<\/td>\n<td>190,976<\/td>\n<td>12,435<\/td>\n<td>141&#043;182 \u884c<\/td>\n<\/tr>\n<tr>\n<td>&#x1f949;<\/td>\n<td>Codex<\/td>\n<td>0.50.0<\/td>\n<td>\u2705 13\/13<\/td>\n<td>78s<\/td>\n<td>~132K (\u4f30)*<\/td>\n<td>\u2014<\/td>\n<td>~12K (\u4f30)*<\/td>\n<td>\u7ea6 180 \u884c<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>Goose<\/td>\n<td>1.45.0<\/td>\n<td>\u2705 17\/17<\/td>\n<td>77s<\/td>\n<td>80,848<\/td>\n<td>43,776<\/td>\n<td>6,769<\/td>\n<td>126&#043;146 \u884c<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>Crush<\/td>\n<td>go \u7f16\u8bd1\u7248<\/td>\n<td>\u2705 13\/13<\/td>\n<td>66s<\/td>\n<td>14,499<\/td>\n<td>\u65e0\u6b64\u5b57\u6bb5\u2020<\/td>\n<td>40\u2021<\/td>\n<td>124&#043;102 \u884c<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>Cline<\/td>\n<td>3.0.49<\/td>\n<td>\u2705 24\/24 (\u4fee\u590d\u540e)<\/td>\n<td>104s<\/td>\n<td>11,234<\/td>\n<td>5,632<\/td>\n<td>6,033<\/td>\n<td>154&#043;200 \u884c<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>Kilo Code<\/td>\n<td>7.4.17<\/td>\n<td>\u2705 10\/10<\/td>\n<td>121s<\/td>\n<td>15,488<\/td>\n<td>102,272<\/td>\n<td>2,291<\/td>\n<td>101&#043;74 \u884c<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>* Codex \u672c\u5730\u4e0d\u8bb0\u5f55 usage&#xff08;OpenAI \u517c\u5bb9\u63a5\u53e3&#xff09;&#xff0c;\u7f51\u5173\u65e0\u5206 key \u660e\u7ec6&#xff1b;\u6309\u6210\u529f session \u7684 6 \u8f6e API \u8bf7\u6c42 \u00d7 \u7d2f\u79ef\u4e0a\u4e0b\u6587\u4f30\u7b97&#xff08;input 12K\u219232K \u9012\u589e&#xff09;&#xff0c;\u5355\u4efb\u52a1\u6210\u672c\u7ea6 $0.027 \u2020 Crush \u7684 crush.db sessions \u8868\u65e0 cache_read \u5b57\u6bb5&#xff0c;\u6545\u65e0\u6570\u636e \u2021 Crush \u8bb0\u5f55\u503c&#xff08;completion_tokens \u7591\u4f3c\u53ea\u8bb0\u672b\u6b21\u8bf7\u6c42&#xff0c;\u5b9e\u9645\u751f\u6210\u4ee3\u7801\u89c1\u4ea7\u7269&#xff09;<\/p>\n<h3>\u5206\u5de5\u5177\u8be6\u89e3<\/h3>\n<h4>&#x1f947; 1. OpenCode \u2014 \u7efc\u5408\u6700\u4f18<\/h4>\n<p>\u6700\u5feb&#xff08;32s&#xff09;&#043; \u6700\u7701 token&#xff08;11.7K input&#xff0c;\u5176\u4ed6\u5de5\u5177\u7684 1\/5-1\/7&#xff09;&#043; \u4ee3\u7801\u8d28\u91cf\u8fc7\u5173\u3002<\/p>\n<ul>\n<li>\u6d4b\u8bd5&#xff1a;12\/12 \u901a\u8fc7<\/li>\n<li>\u81ea\u52a8\u53d1\u73b0\u9879\u76ee .venv \u91cc\u7684 pytest 9.1.1 \u5e76\u76f4\u63a5\u4f7f\u7528<\/li>\n<li>\u5b89\u88c5\u96be\u70b9&#xff1a;GitHub \u4e0b\u8f7d\u6162\u9700\u955c\u50cf&#xff08;ghfast.top&#xff09;&#xff0c;\u4f46\u914d\u7f6e\u6781\u7b80<\/li>\n<li>Token \u6570\u636e&#xff1a;\u672c\u5730 SQLite&#xff08;~\/.local\/share\/opencode\/opencode.db session \u8868&#xff09;\u53ef\u7cbe\u786e\u67e5\u8be2<\/li>\n<\/ul>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u9879\u76ee\u7ea7 opencode.json<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;provider&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;myagentlab&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;npm&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;&#064;ai-sdk\/openai-compatible&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;options&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;baseURL&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;https:\/\/api.myagentlab.homes\/v1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;apiKey&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u89c1 credentials&#034;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;models&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;deepseek-v4-flash&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;deepseek-v4-flash&#034;<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;model&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;myagentlab\/deepseek-v4-flash&#034;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>opencode run <span class=\"token string\">&#034;\u4efb\u52a1\u63cf\u8ff0&#034;<\/span><\/p>\n<h4>&#x1f948; 2. Claude Code \u2014 \u8d28\u91cf\u5929\u82b1\u677f<\/h4>\n<p>\u4ee3\u7801\u8d28\u91cf\u6700\u9ad8&#xff08;22 \u4e2a\u6d4b\u8bd5\u6700\u591a\u6700\u5168&#xff09;&#xff0c;\u4f46 token \u6d88\u8017\u6700\u5927\u3002<\/p>\n<ul>\n<li>\u6d4b\u8bd5&#xff1a;22\/22 \u901a\u8fc7<\/li>\n<li>\u4eae\u70b9&#xff1a;\u81ea\u5df1\u53d1\u73b0\u5e76\u4fee\u590d\u4e86 mktemp \u7a7a\u6587\u4ef6\u5bfc\u81f4 json.load \u5d29\u6e83\u7684 bug&#xff08;\u52a0\u4e86\u7a7a\u6587\u4ef6\u5bb9\u9519 &#043; 2 \u4e2a\u5bf9\u5e94\u6d4b\u8bd5&#xff09;&#xff1b;\u7528 next_id \u8ba1\u6570\u5668\u4fdd\u8bc1\u5220\u9664\u540e id \u4e0d\u590d\u7528<\/li>\n<li>\u7cfb\u7edf\u63d0\u793a\u8bcd\u6700\u5b8c\u5584&#xff0c;\u5de5\u5177\u5b9a\u4e49\u6700\u5168\u2014\u2014\u8fd9\u4e5f\u662f\u5b83 token \u5927\u7684\u539f\u56e0<\/li>\n<li>\u751f\u6001\u6700\u5927&#xff08;134K stars&#xff09;\u3001\u6587\u6863\u5168\u3001\u6700\u6210\u719f<\/li>\n<\/ul>\n<p>Token \u5206\u6790&#xff1a; input 227K \u4e2d 190K \u662f cache read&#xff08;\u4ef7\u683c\u662f\u6b63\u5e38 input \u7684 1\/10&#xff09;&#xff0c;\u5b9e\u9645\u65b0\u8ba1\u7b97 ~36K&#xff0c;\u5e76\u975e\u5168\u4ef7\u6d88\u8017\u3002<\/p>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p><span class=\"token builtin class-name\">export<\/span> <span class=\"token assign-left variable\">ANTHROPIC_API_KEY<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token operator\">&lt;<\/span>key<span class=\"token operator\">&gt;<\/span> <span class=\"token assign-left variable\">ANTHROPIC_BASE_URL<\/span><span class=\"token operator\">&#061;<\/span>https:\/\/api.myagentlab.homes<br \/>\nclaude <span class=\"token parameter variable\">-p<\/span> <span class=\"token string\">&#034;\u4efb\u52a1&#034;<\/span> <span class=\"token parameter variable\">&#8211;model<\/span> deepseek-v4-flash <span class=\"token parameter variable\">&#8211;allowedTools<\/span> <span class=\"token string\">&#039;Bash,Write,Read,Edit&#039;<\/span> &#8211;output-format stream-json <span class=\"token parameter variable\">&#8211;verbose<\/span><\/p>\n<p>\u26a0\ufe0f root \u7528\u6237\u4e0d\u80fd\u7528 &#8211;dangerously-skip-permissions&#xff08;\u88ab\u62d2&#xff09;&#xff0c;\u5fc5\u987b\u7528 &#8211;allowedTools<\/p>\n<h4>&#x1f949; 3. Codex \u2014 \u6a21\u578b\u5bf9\u4e86\u5c31\u8d77\u98de<\/h4>\n<p>\u6362 deepseek \u540e\u4ece&#034;\u5931\u8d25\u00d74&#034;\u53d8&#034;13\/13 \u901a\u8fc7\u300178s&#034;&#xff0c;\u4f46 token \u6570\u636e\u7f3a\u5931 &#043; \u6709\u63a8\u7406\u6a21\u578b\u517c\u5bb9\u9690\u60a3\u3002<\/p>\n<ul>\n<li>\u6d4b\u8bd5&#xff1a;13\/13 \u901a\u8fc7&#xff0c;\u8fd8\u505a\u4e86\u5b8c\u6574 smoke test&#xff08;add\u2192done\u2192list\u2192delete \u7aef\u5230\u7aef&#xff09;<\/li>\n<li>\u91cd\u8981\u5386\u53f2&#xff1a;glm_for_coding \u4e0b\u5931\u8d25 4 \u6b21&#xff08;heredoc \u88ab chr(39) \u8f6c\u4e49\u641e\u574f\u3001\u4ee3\u7801\u6d4b\u8bd5\u4e0d\u4e00\u81f4\u3001\u8fde\u63a5\u5361\u6b7b&#xff09;\u2014\u2014\u662f\u6a21\u578b\u95ee\u9898\u4e0d\u662f Codex \u95ee\u9898<\/li>\n<li>\u9690\u60a3&#xff1a;deepseek \u662f\u63a8\u7406\u6a21\u578b&#xff0c;Codex \u591a\u8f6e\u5bf9\u8bdd\u65f6\u89e6\u53d1 reasoning_content \u5fc5\u987b\u56de\u4f20 400 \u62a5\u9519\u2014\u2014\u590d\u6742\u591a\u8f6e\u4efb\u52a1\u4f1a\u968f\u673a\u6302&#xff0c;\u53ea\u9002\u5408\u5355\u8f6e\/\u7b80\u5355\u4efb\u52a1<\/li>\n<li>Terminal-Bench 2.1 \u6392\u540d\u7b2c\u4e00&#xff08;83.4%&#xff09;\u7684\u5de5\u5177&#xff0c;\u80fd\u529b\u672c\u8eab\u6700\u5f3a<\/li>\n<li>Token \u8bf4\u660e&#xff1a;\u672c\u5730 session \u4e0d\u8bb0\u5f55 usage&#xff1b;\u66fe\u5c1d\u8bd5&#034;\u8d26\u5355\u524d\u540e\u5dee\u503c\u6cd5&#034;\u4f46\u7f51\u5173\u4e3a\u5171\u4eab key&#xff08;\u540e\u53f0\u6709 MRS refactor \u7b49\u4efb\u52a1\u5e76\u53d1\u6d88\u8017&#xff09;&#xff0c;\u5dee\u503c $2.09 \u4e0d\u53ef\u4fe1&#xff1b;\u6700\u7ec8\u6309 6 \u8f6e\u8bf7\u6c42 \u00d7 \u7d2f\u79ef\u4e0a\u4e0b\u6587\u4f30\u7b97 input ~132K \/ output ~12K \/ \u6210\u672c ~$0.027<\/li>\n<\/ul>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p># ~\/.codex\/config.toml<br \/>\nmodel &#061; &#034;deepseek-v4-flash&#034;<br \/>\nmodel_provider &#061; &#034;myagentlab&#034;<br \/>\n[model_providers.myagentlab]<br \/>\nname &#061; &#034;myagentlab&#034;<br \/>\nbase_url &#061; &#034;https:\/\/api.myagentlab.homes\/v1&#034;<br \/>\nenv_key &#061; &#034;OPENAI_API_KEY&#034;<br \/>\nwire_api &#061; &#034;chat&#034;<\/p>\n<p>codex <span class=\"token builtin class-name\">exec<\/span> &#8211;dangerously-bypass-approvals-and-sandbox &#8211;skip-git-repo-check <span class=\"token parameter variable\">&#8211;json<\/span> <span class=\"token string\">&#039;\u4efb\u52a1&#039;<\/span><\/p>\n<h4>4. Goose \u2014 \u5927\u5668\u665a\u6210<\/h4>\n<p>\u914d\u7f6e\u5751\u6700\u591a\u4f46\u4fee\u597d\u540e\u5f88\u7a33&#xff0c;17\/17 \u901a\u8fc7&#xff0c;77s\u3002<\/p>\n<ul>\n<li>\u6d4b\u8bd5&#xff1a;17\/17 \u901a\u8fc7&#xff0c;\u4ee3\u7801\u8d28\u91cf\u597d&#xff08;126 \u884c todo.py \u7ed3\u6784\u6e05\u6670&#xff0c;\u542b\u635f\u574f\u6587\u4ef6\u5bb9\u9519\u3001\u65f6\u95f4\u6233\u3001\u81ea\u52a8\u9012\u589e ID&#xff09;<\/li>\n<li>\u81ea\u5e26\u4efb\u52a1\u7ba1\u7406&#xff08;todo_write \u5de5\u5177&#xff09;&#xff0c;agent \u4f1a\u81ea\u5df1\u8bb0\u8d26<\/li>\n<li>Linux Foundation \u9879\u76ee&#xff0c;48K stars&#xff0c;\u6f5c\u529b\u5927<\/li>\n<\/ul>\n<p>\u26a0\ufe0f \u914d\u7f6e\u5751&#xff08;\u90fd\u662f\u5b9e\u6d4b\u8e29\u51fa\u6765\u7684&#xff09;&#xff1a;<\/p>\n<li>\u5fc5\u987b\u7528 OPENAI_API_KEY \/ OPENAI_BASE_URL&#xff08;\u4e0d\u662f GOOSE_API_KEY\/GOOSE_BASE_URL&#xff01;\u4e4b\u524d\u4e00\u76f4\u8bbe\u9519\u8fde\u9ed8\u8ba4 api.openai.com \u5f53\u7136\u8d85\u65f6&#xff09;<\/li>\n<li>\u6d41\u5f0f\u6a21\u5f0f\u4f1a\u62a5 Stream decode error\u2014\u2014\u5fc5\u987b\u5728 declarative provider \u91cc\u8bbe &#034;supports_streaming&#034;: false<\/li>\n<li>\u81ea\u5b9a\u4e49 provider \u8981\u653e ~\/.config\/goose\/custom_providers\/&lt;name&gt;.json<\/li>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ ~\/.config\/goose\/custom_providers\/myagentlab.json<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;myagentlab&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;engine&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;openai&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;api_key_env&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;MYAGENTLAB_API_KEY&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;base_url&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;https:\/\/api.myagentlab.homes\/v1&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;models&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;deepseek-v4-flash&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;context_limit&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">128000<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;supports_streaming&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;requires_auth&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token assign-left variable\">MYAGENTLAB_API_KEY<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token operator\">&lt;<\/span>key<span class=\"token operator\">&gt;<\/span> goose run <span class=\"token parameter variable\">-t<\/span> <span class=\"token string\">&#039;\u4efb\u52a1&#039;<\/span> <span class=\"token parameter variable\">&#8211;provider<\/span> myagentlab <span class=\"token parameter variable\">&#8211;model<\/span> deepseek-v4-flash<\/p>\n<h4>5. Crush \u2014 \u7115\u7136\u4e00\u65b0<\/h4>\n<p>\u4ece glm \u4e0b 13\/14&#xff08;\u6709 bug&#xff09;\u53d8\u6210 deepseek \u4e0b 13\/13 \u5168\u8fc7\u300166s&#xff0c;\u4f46\u914d\u7f6e\u6781\u5751 &#043; token \u8bb0\u5f55\u4e0d\u5168\u3002<\/p>\n<ul>\n<li>\u6d4b\u8bd5&#xff1a;13\/13 \u901a\u8fc7&#xff08;glm_for_coding \u4e0b\u6709\u4e2a DEFAULT_FILE \u7ed1\u5b9a bug&#xff0c;\u6362 deepseek \u540e\u81ea\u52a8\u6d88\u5931&#xff09;<\/li>\n<li>\u901f\u5ea6\u5feb&#xff08;66s&#xff09;&#xff0c;token \u7701&#xff08;14.5K input&#xff09;<\/li>\n<li>Charm \u51fa\u54c1&#xff0c;UI \u597d\u770b&#xff0c;\u4f46\u5b9e\u7528\u6027\u4e00\u822c<\/li>\n<\/ul>\n<p>\u26a0\ufe0f \u914d\u7f6e\u5751&#xff1a;<\/p>\n<li>\u6b63\u786e\u914d\u7f6e\u6587\u4ef6\u662f ~\/.config\/crush\/crush.json&#xff08;\u4e0d\u662f config.json&#xff01;\u6539\u4e86 config.json \u5b8c\u5168\u4e0d\u751f\u6548&#xff09;<\/li>\n<li>\u81ea\u5b9a\u4e49 provider \u7684 models \u5fc5\u987b\u662f\u6570\u7ec4&#xff08;\u4e0d\u662f\u5bf9\u8c61&#xff0c;\u5426\u5219\u62a5 model not found&#xff09;<\/li>\n<li>crush update-providers \u4f1a\u8986\u76d6 providers.json \u624b\u52a8\u4fee\u6539&#xff08;\u8fdc\u7a0b\u62c9\u53d6 40 \u4e2a provider&#xff09;<\/li>\n<li>\u8fd0\u884c flag \u662f -m provider\/model&#xff08;\u5982 -m myagentlab\/deepseek-v4-flash&#xff09;<\/li>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ ~\/.config\/crush\/crush.json<\/span><br \/>\n<span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token string-property property\">&#034;providers&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;myagentlab&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token string-property property\">&#034;type&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;openai-compat&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;base_url&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;https:\/\/api.myagentlab.homes\/v1&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;api_key&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;$MYAGENTLAB_API_KEY&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token string-property property\">&#034;models&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;id&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;deepseek-v4-flash&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;DeepSeek V4 Flash&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;context_window&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">128000<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;default_max_tokens&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">8192<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token string-property property\">&#034;defaultModel&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;myagentlab\/deepseek-v4-flash&#034;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token assign-left variable\">MYAGENTLAB_API_KEY<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token operator\">&lt;<\/span>key<span class=\"token operator\">&gt;<\/span> crush run <span class=\"token parameter variable\">-m<\/span> myagentlab\/deepseek-v4-flash <span class=\"token string\">&#034;\u4efb\u52a1&#034;<\/span><\/p>\n<h4>6. Cline \u2014 \u4fee\u597d\u4ee3\u7801\u540e\u5168\u8fc7&#xff0c;\u4f46 CLI \u6709\u771f bug<\/h4>\n<p>\u539f\u59cb 22\/24&#xff08;2 \u4e2a\u4ee3\u7801 bug&#xff09;&#xff0c;\u624b\u52a8\u4fee\u590d\u540e 24\/24&#xff1b;\u4f46 CLI \u4e8c\u8fdb\u5236\u6709 team_status \u5d29\u6e83 bug\u3002<\/p>\n<ul>\n<li>\u539f\u59cb\u6d4b\u8bd5&#xff1a;22\/24\u3002\u4e24\u4e2a bug&#xff1a;\n<li>_next_id() \u7528\u73b0\u5b58\u4efb\u52a1 max&#043;1&#xff0c;\u5220\u9664\u540e id \u590d\u7528&#xff08;\u6d4b\u8bd5\u8981\u6c42\u6c38\u4e0d\u590d\u7528&#xff09;<\/li>\n<li>except KeyError: print(f&#034;Error: {exc}&#034;) \u4e2d KeyError \u7684 str \u81ea\u5e26\u5f15\u53f7<\/li>\n<\/li>\n<li>\u4fee\u590d\u65b9\u6cd5&#xff08;\u5df2\u9a8c\u8bc1 24\/24&#xff09;&#xff1a;\u2460 \u52a0 self._max_id \u5b9e\u4f8b\u5c5e\u6027\u6301\u7eed\u9012\u589e \u2461 exc.args[0] \u53d6\u5e72\u51c0\u6d88\u606f<\/li>\n<li>\u26a0\ufe0f CLI \u771f bug&#xff1a;team_status \u5de5\u5177\u4e0e deepseek tool schema \u6821\u9a8c\u968f\u673a\u5d29\u6e83&#xff08;\u7ea6 1\/3 \u6982\u7387\u62a5 Invalid schema for function &#039;team_status&#039;: null is not of type &#034;array&#034;&#xff09;&#xff0c;\u662f Cline v3.0.49 \u4e8c\u8fdb\u5236\u7f3a\u9677\n<ul>\n<li>\u7f13\u89e3&#xff1a;~\/.cline\/data\/settings\/settings.json \u8bbe &#034;enableTeams&#034;: false&#xff08;\u4e0d\u5b8c\u5168\u7a33\u5b9a&#xff09;<\/li>\n<li>glm_for_coding \u4e0b\u65e0\u6b64\u95ee\u9898&#xff08;21\/21 \u5168\u8fc7&#xff09;<\/li>\n<\/ul>\n<\/li>\n<li>CLI \u5b89\u88c5\u914d\u7f6e\u6700\u7b80\u5355&#xff1a;cline auth openai -b &lt;url&gt; -k &lt;key&gt; -m &lt;model&gt; \u4e00\u884c\u641e\u5b9a<\/li>\n<li>\u771f\u5b9e\u573a\u666f\u662f VS Code \u6269\u5c55&#xff0c;CLI \u662f\u8f7b\u91cf\u7248<\/li>\n<\/ul>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p>cline auth openai <span class=\"token parameter variable\">-b<\/span> https:\/\/api.myagentlab.homes\/v1 <span class=\"token parameter variable\">-k<\/span> <span class=\"token operator\">&lt;<\/span>key<span class=\"token operator\">&gt;<\/span> <span class=\"token parameter variable\">-m<\/span> deepseek-v4-flash<br \/>\ncline <span class=\"token parameter variable\">&#8211;json<\/span> <span class=\"token string\">&#034;\u4efb\u52a1&#034;<\/span><\/p>\n<h4>7. Kilo Code \u2014 OpenCode \u6362\u76ae\u4f46\u66f4\u8d39<\/h4>\n<p>\u4e0e OpenCode \u540c\u6e90&#xff08;fork&#xff09;&#xff0c;\u529f\u80fd\u51e0\u4e4e\u4e00\u6837&#xff0c;\u4f46 token \u6d88\u8017\u9ad8&#xff08;cache read 102K&#xff09;\u4e14\u66f4\u6162\u3002<\/p>\n<ul>\n<li>\u6d4b\u8bd5&#xff1a;10\/10 \u901a\u8fc7&#xff0c;\u8fd8\u81ea\u5df1\u4fee\u4e86\u4e2a bug&#xff08;self.done \u5c5e\u6027\u906e\u853d done() \u65b9\u6cd5&#xff0c;\u6539\u540d self.is_done&#xff09;<\/li>\n<li>\u914d\u7f6e\u548c OpenCode \u51e0\u4e4e\u76f8\u540c&#xff08;kilo.jsonc&#xff09;<\/li>\n<li>Token \u5206\u6790&#xff1a;cache read 102K \u662f 7 \u4e2a\u5de5\u5177\u6700\u9ad8\u2014\u2014\u5b83\u6bcf\u6b21\u8bf7\u6c42\u91cd\u53d1\u5927\u91cf\u5de5\u5177\u5b9a\u4e49\/\u4e0a\u4e0b\u6587&#xff0c;\u4f46 cache \u4ef7\u683c\u4fbf\u5b9c&#xff08;1\/10&#xff09;<\/li>\n<li>\u7ed3\u8bba&#xff1a;\u6ca1\u7406\u7531\u9009\u5b83&#xff0c;\u76f4\u63a5\u7528 OpenCode \u66f4\u597d<\/li>\n<\/ul>\n<p>\u914d\u7f6e\u8981\u70b9&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ ~\/.config\/kilo\/kilo.jsonc<\/span><br \/>\n<span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;provider&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;myagentlab&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#034;npm&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;&#064;ai-sdk\/openai-compatible&#034;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;options&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;baseURL&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;https:\/\/api.myagentlab.homes\/v1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;apiKey&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;\u89c1 credentials&#034;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token string-property property\">&#034;models&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;deepseek-v4-flash&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token string-property property\">&#034;name&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;deepseek-v4-flash&#034;<\/span> <span class=\"token punctuation\">}<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;model&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#034;myagentlab\/deepseek-v4-flash&#034;<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>kilo run <span class=\"token parameter variable\">-m<\/span> myagentlab\/deepseek-v4-flash <span class=\"token string\">&#034;\u4efb\u52a1&#034;<\/span><\/p>\n<h3>\u6a21\u578b\u5bf9\u6bd4&#xff1a;glm_for_coding vs deepseek-v4-flash<\/h3>\n<table>\n<tr>\u9879glm_for_coding&#xff08;\u7f51\u5173&#xff09;deepseek-v4-flash&#xff08;\u7f51\u5173&#xff09;<\/tr>\n<tbody>\n<tr>\n<td>\u9996 token<\/td>\n<td>40-70s<\/td>\n<td>1.7s<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u5b8c\u6210\u8017\u65f6<\/td>\n<td>\u5168\u90e8 7-9 \u5206\u949f<\/td>\n<td>32s-134s<\/td>\n<\/tr>\n<tr>\n<td>Codex<\/td>\n<td>\u274c \u5931\u8d25\u00d74&#xff08;heredoc \u8f6c\u4e49\u9519\u4e71&#xff09;<\/td>\n<td>\u2705 13\/13<\/td>\n<\/tr>\n<tr>\n<td>Crush<\/td>\n<td>\u26a0\ufe0f 13\/14&#xff08;DEFAULT_FILE bug&#xff09;<\/td>\n<td>\u2705 13\/13<\/td>\n<\/tr>\n<tr>\n<td>Cline<\/td>\n<td>\u2705 21\/21<\/td>\n<td>\u2705 24\/24&#xff08;\u4fee\u590d\u540e&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>shell \u751f\u6210\u8d28\u91cf<\/td>\n<td>\u5dee&#xff08;chr(39) \u8f6c\u4e49\u3001heredoc \u4e71&#xff09;<\/td>\n<td>\u5e72\u51c0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u7ed3\u8bba&#xff1a;deepseek-v4-flash \u662f\u5f53\u524d\u7f51\u5173\u4e0b\u6700\u4f73\u901a\u7528\u7f16\u7801\u6a21\u578b&#xff08;\u5feb &#043; \u5e72\u51c0 &#043; \u4fbf\u5b9c&#xff09;\u3002<\/p>\n<h3>\u6700\u7ec8\u63a8\u8350<\/h3>\n<ul>\n<li>\u65e5\u5e38\u5f00\u53d1\u9996\u9009&#xff1a;OpenCode &#043; deepseek-v4-flash&#xff08;\u6700\u5feb\u6700\u7701&#xff0c;\u8d28\u91cf\u8fc7\u5173&#xff09;<\/li>\n<li>\u8981\u6700\u9ad8\u8d28\u91cf&#xff1a;Claude Code &#043; deepseek-v4-flash&#xff08;\u6700\u7a33\u6700\u4e25\u8c28&#xff0c;\u4f46 token \u5927&#xff09;<\/li>\n<li>\u5355\u8f6e\/\u7b80\u5355\u4efb\u52a1&#xff1a;Codex&#xff08;\u80fd\u529b\u5f3a&#xff0c;\u4f46\u63a8\u7406\u6a21\u578b\u591a\u8f6e\u6709\u517c\u5bb9\u9690\u60a3&#xff09;<\/li>\n<li>\u907f\u514d&#xff1a;Kilo&#xff08;OpenCode \u7684\u52a3\u5316\u7248&#xff09;\u3001Cline CLI&#xff08;team_status \u5d29\u6e83 bug \u672a\u4fee&#xff0c;\u7b49\u65b0\u7248\u672c&#xff09;<\/li>\n<\/ul>\n<h3>\u5b89\u88c5\u8bb0\u5f55&#xff08;\u8e29\u5751\u6c47\u603b&#xff09;<\/h3>\n<table>\n<tr>\u5de5\u5177\u5b89\u88c5\u9014\u5f84\u5751<\/tr>\n<tbody>\n<tr>\n<td>OpenCode<\/td>\n<td>ghfast.top \u955c\u50cf\u4e0b\u8f7d v1.18.12 glibc \u4e8c\u8fdb\u5236<\/td>\n<td>GitHub \u76f4\u8fde\u8d85\u65f6&#xff1b;npm \u5e73\u53f0\u5305\u662f\u7a7a\u58f3<\/td>\n<\/tr>\n<tr>\n<td>Codex<\/td>\n<td>npm &#064;openai\/codex<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>Goose<\/td>\n<td>ghfast.top \u955c\u50cf\u4e0b\u8f7d v1.45.0<\/td>\n<td>\u914d\u7f6e\u53d8\u91cf\u540d\u5751&#xff08;\u89c1\u4e0a&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>Crush<\/td>\n<td>go install charmbracelet\/crush<\/td>\n<td>\u914d\u7f6e\u6587\u4ef6\u5751&#xff08;\u89c1\u4e0a&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>Cline<\/td>\n<td>npm cline v3.0.49<\/td>\n<td>team_status \u5d29\u6e83 bug<\/td>\n<\/tr>\n<tr>\n<td>Kilo<\/td>\n<td>npm &#064;kilocode\/cli v7.4.17<\/td>\n<td>\u65e0<\/td>\n<\/tr>\n<tr>\n<td>Claude Code<\/td>\n<td>\u9884\u88c5 v2.1.220<\/td>\n<td>root \u4e0d\u80fd\u7528 &#8211;dangerously-skip-permissions<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u7f51\u7edc\u73af\u5883\u5907\u6ce8&#xff1a;GitHub \u76f4\u8fde\u6162\/\u8d85\u65f6 \u2192 \u7528 https:\/\/ghfast.top\/https:\/\/github.com\/&#8230; \u955c\u50cf&#xff1b;npm \u7528 &#8211;registry&#061;https:\/\/registry.npmmirror.com&#xff1b;Go \u7528 GOPROXY&#061;https:\/\/goproxy.cn,direct\u3002<\/p>\n<h3>\u6d4b\u8bd5\u4ea7\u7269\u5b58\u653e<\/h3>\n<p>\u6240\u6709\u6d4b\u8bd5\u4ee3\u7801\u3001\u65e5\u5fd7\u3001token \u6570\u636e\u4fdd\u7559\u5728 \/home\/agent\/coding-benchmark\/&#xff1a;<\/p>\n<ul>\n<li>test-&lt;\u5de5\u5177\u540d&gt;\/todo.py &#043; test_todo.py \u2014 \u5404\u5de5\u5177\u4ea7\u7269&#xff08;\u53ef\u590d\u9a8c pytest&#xff09;<\/li>\n<li>REPORT-deepseek.md \u2014 \u7cbe\u7b80\u7248\u62a5\u544a<\/li>\n<li>\/tmp\/&lt;\u5de5\u5177&gt;-ds.log \u2014 \u8fd0\u884c\u65e5\u5fd7<\/li>\n<li>\u5404\u5de5\u5177 token \u6570\u636e\u6765\u6e90&#xff1a;OpenCode\/Kilo \u672c\u5730 SQLite\u3001Goose sessions.db usage_ledger\u3001Cline session JSON metrics\u3001Crush .crush\/crush.db\u3001Claude Code stream-json usage<\/li>\n<\/ul>\n<p>\u6587\u6863\u7ef4\u62a4&#xff1a;CEO Agent&#xff0c;2026-08-04<\/p>\n<hr \/>\n<h3>\u90e8\u7f72\u4e0e\u914d\u7f6e\u5751&#xff08;\u8be6\u7248&#xff09;<\/h3>\n<p>\u4ee5\u4e0b\u5747\u4e3a\u672c\u6b21\u5b9e\u6d4b\u771f\u5b9e\u8e29\u5751\u8bb0\u5f55&#xff08;\u542b\u62a5\u9519\u539f\u6587&#xff09;\u3002\u914d\u7f6e\u4ee3\u7801\u89c1\u4e0a\u6587\u5404\u5de5\u5177\u8be6\u89e3&#xff1b;\u5b8c\u6574\u751f\u6210\u4ee3\u7801\u89c1\u6587\u672b \u6d4b\u8bd5\u4ea7\u7269\u5168\u96c6\u3002 \u4fa7\u91cd\u70b9&#xff1a;\u8fd9\u91cc\u662f&#034;\u51fa\u4e86\u4ec0\u4e48\u9519\u3001\u600e\u4e48\u89e3\u51b3&#034;&#xff0c;\u4e0a\u6587\u8be6\u89e3\u662f&#034;\u600e\u4e48\u914d&#034;\u3002<\/p>\n<h4>Claude Code<\/h4>\n<ul>\n<li>root \u7528\u6237\u9650\u5236&#xff1a;&#8211;dangerously-skip-permissions \u76f4\u63a5\u62d2\u7edd&#xff08;\u201ccannot be used with root\/sudo privileges\u201d&#xff09;&#xff0c;\u5fc5\u987b\u7528 &#8211;allowedTools &#039;Bash,Write,Read,Edit&#039;<\/li>\n<li>\u73af\u5883\u53d8\u91cf\u4f18\u5148\u7ea7&#xff1a;.bashrc \u91cc\u7684 ANTHROPIC_API_KEY\/ANTHROPIC_BASE_URL export \u8986\u76d6 ~\/.claude\/settings.json\u2014\u2014\u8981\u6362\u6d4b\u8bd5\u7aef\u70b9\u5fc5\u987b\u4e34\u65f6 export&#xff0c;\u4e0d\u80fd\u53ea\u6539 settings.json<\/li>\n<li>\u751f\u4ea7\u914d\u7f6e\u9694\u79bb&#xff1a;\u6d4b\u8bd5\u65f6\u7528 export \u8986\u76d6&#xff0c;\u4e0d\u52a8 ~\/.claude\/settings.json \u548c .bashrc<\/li>\n<\/ul>\n<h4>OpenCode<\/h4>\n<ul>\n<li>GitHub \u76f4\u8fde\u4e0b\u8f7d\u8d85\u65f6 \u2192 \u7528 https:\/\/ghfast.top\/https:\/\/github.com\/&#8230; \u955c\u50cf\u4e0b\u8f7d opencode-linux-x64.tar.gz&#xff08;v1.18.12 glibc&#xff09;<\/li>\n<li>npm opencode \u5305 404&#xff1b;&#064;opencode-ai\/cli \u5e73\u53f0\u5305\u662f\u7a7a\u58f3\u2014\u2014\u5fc5\u987b\u4e0b\u4e8c\u8fdb\u5236<\/li>\n<li>\u66fe\u9047 EEXIST bug&#xff1a;\/tmp\/opencode \u88ab musl \u4e8c\u8fdb\u5236\u7559\u6210\u6587\u4ef6&#xff0c;glibc \u7248 mkdir \u5931\u8d25 \u2192 rm \/tmp\/opencode \u89e3\u51b3<\/li>\n<li>opencode version \u4e0d\u662f\u5b50\u547d\u4ee4&#xff0c;TUI \u662f\u9ed8\u8ba4\u547d\u4ee4<\/li>\n<\/ul>\n<h4>Codex<\/h4>\n<ul>\n<li>\u914d\u7f6e ~\/.codex\/config.toml&#xff1a;wire_api &#061; &#034;chat&#034;&#xff08;OpenAI \u517c\u5bb9&#xff09;&#xff0c;env_key &#061; &#034;OPENAI_API_KEY&#034;<\/li>\n<li>\u8fd0\u884c&#xff1a;codex exec &#8211;dangerously-bypass-approvals-and-sandbox &#8211;skip-git-repo-check &#8211;json<\/li>\n<li>\u63a8\u7406\u6a21\u578b\u9690\u60a3&#xff1a;deepseek \u662f\u63a8\u7406\u6a21\u578b&#xff0c;Codex \u591a\u8f6e\u5bf9\u8bdd\u89e6\u53d1 reasoning_content \u5fc5\u987b\u56de\u4f20 400\u2014\u2014\u590d\u6742\u4efb\u52a1\u4f1a\u6302&#xff0c;\u5355\u8f6e\u4efb\u52a1 OK<\/li>\n<li>token \u4e0d\u843d\u672c\u5730&#xff1a;session jsonl \u65e0 usage \u5b57\u6bb5<\/li>\n<\/ul>\n<h4>Goose&#xff08;\u5751\u6700\u591a&#xff09;<\/h4>\n<ul>\n<li>\u53d8\u91cf\u540d\u5751&#xff1a;\u5fc5\u987b\u7528 OPENAI_API_KEY\/OPENAI_BASE_URL&#xff08;\u4e0d\u662f GOOSE_API_KEY\/GOOSE_BASE_URL&#xff01;&#xff09;\u2014\u2014\u7528\u9519\u8fde\u9ed8\u8ba4 api.openai.com \u5fc5\u7136\u8d85\u65f6<\/li>\n<li>\u6d41\u5f0f\u5751&#xff1a;\u9ed8\u8ba4\u6d41\u5f0f\u62a5 Stream decode error \u2192 declarative provider \u5fc5\u987b\u8bbe &#034;supports_streaming&#034;: false<\/li>\n<li>\u81ea\u5b9a\u4e49 provider \u8def\u5f84&#xff1a;~\/.config\/goose\/custom_providers\/&lt;name&gt;.json<\/li>\n<li>\u8bca\u65ad\u65b9\u6cd5&#xff1a;\u672c\u5730 SQLite ~\/.local\/share\/goose\/sessions\/sessions.db \u7684 messages \u8868\u770b\u8bf7\u6c42\u662f\u5426\u771f\u7684\u53d1\u51fa\u53bb&#xff08;\u4e4b\u524d\u53ea\u5b58 user \u6d88\u606f &#061; \u8bf7\u6c42\u6ca1\u5230\u6a21\u578b&#xff09;<\/li>\n<\/ul>\n<h4>Crush<\/h4>\n<ul>\n<li>\u914d\u7f6e\u6587\u4ef6\u5751&#xff1a;\u6b63\u786e\u6587\u4ef6\u540d\u662f ~\/.config\/crush\/crush.json&#xff08;\u4e0d\u662f config.json&#xff01;\u6539 config.json \u5b8c\u5168\u4e0d\u751f\u6548&#xff0c;\u6392\u67e5\u534a\u5929&#xff09;<\/li>\n<li>models \u5fc5\u987b\u662f\u6570\u7ec4\u4e0d\u662f\u5bf9\u8c61&#xff08;\u5bf9\u8c61\u7ed3\u6784\u62a5 \u201clarge model not found\u201d&#xff09;<\/li>\n<li>crush update-providers \u4f1a\u8986\u76d6 providers.json \u624b\u52a8\u4fee\u6539&#xff08;\u8fdc\u7a0b\u62c9 40 \u4e2a provider&#xff09;<\/li>\n<li>-m provider\/model \u683c\u5f0f&#xff08;\u5982 -m myagentlab\/deepseek-v4-flash&#xff09;<\/li>\n<li>token \u8bb0\u5f55\u4e0d\u5168&#xff1a;crush.db sessions \u8868\u53ea\u6709 prompt\/completion\/cost&#xff0c;\u65e0 cache_read<\/li>\n<\/ul>\n<h4>Cline<\/h4>\n<ul>\n<li>\u914d\u7f6e\u6700\u7b80\u5355&#xff1a;cline auth openai -b &lt;url&gt; -k &lt;key&gt; -m &lt;model&gt; \u4e00\u884c<\/li>\n<li>\u26a0\ufe0f CLI \u4e8c\u8fdb\u5236 bug&#xff1a;team_status \u5de5\u5177\u4e0e deepseek tool schema \u6821\u9a8c\u968f\u673a\u5d29\u6e83&#xff08;~1\/3 \u6982\u7387 Invalid schema for function &#039;team_status&#039;: null is not of type &#034;array&#034;&#xff09;\n<ul>\n<li>\u7f13\u89e3&#xff1a;~\/.cline\/data\/settings\/settings.json \u8bbe &#034;enableTeams&#034;: false&#xff08;\u4e0d\u5b8c\u5168\u7a33\u5b9a&#xff09;<\/li>\n<li>glm_for_coding \u4e0b\u65e0\u6b64\u95ee\u9898<\/li>\n<\/ul>\n<\/li>\n<li>session \u6570\u636e\u5728 ~\/.cline\/data\/sessions\/&lt;id&gt;\/&#xff0c;token \u5728 messages.json \u7684 assistant \u6d88\u606f metrics \u5b57\u6bb5<\/li>\n<\/ul>\n<h4>Kilo Code<\/h4>\n<ul>\n<li>\u914d\u7f6e ~\/.config\/kilo\/kilo.jsonc&#xff08;opencode fork&#xff0c;\u683c\u5f0f\u51e0\u4e4e\u76f8\u540c&#xff09;<\/li>\n<li>kilo run -m myagentlab\/deepseek-v4-flash &#034;\u4efb\u52a1&#034;<\/li>\n<li>token \u5728 ~\/.local\/share\/kilo\/kilo.db session \u8868<\/li>\n<\/ul>\n<hr \/>\n<h3>Token \u6570\u636e\u8bc1\u636e\u94fe&#xff08;\u6bcf\u4e2a\u6570\u5b57\u4ece\u54ea\u6765&#xff09;<\/h3>\n<table>\n<tr>\u5de5\u5177InputCacheOutput\u6570\u636e\u6765\u6e90&#xff08;\u53ef\u590d\u6838&#xff09;<\/tr>\n<tbody>\n<tr>\n<td>Claude Code<\/td>\n<td>227,467<\/td>\n<td>190,976<\/td>\n<td>12,435<\/td>\n<td>\/tmp\/cc-ds.log \u6700\u540e\u4e00\u884c &#034;usage&#034;:{&#8230;}&#xff08;stream-json \u8f93\u51fa&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>OpenCode<\/td>\n<td>11,749<\/td>\n<td>40,576<\/td>\n<td>1,992<\/td>\n<td>~\/.local\/share\/opencode\/opencode.db session \u8868 tokens_input\/output\/cache_read<\/td>\n<\/tr>\n<tr>\n<td>Codex<\/td>\n<td>~132K (\u4f30)<\/td>\n<td>\u2014<\/td>\n<td>~12K (\u4f30)<\/td>\n<td>\u672c\u5730\u4e0d\u8bb0\u5f55&#xff1b;\u6309 6 \u8f6e\u8bf7\u6c42\u00d7\u7d2f\u79ef\u4e0a\u4e0b\u6587\u4f30\u7b97&#xff0c;\u6210\u672c ~$0.027<\/td>\n<\/tr>\n<tr>\n<td>Goose<\/td>\n<td>80,848<\/td>\n<td>43,776<\/td>\n<td>6,769<\/td>\n<td>~\/.local\/share\/goose\/sessions\/sessions.db usage_ledger \u8868 SUM()<\/td>\n<\/tr>\n<tr>\n<td>Crush<\/td>\n<td>14,499<\/td>\n<td>\u65e0\u6b64\u5b57\u6bb5<\/td>\n<td>40*<\/td>\n<td>~\/.crush\/crush.db sessions \u8868 prompt_tokens\/completion_tokens<\/td>\n<\/tr>\n<tr>\n<td>Cline<\/td>\n<td>11,234<\/td>\n<td>5,632<\/td>\n<td>6,033<\/td>\n<td>~\/.cline\/data\/sessions\/&lt;id&gt;\/&lt;id&gt;.messages.json assistant metrics \u7d2f\u52a0<\/td>\n<\/tr>\n<tr>\n<td>Kilo<\/td>\n<td>15,488<\/td>\n<td>102,272<\/td>\n<td>2,291<\/td>\n<td>~\/.local\/share\/kilo\/kilo.db session \u8868<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>* Crush completion_tokens&#061;40 \u7591\u4f3c\u53ea\u8bb0\u672b\u6b21\u8bf7\u6c42&#xff08;\u5b9e\u9645\u751f\u6210 124 \u884c\u4ee3\u7801&#xff09;&#xff0c;\u5df2\u6309\u5b9e\u9645\u4ea7\u7269\u4fee\u6b63\u7406\u89e3<\/p>\n<p>\u590d\u6838\u547d\u4ee4\u793a\u4f8b&#xff08;OpenCode&#xff09;&#xff1a;<\/p>\n<p><span class=\"token keyword\">SELECT<\/span> tokens_input<span class=\"token punctuation\">,<\/span> tokens_output<span class=\"token punctuation\">,<\/span> tokens_cache_read <span class=\"token keyword\">FROM<\/span> <span class=\"token keyword\">session<\/span><br \/>\n<span class=\"token keyword\">WHERE<\/span> model <span class=\"token operator\">LIKE<\/span> <span class=\"token string\">&#039;%deepseek%&#039;<\/span> <span class=\"token keyword\">ORDER<\/span> <span class=\"token keyword\">BY<\/span> time_created <span class=\"token keyword\">DESC<\/span> <span class=\"token keyword\">LIMIT<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u590d\u6838\u547d\u4ee4\u793a\u4f8b&#xff08;Goose&#xff09;&#xff1a;<\/p>\n<p><span class=\"token keyword\">SELECT<\/span> session_id<span class=\"token punctuation\">,<\/span> <span class=\"token function\">SUM<\/span><span class=\"token punctuation\">(<\/span>input_tokens<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">SUM<\/span><span class=\"token punctuation\">(<\/span>output_tokens<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">SUM<\/span><span class=\"token punctuation\">(<\/span>cache_read_tokens<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token keyword\">FROM<\/span> usage_ledger <span class=\"token keyword\">GROUP<\/span> <span class=\"token keyword\">BY<\/span> session_id <span class=\"token keyword\">ORDER<\/span> <span class=\"token keyword\">BY<\/span> <span class=\"token function\">MIN<\/span><span class=\"token punctuation\">(<\/span>id<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">DESC<\/span> <span class=\"token keyword\">LIMIT<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u590d\u6838\u547d\u4ee4\u793a\u4f8b&#xff08;Claude Code&#xff09;&#xff1a;<\/p>\n<p><span class=\"token function\">grep<\/span> <span class=\"token parameter variable\">-oE<\/span> <span class=\"token string\">&#039;&#034;usage&#034;:\\\\{[^}]*\\\\}&#039;<\/span> \/tmp\/cc-ds.log <span class=\"token operator\">|<\/span> <span class=\"token function\">tail<\/span> <span class=\"token parameter variable\">-1<\/span><\/p>\n<p>\u4e3a\u4ec0\u4e48 Codex \u6ca1\u6709\u7cbe\u786e\u503c&#xff1a; \u672c\u5730 session jsonl \u65e0 usage \u5b57\u6bb5&#xff1b;\u7f51\u5173 billing \u63a5\u53e3\u53ea\u7ed9\u603b\u989d&#xff08;\u5171\u4eab key&#xff0c;\u540e\u53f0 MRS \u4efb\u52a1\u5e76\u53d1\u6d88\u8017&#xff0c;\u5dee\u503c\u6cd5\u4e0d\u53ef\u4fe1&#xff09;&#xff1b;\u552f\u4e00\u7cbe\u786e\u9014\u5f84\u662f new-api \u540e\u53f0\u6309\u6e20\u9053\u67e5\u660e\u7ec6\u3002<\/p>\n<hr \/>\n<h2>\u9644&#xff1a;\u6d4b\u8bd5\u4ea7\u7269\u5168\u96c6&#xff08;7 \u4efd\u5b8c\u6574\u4ee3\u7801 &#043; pytest \u8f93\u51fa&#xff09;<\/h2>\n<p>\u4ee5\u4e0b\u4e3a 7 \u6b3e\u5de5\u5177\u5728\u7edf\u4e00\u6d4b\u8bd5\u9898\u4e0b\u5b9e\u9645\u751f\u6210\u7684\u5168\u90e8\u4ee3\u7801 &#043; pytest \u590d\u9a8c\u8f93\u51fa&#xff08;\u673a\u5668\u5b9e\u8dd1&#xff0c;\u975e\u624b\u5199&#xff09;\u3002 \u590d\u9a8c\u547d\u4ee4&#xff1a;\/tmp\/bench-venv\/bin\/python -m pytest test_todo.py -v&#xff08;\u4ea7\u7269\u76ee\u5f55 \/home\/agent\/coding-benchmark\/test-&lt;\u5de5\u5177\u540d&gt;\/&#xff09;<\/p>\n<p>\u672c\u9875\u5b58\u653e 7 \u6b3e\u5de5\u5177\u5728\u7edf\u4e00\u6d4b\u8bd5\u9898\u4e0b\u5b9e\u9645\u751f\u6210\u7684\u5168\u90e8\u4ee3\u7801 &#043; pytest \u590d\u9a8c\u8f93\u51fa\u3002<\/p>\n<p>\u590d\u9a8c\u547d\u4ee4&#xff1a;\/tmp\/bench-venv\/bin\/python -m pytest test_todo.py -v&#xff08;\u4ea7\u7269\u76ee\u5f55 \/home\/agent\/coding-benchmark\/test-&lt;\u5de5\u5177\u540d&gt;\/&#xff09;<\/p>\n<hr \/>\n<h3>Claude Code v2.1.220 \u2014 22\/22<\/h3>\n<h4>Claude Code \u751f\u6210\u7684 todo.py (4619 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A simple command-line todo app with JSON persistence.<\/p>\n<p>Usage:<br \/>\n    todo.py add &lt;task&gt;      Add a new task<br \/>\n    todo.py list            List all tasks<br \/>\n    todo.py done &lt;id&gt;       Mark a task as done<br \/>\n    todo.py delete &lt;id&gt;     Delete a task<br \/>\n    todo.py &#8211;file &lt;path&gt;   Use a custom JSON file (default: ~\/.todo.json)<\/p>\n<p>Tasks are stored in a JSON file of the form:<br \/>\n    {&#034;next_id&#034;: 2, &#034;todos&#034;: [{&#034;id&#034;: 1, &#034;task&#034;: &#034;&#8230;&#034;, &#034;done&#034;: false}]}<br \/>\nThe &#096;&#096;next_id&#096;&#096; counter is persisted so task IDs are never reused, even<br \/>\nafter a delete. This prevents a stale reference from completing or<br \/>\ndeleting the wrong task later.<br \/>\n&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> os<br \/>\n<span class=\"token keyword\">import<\/span> sys<\/p>\n<p>DEFAULT_FILE <span class=\"token operator\">&#061;<\/span> os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>join<span class=\"token punctuation\">(<\/span>os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>expanduser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;~&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;.todo.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TodoApp<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Todo list backed by a JSON file.&#034;&#034;&#034;<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> filepath<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>filepath <span class=\"token operator\">&#061;<\/span> filepath<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">load<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return the store (&#096;&#096;next_id&#096;&#096; counter &#043; &#096;&#096;todos&#096;&#096; list).&#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>filepath<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;r&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n            content <span class=\"token operator\">&#061;<\/span> f<span class=\"token punctuation\">.<\/span>read<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> content<span class=\"token punctuation\">.<\/span>strip<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token comment\"># Empty file (e.g. created by touch\/mktemp) means a fresh store.<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><br \/>\n        data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span>content<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token comment\"># Backwards compatibility: a bare list of todos.<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token builtin\">isinstance<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            data <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> data<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                <span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">:<\/span> data<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> data<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> data<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Write the store to the JSON file.&#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>filepath<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n            json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> f<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">_allocate_id<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> data<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        next_id <span class=\"token operator\">&#061;<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> next_id <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> next_id<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> task<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Add a new task and return the created todo.&#034;&#034;&#034;<\/span><br \/>\n        data <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> self<span class=\"token punctuation\">.<\/span>_allocate_id<span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">:<\/span> task<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n        data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>save<span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> todo<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">list_todos<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return all todos in insertion order.&#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> self<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">done<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> todo_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Mark a todo as done and return it, or None if not found.&#034;&#034;&#034;<\/span><br \/>\n        data <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n                todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>save<span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> todo<br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">delete<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> todo_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Delete a todo and return it, or None if not found.&#034;&#034;&#034;<\/span><br \/>\n        data <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> i<span class=\"token punctuation\">,<\/span> todo <span class=\"token keyword\">in<\/span> <span class=\"token builtin\">enumerate<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n                removed <span class=\"token operator\">&#061;<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>pop<span class=\"token punctuation\">(<\/span>i<span class=\"token punctuation\">)<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>save<span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> removed<br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span>description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;A simple todo app&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;JSON file to store todos&#034;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    subparsers <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    add_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Add a task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    add_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Task description&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;List all tasks&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    done_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Mark a task as done&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    done_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Task ID&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    delete_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Delete a task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    delete_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Task ID&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">file<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>task<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;task&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todos <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;No todos.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            status <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;[x]&#034;<\/span> <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034;[ ]&#034;<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">. <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>status<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;task&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> not found.&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Done: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;task&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> not found.&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;task&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>Claude Code \u751f\u6210\u7684 test_todo.py (5048 bytes)<\/h4>\n<p><span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Unit tests for the todo app.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> json<\/p>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">from<\/span> todo <span class=\"token keyword\">import<\/span> TodoApp<span class=\"token punctuation\">,<\/span> main<\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">app<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; add &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_returns_created_todo<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_persists_to_json<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">,<\/span> tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Write tests&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;Write tests&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_persists_next_id_counter<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">,<\/span> tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;second&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">3<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_increments_ids<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;second&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_after_delete_does_not_reuse_id<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>first<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    third <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;third&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> third<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_ids_are_monotonic_across_restarts<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    app1 <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>filepath<span class=\"token punctuation\">)<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> app1<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app2 <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>filepath<span class=\"token punctuation\">)<\/span><br \/>\n    app2<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>first<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    third <span class=\"token operator\">&#061;<\/span> app2<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;third&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> third<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; list &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_empty_when_no_file<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;nonexistent.json&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_empty_when_file_is_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    filepath<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>filepath<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_over_empty_file<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    filepath<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>filepath<span class=\"token punctuation\">)<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_empty_when_file_is_empty_store<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    filepath<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>dumps<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;next_id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>filepath<span class=\"token operator\">&#061;<\/span>filepath<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_returns_all_todos_in_order<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;a&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;b&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;a&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;b&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; done &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_marks_todo<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    result <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> result<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_persists_to_json<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">,<\/span> tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_missing_returns_none<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">999<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; delete &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_removes_todo<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    removed <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> removed<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;Task&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_persists_to_json<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">,<\/span> tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;todos&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_missing_returns_none<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">999<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; CLI &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_add_and_list<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Added todo #1: Buy milk&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p>    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    out <span class=\"token operator\">&#061;<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;1.&#034;<\/span> <span class=\"token keyword\">in<\/span> out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span> <span class=\"token keyword\">in<\/span> out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_list_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todos.&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_done_and_delete<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Done: Task&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p>    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Deleted: Task&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_done_missing_id_returns_nonzero<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;not found&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>err<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_delete_missing_id_returns_nonzero<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    filepath <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>filepath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;not found&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>err<\/p>\n<h4>Claude Code pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>_after_delete_does_not_reuse_id PASSED             [ 22%]<br \/>\ntest_todo.py::test_ids_are_monotonic_across_restarts PASSED              [ 27%]<br \/>\ntest_todo.py::test_list_empty_when_no_file PASSED                        [ 31%]<br \/>\ntest_todo.py::test_list_empty_when_file_is_empty PASSED                  [ 36%]<br \/>\ntest_todo.py::test_add_over_empty_file PASSED                            [ 40%]<br \/>\ntest_todo.py::test_list_empty_when_file_is_empty_store PASSED            [ 45%]<br \/>\ntest_todo.py::test_list_returns_all_todos_in_order PASSED                [ 50%]<br \/>\ntest_todo.py::test_done_marks_todo PASSED                                [ 54%]<br \/>\ntest_todo.py::test_done_persists_to_json PASSED                          [ 59%]<br \/>\ntest_todo.py::test_done_missing_returns_none PASSED                      [ 63%]<br \/>\ntest_todo.py::test_delete_removes_todo PASSED                            [ 68%]<br \/>\ntest_todo.py::test_delete_persists_to_json PASSED                        [ 72%]<br \/>\ntest_todo.py::test_delete_missing_returns_none PASSED                    [ 77%]<br \/>\ntest_todo.py::test_cli_add_and_list PASSED                               [ 81%]<br \/>\ntest_todo.py::test_cli_list_empty PASSED                                 [ 86%]<br \/>\ntest_todo.py::test_cli_done_and_delete PASSED                            [ 90%]<br \/>\ntest_todo.py::test_cli_done_missing_id_returns_nonzero PASSED            [ 95%]<br \/>\ntest_todo.py::test_cli_delete_missing_id_returns_nonzero PASSED          [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 22 passed in 0.16s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n<hr \/>\n<h3>OpenCode v1.18.12 \u2014 12\/12<\/h3>\n<h4>OpenCode \u751f\u6210\u7684 todo.py (3444 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A simple CLI todo app with JSON persistence.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> os<br \/>\n<span class=\"token keyword\">import<\/span> sys<\/p>\n<p>DEFAULT_STORE <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><\/p>\n<p><span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TodoApp<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> store_path<span class=\"token operator\">&#061;<\/span>DEFAULT_STORE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>store_path <span class=\"token operator\">&#061;<\/span> store_path<br \/>\n        self<span class=\"token punctuation\">.<\/span>todos <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>_load<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">_load<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;r&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> fh<span class=\"token punctuation\">:<\/span><br \/>\n                data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span>fh<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">except<\/span> <span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>JSONDecodeError<span class=\"token punctuation\">,<\/span> OSError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> <span class=\"token builtin\">isinstance<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> data<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">_save<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> fh<span class=\"token punctuation\">:<\/span><br \/>\n            json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">,<\/span> fh<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> title<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> self<span class=\"token punctuation\">.<\/span>_next_id<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> title<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>_save<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> todo<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">_next_id<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> self<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">list<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> show_done<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todos <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>todos<br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> show_done<span class=\"token punctuation\">:<\/span><br \/>\n            todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span>t <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> todos<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">done<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> todo_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> self<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n                todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>_save<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> todo<br \/>\n        <span class=\"token keyword\">raise<\/span> KeyError<span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;No todo with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">delete<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> todo_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> self<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">.<\/span>remove<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>_save<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> todo<br \/>\n        <span class=\"token keyword\">raise<\/span> KeyError<span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;No todo with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span>prog<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo&#034;<\/span><span class=\"token punctuation\">,<\/span> description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;A simple todo app.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token string\">&#034;&#8211;store&#034;<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span>DEFAULT_STORE<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;path to the JSON store file&#034;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    sub <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_add <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;add a todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_add<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;title of the todo&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_list <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;list todos&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_list<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token string\">&#034;&#8211;all&#034;<\/span><span class=\"token punctuation\">,<\/span> action<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;store_true&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;show completed todos too&#034;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_done <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;mark a todo as done&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_done<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo id&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_delete <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;delete a todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_delete<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo id&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><\/p>\n<p>    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>store<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>title<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            todos <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span>show_done<span class=\"token operator\">&#061;<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">all<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n                <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;No todos.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n                status <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;[x]&#034;<\/span> <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034;[ ]&#034;<\/span><br \/>\n                <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>status<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Marked todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> as done: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">except<\/span> KeyError <span class=\"token keyword\">as<\/span> exc<span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>exc<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>OpenCode \u751f\u6210\u7684 test_todo.py (2052 bytes)<\/h4>\n<p><span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> os<\/p>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">from<\/span> todo <span class=\"token keyword\">import<\/span> TodoApp<\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">app<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    store <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> TodoApp<span class=\"token punctuation\">(<\/span><span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>store<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_creates_todo<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_persists_to_disk<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Walk the dog&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> fh<span class=\"token punctuation\">:<\/span><br \/>\n        data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span>fh<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> data<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;Walk the dog&#034;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_empty<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_returns_all_todos<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;A&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;B&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_hides_done_when_requested<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;A&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;B&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    remaining <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span>show_done<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">False<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> remaining<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_marks_todo_completed<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;A&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span>todos<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_unknown_id_raises<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> pytest<span class=\"token punctuation\">.<\/span>raises<span class=\"token punctuation\">(<\/span>KeyError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        app<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">999<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_removes_todo<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;A&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;B&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_unknown_id_raises<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> pytest<span class=\"token punctuation\">.<\/span>raises<span class=\"token punctuation\">(<\/span>KeyError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">999<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_next_id_increments_after_delete<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;A&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;B&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> app<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;C&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">3<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_existing_store<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    store <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    store<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>dumps<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;existing&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span><span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>store<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;existing&#034;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_corrupt_store_returns_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    store <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    store<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;{not valid json&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    app <span class=\"token operator\">&#061;<\/span> TodoApp<span class=\"token punctuation\">(<\/span><span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>store<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> app<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<h4>OpenCode pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; test session starts &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\nplatform linux &#8212; Python 3.13.5, pytest-9.1.1, pluggy-1.6.0 &#8212; \/tmp\/bench-venv\/bin\/python<br \/>\ncachedir: .pytest_cache<br \/>\nrootdir: \/home\/agent\/coding-benchmark\/test-opencode<br \/>\ncollecting &#8230; collected 12 items<\/p>\n<p>test_todo.py::test_add_creates_todo PASSED                               [  8%]<br \/>\ntest_todo.py::test_add_persists_to_disk PASSED                           [ 16%]<br \/>\ntest_todo.py::test_list_empty PASSED                                     [ 25%]<br \/>\ntest_todo.py::test_list_returns_all_todos PASSED                         [ 33%]<br \/>\ntest_todo.py::test_list_hides_done_when_requested PASSED                 [ 41%]<br \/>\ntest_todo.py::test_done_marks_todo_completed PASSED                      [ 50%]<br \/>\ntest_todo.py::test_done_unknown_id_raises PASSED                         [ 58%]<br \/>\ntest_todo.py::test_delete_removes_todo PASSED                            [ 66%]<br \/>\ntest_todo.py::test_delete_unknown_id_raises PASSED                       [ 75%]<br \/>\ntest_todo.py::test_next_id_increments_after_delete PASSED                [ 83%]<br \/>\ntest_todo.py::test_load_existing_store PASSED                            [ 91%]<br \/>\ntest_todo.py::test_load_corrupt_store_returns_empty PASSED               [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 12 passed in 0.07s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n<hr \/>\n<h3>Codex v0.50.0 \u2014 13\/13<\/h3>\n<h4>Codex \u751f\u6210\u7684 todo.py (4025 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A simple command-line todo application with JSON persistence.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> sys<br \/>\n<span class=\"token keyword\">from<\/span> pathlib <span class=\"token keyword\">import<\/span> Path<\/p>\n<p>DEFAULT_FILE <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">(<\/span>__file__<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>parent <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">load_todos<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Load todos from a JSON file, returning an empty list if missing or corrupt.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> Path<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;r&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n            data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span>f<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">except<\/span> <span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>JSONDecodeError<span class=\"token punctuation\">,<\/span> OSError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> data <span class=\"token keyword\">if<\/span> <span class=\"token builtin\">isinstance<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">save_todos<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Save a list of todos to a JSON file.&#034;&#034;&#034;<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    path<span class=\"token punctuation\">.<\/span>parent<span class=\"token punctuation\">.<\/span>mkdir<span class=\"token punctuation\">(<\/span>parents<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">,<\/span> exist_ok<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n        json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> f<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">add_todo<\/span><span class=\"token punctuation\">(<\/span>description<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Add a new todo and return its id.&#034;&#034;&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    todo_id <span class=\"token operator\">&#061;<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><br \/>\n    todos<span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> todo_id<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> description<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> todo_id<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">list_todos<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return the list of todos.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">mark_done<\/span><span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Mark a todo as done; return True if it was found.&#034;&#034;&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n            todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n            save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">delete_todo<\/span><span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Delete a todo; return True if it was found.&#034;&#034;&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    remaining <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span>t <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos <span class=\"token keyword\">if<\/span> t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">!&#061;<\/span> todo_id<span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>remaining<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">False<\/span><br \/>\n    save_todos<span class=\"token punctuation\">(<\/span>remaining<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Parse command-line arguments and run the requested command.&#034;&#034;&#034;<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span>prog<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo&#034;<\/span><span class=\"token punctuation\">,<\/span> description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;A simple todo app.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    subparsers <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    add_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Add a new todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    add_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">,<\/span> nargs<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;&#043;&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Todo description&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    add_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;JSON file to use&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    list_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;List all todos&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    list_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;JSON file to use&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    done_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Mark a todo as done&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    done_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;todo_id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Todo ID&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    done_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;JSON file to use&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    delete_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Delete a todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    delete_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;todo_id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Todo ID&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    delete_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;&#8211;file&#034;<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;JSON file to use&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        description <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034; &#034;<\/span><span class=\"token punctuation\">.<\/span>join<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>description<span class=\"token punctuation\">)<\/span><br \/>\n        todo_id <span class=\"token operator\">&#061;<\/span> add_todo<span class=\"token punctuation\">(<\/span>description<span class=\"token punctuation\">,<\/span> args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">file<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>description<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todos <span class=\"token operator\">&#061;<\/span> list_todos<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">file<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;No todos.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            status <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;[x]&#034;<\/span> <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034;[ ]&#034;<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>status<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> mark_done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>todo_id<span class=\"token punctuation\">,<\/span> args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">file<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Marked todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> as done.&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">else<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;No todo with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">.&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> delete_todo<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>todo_id<span class=\"token punctuation\">,<\/span> args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">file<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">.&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">else<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;No todo with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">.&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>Codex \u751f\u6210\u7684 test_todo.py (3197 bytes)<\/h4>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">import<\/span> todo<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_missing_file_returns_empty_list<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;nope.json&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_save_and_load_round_trip<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todos<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_corrupt_json_returns_empty_list<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    path<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;{not json&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_non_list_json_returns_empty_list<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    path<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;{&#034;key&#034;: &#034;value&#034;}&#039;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_todo_assigns_incrementing_ids<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first task&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;second task&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> first <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todos <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;first task&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;second task&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_mark_done<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_mark_done_missing_id_returns_false<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_todo<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;keep&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;remove&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>delete_todo<span class=\"token punctuation\">(<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;keep&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_missing_id_returns_false<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>delete_todo<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_main_add_and_list<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;buy&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    out <span class=\"token operator\">&#061;<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span> <span class=\"token keyword\">in<\/span> out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Added todo&#034;<\/span> <span class=\"token keyword\">in<\/span> out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_shows_done_status<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;pending&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;finished&#034;<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    out <span class=\"token operator\">&#061;<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;[ ] 1: pending&#034;<\/span> <span class=\"token keyword\">in<\/span> out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;[x] 2: finished&#034;<\/span> <span class=\"token keyword\">in<\/span> out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_main_done_and_delete<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;task&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todos.&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_main_missing_todo_returns_error<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todo with id 1&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>err<br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;-f&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todo with id 1&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>err<\/p>\n<h4>Codex pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; test session starts &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\nplatform linux &#8212; Python 3.13.5, pytest-9.1.1, pluggy-1.6.0 &#8212; \/tmp\/bench-venv\/bin\/python<br \/>\ncachedir: .pytest_cache<br \/>\nrootdir: \/home\/agent\/coding-benchmark\/test-codex<br \/>\ncollecting &#8230; collected 13 items<\/p>\n<p>test_todo.py::test_load_missing_file_returns_empty_list PASSED           [  7%]<br \/>\ntest_todo.py::test_save_and_load_round_trip PASSED                       [ 15%]<br \/>\ntest_todo.py::test_load_corrupt_json_returns_empty_list PASSED           [ 23%]<br \/>\ntest_todo.py::test_load_non_list_json_returns_empty_list PASSED          [ 30%]<br \/>\ntest_todo.py::test_add_todo_assigns_incrementing_ids PASSED              [ 38%]<br \/>\ntest_todo.py::test_mark_done PASSED                                      [ 46%]<br \/>\ntest_todo.py::test_mark_done_missing_id_returns_false PASSED             [ 53%]<br \/>\ntest_todo.py::test_delete_todo PASSED                                    [ 61%]<br \/>\ntest_todo.py::test_delete_missing_id_returns_false PASSED                [ 69%]<br \/>\ntest_todo.py::test_main_add_and_list PASSED                              [ 76%]<br \/>\ntest_todo.py::test_list_shows_done_status PASSED                         [ 84%]<br \/>\ntest_todo.py::test_main_done_and_delete PASSED                           [ 92%]<br \/>\ntest_todo.py::test_main_missing_todo_returns_error PASSED                [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 13 passed in 0.10s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n<hr \/>\n<h3>Cline v3.0.49 \u2014 24\/24 (\u624b\u52a8\u4fee\u590d\u540e)<\/h3>\n<h4>Cline \u751f\u6210\u7684 todo.py (4751 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A simple command-line todo app with JSON persistence.<\/p>\n<p>Usage:<br \/>\n    python todo.py add &#034;Buy milk&#034;<br \/>\n    python todo.py list<br \/>\n    python todo.py done 1<br \/>\n    python todo.py delete 1<\/p>\n<p>Tasks are stored in a JSON file (todo.json by default). Set the TODO_FILE<br \/>\nenvironment variable to use a different data file.<br \/>\n&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> os<br \/>\n<span class=\"token keyword\">import<\/span> sys<\/p>\n<p>DEFAULT_DATA_FILE <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;todo.json&#034;<\/span><\/p>\n<p><span class=\"token keyword\">class<\/span> <span class=\"token class-name\">TodoList<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A todo list backed by a JSON file.<\/p>\n<p>    Each task is a dict: {&#034;id&#034;: int, &#034;description&#034;: str, &#034;done&#034;: bool}.<br \/>\n    &#034;&#034;&#034;<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>DEFAULT_DATA_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>data_file <span class=\"token operator\">&#061;<\/span> data_file<br \/>\n        self<span class=\"token punctuation\">.<\/span>tasks <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>_max_id <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">load<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Load tasks from the JSON data file.<\/p>\n<p>        A missing or corrupt file simply yields an empty list so the app<br \/>\n        never crashes on startup.<br \/>\n        &#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>data_file<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;r&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> fh<span class=\"token punctuation\">:<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>tasks <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span>fh<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">except<\/span> <span class=\"token punctuation\">(<\/span>FileNotFoundError<span class=\"token punctuation\">,<\/span> json<span class=\"token punctuation\">.<\/span>JSONDecodeError<span class=\"token punctuation\">,<\/span> OSError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            self<span class=\"token punctuation\">.<\/span>tasks <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>_max_id <span class=\"token operator\">&#061;<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> task <span class=\"token keyword\">in<\/span> self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Persist tasks to the JSON data file.&#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>data_file<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> fh<span class=\"token punctuation\">:<\/span><br \/>\n            json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">,<\/span> fh<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">_next_id<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return the next task id: never reuse an id, even after deletion.&#034;&#034;&#034;<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>_max_id <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> self<span class=\"token punctuation\">.<\/span>_max_id<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> description<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Add a new task and return it.&#034;&#034;&#034;<\/span><br \/>\n        task <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> self<span class=\"token punctuation\">.<\/span>_next_id<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> description<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span>task<span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>save<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> task<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> task_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return the task with the given id, or None if it does not exist.&#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> task <span class=\"token keyword\">in<\/span> self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> task_id<span class=\"token punctuation\">:<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> task<br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">list_tasks<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return a copy of all tasks in insertion order.&#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">done<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> task_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Mark the task with the given id as done and return it.<\/p>\n<p>        Raises KeyError if no such task exists.<br \/>\n        &#034;&#034;&#034;<\/span><br \/>\n        task <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span>task_id<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> task <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">raise<\/span> KeyError<span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;no task with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>save<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> task<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">delete<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> task_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Remove the task with the given id and return it.<\/p>\n<p>        Raises KeyError if no such task exists.<br \/>\n        &#034;&#034;&#034;<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> index<span class=\"token punctuation\">,<\/span> task <span class=\"token keyword\">in<\/span> <span class=\"token builtin\">enumerate<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> task_id<span class=\"token punctuation\">:<\/span><br \/>\n                removed <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">.<\/span>pop<span class=\"token punctuation\">(<\/span>index<span class=\"token punctuation\">)<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>save<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token keyword\">return<\/span> removed<br \/>\n        <span class=\"token keyword\">raise<\/span> KeyError<span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;no task with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">format_task<\/span><span class=\"token punctuation\">(<\/span>task<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Render a task as a one-line string, e.g. &#039;[x] 1. Buy milk&#039;.&#034;&#034;&#034;<\/span><br \/>\n    marker <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;[x]&#034;<\/span> <span class=\"token keyword\">if<\/span> task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034;[ ]&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>marker<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">. <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span><br \/>\n        prog<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo&#034;<\/span><span class=\"token punctuation\">,<\/span> description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;A simple CLI todo app with JSON persistence.&#034;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    subparsers <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    add_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;add a new task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    add_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;task description&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;list all tasks&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    done_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;mark a task as done&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    done_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;task id&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    delete_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;delete a task&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    delete_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;task id&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><\/p>\n<p>    data_file <span class=\"token operator\">&#061;<\/span> os<span class=\"token punctuation\">.<\/span>environ<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;TODO_FILE&#034;<\/span><span class=\"token punctuation\">,<\/span> DEFAULT_DATA_FILE<span class=\"token punctuation\">)<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> TodoList<span class=\"token punctuation\">(<\/span>data_file<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            task <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>description<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added task <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            tasks <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>list_tasks<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> tasks<span class=\"token punctuation\">:<\/span><br \/>\n                <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;No tasks yet.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">else<\/span><span class=\"token punctuation\">:<\/span><br \/>\n                <span class=\"token keyword\">for<\/span> task <span class=\"token keyword\">in<\/span> tasks<span class=\"token punctuation\">:<\/span><br \/>\n                    <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span>format_task<span class=\"token punctuation\">(<\/span>task<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            todo<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Marked task <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> as done.&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            task <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted task <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">except<\/span> KeyError <span class=\"token keyword\">as<\/span> exc<span class=\"token punctuation\">:<\/span><br \/>\n        msg <span class=\"token operator\">&#061;<\/span> exc<span class=\"token punctuation\">.<\/span>args<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">if<\/span> exc<span class=\"token punctuation\">.<\/span>args <span class=\"token keyword\">else<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>exc<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Error: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>msg<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>Cline \u751f\u6210\u7684 test_todo.py (5061 bytes)<\/h4>\n<p><span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Unit tests for the todo CLI app.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> json<\/p>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">import<\/span> todo<\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">todo_list<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A TodoList backed by a temp JSON file.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> todo<span class=\"token punctuation\">.<\/span>TodoList<span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;tasks.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">cli<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> monkeypatch<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Point the CLI at a temp data file via the TODO_FILE env var.&#034;&#034;&#034;<\/span><br \/>\n    data_file <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;tasks.json&#034;<\/span><br \/>\n    monkeypatch<span class=\"token punctuation\">.<\/span>setenv<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;TODO_FILE&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>data_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> data_file<\/p>\n<p><span class=\"token comment\"># &#8212; Model: add &#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_creates_task<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    task <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> task <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo_list<span class=\"token punctuation\">.<\/span>tasks <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span>task<span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_persists_to_disk<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo_list<span class=\"token punctuation\">.<\/span>data_file<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    saved <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">.<\/span>data_file<span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> saved <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_increments_ids<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> first<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; Model: list &#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_empty<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo_list<span class=\"token punctuation\">.<\/span>list_tasks<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_returns_all_tasks<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    tasks <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>list_tasks<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> task <span class=\"token keyword\">in<\/span> tasks<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_returns_copy<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    listing <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>list_tasks<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    listing<span class=\"token punctuation\">.<\/span>clear<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">.<\/span>tasks<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; Model: done &#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_marks_task<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    task <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo_list<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_persists<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    saved <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">.<\/span>data_file<span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> saved<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_unknown_id_raises<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> pytest<span class=\"token punctuation\">.<\/span>raises<span class=\"token punctuation\">(<\/span>KeyError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo_list<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; Model: delete &#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_removes_task<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    removed <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> removed<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todo_list<span class=\"token punctuation\">.<\/span>list_tasks<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_persists<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    saved <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">.<\/span>data_file<span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> saved <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_unknown_id_raises<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> pytest<span class=\"token punctuation\">.<\/span>raises<span class=\"token punctuation\">(<\/span>KeyError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo_list<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_next_id_survives_delete<\/span><span class=\"token punctuation\">(<\/span>todo_list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token comment\"># Ids are derived from max existing id, so a deleted id is not reused.<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo_list<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    task <span class=\"token operator\">&#061;<\/span> todo_list<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> task<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; Model: persistence \/ loading &#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_reload_from_disk<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;tasks.json&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>TodoList<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;Persisted&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    reloaded <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>TodoList<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> reloaded<span class=\"token punctuation\">.<\/span>list_tasks<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Persisted&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_corrupt_file_starts_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;tasks.json&#034;<\/span><br \/>\n    path<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;{not valid json&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    store <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>TodoList<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> store<span class=\"token punctuation\">.<\/span>tasks <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_missing_file_starts_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    store <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>TodoList<span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;nonexistent.json&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> store<span class=\"token punctuation\">.<\/span>tasks <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_format_task<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>format_task<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token string\">&#034;[ ] 1. Buy milk&#034;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>format_task<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;Pay rent&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token string\">&#034;[x] 2. Pay rent&#034;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; CLI end-to-end &#8212;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_add<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Buy milk&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Added task 1: Buy milk&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_list_empty<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No tasks yet.&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_list_shows_tasks<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;First&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Second&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    out <span class=\"token operator\">&#061;<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;[ ] 1. First&#034;<\/span> <span class=\"token keyword\">in<\/span> out<br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;[ ] 2. Second&#034;<\/span> <span class=\"token keyword\">in<\/span> out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_done<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Marked task 1 as done.&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;[x] 1. Task&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_delete<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Task&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Deleted task 1: Task&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No tasks yet.&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_done_unknown_id_fails<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;42&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;Error: no task with id 42&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>err<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_state_persists_across_invocations<\/span><span class=\"token punctuation\">(<\/span>cli<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;Persist me&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;1. Persist me&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<h4>Cline pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>e_marks_task PASSED                                [ 29%]<br \/>\ntest_todo.py::test_done_persists PASSED                                  [ 33%]<br \/>\ntest_todo.py::test_done_unknown_id_raises PASSED                         [ 37%]<br \/>\ntest_todo.py::test_delete_removes_task PASSED                            [ 41%]<br \/>\ntest_todo.py::test_delete_persists PASSED                                [ 45%]<br \/>\ntest_todo.py::test_delete_unknown_id_raises PASSED                       [ 50%]<br \/>\ntest_todo.py::test_next_id_survives_delete PASSED                        [ 54%]<br \/>\ntest_todo.py::test_reload_from_disk PASSED                               [ 58%]<br \/>\ntest_todo.py::test_corrupt_file_starts_empty PASSED                      [ 62%]<br \/>\ntest_todo.py::test_missing_file_starts_empty PASSED                      [ 66%]<br \/>\ntest_todo.py::test_format_task PASSED                                    [ 70%]<br \/>\ntest_todo.py::test_cli_add PASSED                                        [ 75%]<br \/>\ntest_todo.py::test_cli_list_empty PASSED                                 [ 79%]<br \/>\ntest_todo.py::test_cli_list_shows_tasks PASSED                           [ 83%]<br \/>\ntest_todo.py::test_cli_done PASSED                                       [ 87%]<br \/>\ntest_todo.py::test_cli_delete PASSED                                     [ 91%]<br \/>\ntest_todo.py::test_cli_done_unknown_id_fails PASSED                      [ 95%]<br \/>\ntest_todo.py::test_cli_state_persists_across_invocations PASSED          [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 24 passed in 0.16s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n<hr \/>\n<h3>Kilo Code v7.4.17 \u2014 10\/10<\/h3>\n<h4>Kilo Code \u751f\u6210\u7684 todo.py (2985 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A simple CLI todo app with JSON persistence.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> sys<br \/>\n<span class=\"token keyword\">from<\/span> pathlib <span class=\"token keyword\">import<\/span> Path<\/p>\n<p>DEFAULT_STORE <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">(<\/span>__file__<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>with_name<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">class<\/span> <span class=\"token class-name\">Todo<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">__init__<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> text<span class=\"token punctuation\">,<\/span> done<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">False<\/span><span class=\"token punctuation\">,<\/span> store_path<span class=\"token operator\">&#061;<\/span>DEFAULT_STORE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>text <span class=\"token operator\">&#061;<\/span> text<br \/>\n        self<span class=\"token punctuation\">.<\/span>is_done <span class=\"token operator\">&#061;<\/span> done<br \/>\n        self<span class=\"token punctuation\">.<\/span>store_path <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">(<\/span>store_path<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token decorator annotation punctuation\">&#064;property<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">store<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> self<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">or<\/span> <span class=\"token string\">&#034;[]&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token decorator annotation punctuation\">&#064;store<span class=\"token punctuation\">.<\/span>setter<\/span><br \/>\n    <span class=\"token keyword\">def<\/span> <span class=\"token function\">store<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> items<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>dumps<span class=\"token punctuation\">(<\/span>items<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">_next_id<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> items<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> item <span class=\"token keyword\">in<\/span> items<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        items <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>store<br \/>\n        todo_id <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>_next_id<span class=\"token punctuation\">(<\/span>items<span class=\"token punctuation\">)<\/span><br \/>\n        items<span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> todo_id<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">:<\/span> self<span class=\"token punctuation\">.<\/span>text<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> self<span class=\"token punctuation\">.<\/span>is_done<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>store <span class=\"token operator\">&#061;<\/span> items<br \/>\n        <span class=\"token keyword\">return<\/span> todo_id<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">list<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> self<span class=\"token punctuation\">.<\/span>store<\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">done<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> todo_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        items <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>store<br \/>\n        <span class=\"token keyword\">for<\/span> item <span class=\"token keyword\">in<\/span> items<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n                item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n                self<span class=\"token punctuation\">.<\/span>store <span class=\"token operator\">&#061;<\/span> items<br \/>\n                <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">True<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p>    <span class=\"token keyword\">def<\/span> <span class=\"token function\">delete<\/span><span class=\"token punctuation\">(<\/span>self<span class=\"token punctuation\">,<\/span> todo_id<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        items <span class=\"token operator\">&#061;<\/span> self<span class=\"token punctuation\">.<\/span>store<br \/>\n        new_items <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span>item <span class=\"token keyword\">for<\/span> item <span class=\"token keyword\">in<\/span> items <span class=\"token keyword\">if<\/span> item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">!&#061;<\/span> todo_id<span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>new_items<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>items<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">False<\/span><br \/>\n        self<span class=\"token punctuation\">.<\/span>store <span class=\"token operator\">&#061;<\/span> new_items<br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span>description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Manage a todo list.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    subparsers <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    add_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Add a new todo.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    add_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;The todo text.&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;List all todos.&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    done_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Mark a todo done.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    done_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;The todo id.&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    delete_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Delete a todo.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    delete_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;The todo id.&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><\/p>\n<p>    todo <span class=\"token operator\">&#061;<\/span> Todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo<span class=\"token punctuation\">.<\/span>text <span class=\"token operator\">&#061;<\/span> args<span class=\"token punctuation\">.<\/span>text<br \/>\n        todo_id <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo_id<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> item <span class=\"token keyword\">in<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            status <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;x&#034;<\/span> <span class=\"token keyword\">if<\/span> item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034; &#034;<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> [<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>status<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">] <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;text&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Marked todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> as done&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">else<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> not found&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">else<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> not found&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>Kilo Code \u751f\u6210\u7684 test_todo.py (1569 bytes)<\/h4>\n<p><span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Unit tests for todo.py.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> json<\/p>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">from<\/span> todo <span class=\"token keyword\">import<\/span> Todo<\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">todo<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> Todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;&#034;<\/span><span class=\"token punctuation\">,<\/span> store_path<span class=\"token operator\">&#061;<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_creates_todo<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_id <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    items <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>items<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> items<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<br \/>\n    <span class=\"token keyword\">assert<\/span> items<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> items<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_assigns_incrementing_ids<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second <span class=\"token operator\">&#061;&#061;<\/span> first <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_persists_to_disk<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    raw <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>store_path<span class=\"token punctuation\">.<\/span>read_text<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> json<span class=\"token punctuation\">.<\/span>loads<span class=\"token punctuation\">(<\/span>raw<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_empty<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_returns_all_todos<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>text <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;first&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>text <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;second&#034;<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;text&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> item <span class=\"token keyword\">in<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;second&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_marks_todo<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_id <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    items <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> items<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_done_missing_id_returns_false<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>done<span class=\"token punctuation\">(<\/span><span class=\"token number\">999<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_removes_todo<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todo_id <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_missing_id_returns_false<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span><span class=\"token number\">999<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_only_removes_target<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>delete<span class=\"token punctuation\">(<\/span>first<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>item<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> item <span class=\"token keyword\">in<\/span> todo<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">list<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span>second<span class=\"token punctuation\">]<\/span><\/p>\n<h4>Kilo Code pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; test session starts &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\nplatform linux &#8212; Python 3.13.5, pytest-9.1.1, pluggy-1.6.0 &#8212; \/tmp\/bench-venv\/bin\/python<br \/>\ncachedir: .pytest_cache<br \/>\nrootdir: \/home\/agent\/coding-benchmark\/test-kilo<br \/>\ncollecting &#8230; collected 10 items<\/p>\n<p>test_todo.py::test_add_creates_todo PASSED                               [ 10%]<br \/>\ntest_todo.py::test_add_assigns_incrementing_ids PASSED                   [ 20%]<br \/>\ntest_todo.py::test_add_persists_to_disk PASSED                           [ 30%]<br \/>\ntest_todo.py::test_list_empty PASSED                                     [ 40%]<br \/>\ntest_todo.py::test_list_returns_all_todos PASSED                         [ 50%]<br \/>\ntest_todo.py::test_done_marks_todo PASSED                                [ 60%]<br \/>\ntest_todo.py::test_done_missing_id_returns_false PASSED                  [ 70%]<br \/>\ntest_todo.py::test_delete_removes_todo PASSED                            [ 80%]<br \/>\ntest_todo.py::test_delete_missing_id_returns_false PASSED                [ 90%]<br \/>\ntest_todo.py::test_delete_only_removes_target PASSED                     [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 10 passed in 0.06s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n<hr \/>\n<h3>Crush vgo \u7f16\u8bd1\u7248 \u2014 13\/13<\/h3>\n<h4>Crush \u751f\u6210\u7684 todo.py (3654 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A minimal CLI todo app with JSON persistence.<\/p>\n<p>Commands:<br \/>\n    add &lt;description&gt;   Add a new todo<br \/>\n    list                List all todos (with done status)<br \/>\n    done &lt;id&gt;           Mark a todo as done<br \/>\n    delete &lt;id&gt;         Delete a todo<br \/>\n&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> os<br \/>\n<span class=\"token keyword\">import<\/span> sys<\/p>\n<p>DEFAULT_FILE <span class=\"token operator\">&#061;<\/span> os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>join<span class=\"token punctuation\">(<\/span>os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>dirname<span class=\"token punctuation\">(<\/span>os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>abspath<span class=\"token punctuation\">(<\/span>__file__<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">load_todos<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Load todos from the JSON file, returning an empty list if missing.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> os<span class=\"token punctuation\">.<\/span>path<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;r&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n            data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span>f<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">except<\/span> <span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>JSONDecodeError<span class=\"token punctuation\">,<\/span> OSError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> <span class=\"token builtin\">isinstance<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> data<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">save_todos<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Persist todos to the JSON file.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n        json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> f<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">next_id<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return the next available todo id.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">add_todo<\/span><span class=\"token punctuation\">(<\/span>description<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Add a new todo and return it.&#034;&#034;&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> next_id<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> description<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    todos<span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><br \/>\n    save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> todo<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">list_todos<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return the list of todos.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">mark_done<\/span><span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Mark a todo as done. Returns the todo, or None if not found.&#034;&#034;&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n            todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n            save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> todo<br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">delete_todo<\/span><span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">,<\/span> path<span class=\"token operator\">&#061;<\/span>DEFAULT_FILE<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Delete a todo. Returns the deleted todo, or None if not found.&#034;&#034;&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> i<span class=\"token punctuation\">,<\/span> todo <span class=\"token keyword\">in<\/span> <span class=\"token builtin\">enumerate<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n            removed <span class=\"token operator\">&#061;<\/span> todos<span class=\"token punctuation\">.<\/span>pop<span class=\"token punctuation\">(<\/span>i<span class=\"token punctuation\">)<\/span><br \/>\n            save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> removed<br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span>prog<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo&#034;<\/span><span class=\"token punctuation\">,<\/span> description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;A simple todo app&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    sub <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;list all todos&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_add <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;add a todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_add<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo description&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_done <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;mark a todo as done&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_done<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo id&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    p_del <span class=\"token operator\">&#061;<\/span> sub<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;delete a todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    p_del<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;todo id&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> add_todo<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>description<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todos <span class=\"token operator\">&#061;<\/span> list_todos<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;No todos.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><br \/>\n        <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            status <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;[x]&#034;<\/span> <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034;[ ]&#034;<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>status<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> mark_done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> not found.&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Done: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> delete_todo<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Todo #<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> not found.&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">file<\/span><span class=\"token operator\">&#061;<\/span>sys<span class=\"token punctuation\">.<\/span>stderr<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;description&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>Crush \u751f\u6210\u7684 test_todo.py (2861 bytes)<\/h4>\n<p><span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Unit tests for todo.py.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> os<\/p>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">import<\/span> todo<\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">todo_file<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return a path to a temp JSON file for a test.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">(<\/span>tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token decorator annotation punctuation\">&#064;pytest<span class=\"token punctuation\">.<\/span>fixture<\/span><br \/>\n<span class=\"token keyword\">def<\/span> <span class=\"token function\">populated_file<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Create a temp file pre-populated with two todos.&#034;&#034;&#034;<\/span><br \/>\n    data <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;walk dog&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n        json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> f<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> todo_file<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_missing_file<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_invalid_json<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n        f<span class=\"token punctuation\">.<\/span>write<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;not json{&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_non_list<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n        json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;wrong&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;shape&#034;<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> f<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_save_and_load_roundtrip<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;x&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    todo<span class=\"token punctuation\">.<\/span>save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> todo_file<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todos<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_next_id_empty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>next_id<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_next_id_continues<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>next_id<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">3<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_todo<\/span><span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    added <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> todo_file<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> added <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>todo_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span>added<span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_todo_increments_ids<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">,<\/span> populated_file<span class=\"token punctuation\">)<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;second&#034;<\/span><span class=\"token punctuation\">,<\/span> populated_file<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> first<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">3<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">4<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_todos<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>list_todos<span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;walk dog&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_mark_done<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    updated <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> populated_file<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> updated <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    stored <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> stored<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> stored<span class=\"token punctuation\">[<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span>  <span class=\"token comment\"># unchanged<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_mark_done_missing<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">,<\/span> populated_file<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_todo<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    removed <span class=\"token operator\">&#061;<\/span> todo<span class=\"token punctuation\">.<\/span>delete_todo<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> populated_file<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> removed <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;description&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;walk dog&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_missing<\/span><span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todo<span class=\"token punctuation\">.<\/span>delete_todo<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">,<\/span> populated_file<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">.<\/span>load_todos<span class=\"token punctuation\">(<\/span>populated_file<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><\/p>\n<h4>Crush pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; test session starts &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\nplatform linux &#8212; Python 3.13.5, pytest-9.1.1, pluggy-1.6.0 &#8212; \/tmp\/bench-venv\/bin\/python<br \/>\ncachedir: .pytest_cache<br \/>\nrootdir: \/home\/agent\/coding-benchmark\/test-crush<br \/>\ncollecting &#8230; collected 13 items<\/p>\n<p>test_todo.py::test_load_missing_file PASSED                              [  7%]<br \/>\ntest_todo.py::test_load_invalid_json PASSED                              [ 15%]<br \/>\ntest_todo.py::test_load_non_list PASSED                                  [ 23%]<br \/>\ntest_todo.py::test_save_and_load_roundtrip PASSED                        [ 30%]<br \/>\ntest_todo.py::test_next_id_empty PASSED                                  [ 38%]<br \/>\ntest_todo.py::test_next_id_continues PASSED                              [ 46%]<br \/>\ntest_todo.py::test_add_todo PASSED                                       [ 53%]<br \/>\ntest_todo.py::test_add_todo_increments_ids PASSED                        [ 61%]<br \/>\ntest_todo.py::test_list_todos PASSED                                     [ 69%]<br \/>\ntest_todo.py::test_mark_done PASSED                                      [ 76%]<br \/>\ntest_todo.py::test_mark_done_missing PASSED                              [ 84%]<br \/>\ntest_todo.py::test_delete_todo PASSED                                    [ 92%]<br \/>\ntest_todo.py::test_delete_missing PASSED                                 [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 13 passed in 0.07s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n<hr \/>\n<h3>Goose v1.45.0 \u2014 17\/17<\/h3>\n<h4>Goose \u751f\u6210\u7684 todo.py (3972 bytes)<\/h4>\n<p><span class=\"token comment\">#!\/usr\/bin\/env python3<\/span><br \/>\n<span class=\"token triple-quoted-string string\">&#034;&#034;&#034;A simple CLI todo app with JSON persistence.<\/p>\n<p>Commands:<br \/>\n    add &lt;title&gt;    Add a new todo<br \/>\n    list           List all todos<br \/>\n    done &lt;id&gt;      Mark a todo as done<br \/>\n    delete &lt;id&gt;    Delete a todo<br \/>\n&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> argparse<br \/>\n<span class=\"token keyword\">import<\/span> json<br \/>\n<span class=\"token keyword\">import<\/span> sys<br \/>\n<span class=\"token keyword\">from<\/span> pathlib <span class=\"token keyword\">import<\/span> Path<\/p>\n<p>DEFAULT_DATA_FILE <span class=\"token operator\">&#061;<\/span> Path<span class=\"token punctuation\">(<\/span>__file__<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>resolve<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>parent <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">load_todos<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">:<\/span> Path <span class=\"token operator\">&#061;<\/span> DEFAULT_DATA_FILE<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Load todos from a JSON file. Returns an empty list if missing\/invalid.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> path<span class=\"token punctuation\">.<\/span>exists<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">try<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;r&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n            data <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>load<span class=\"token punctuation\">(<\/span>f<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">except<\/span> <span class=\"token punctuation\">(<\/span>json<span class=\"token punctuation\">.<\/span>JSONDecodeError<span class=\"token punctuation\">,<\/span> OSError<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> <span class=\"token builtin\">isinstance<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> data<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">save_todos<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">:<\/span> Path <span class=\"token operator\">&#061;<\/span> DEFAULT_DATA_FILE<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Save todos to a JSON file.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> <span class=\"token builtin\">open<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;w&#034;<\/span><span class=\"token punctuation\">,<\/span> encoding<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;utf-8&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span> f<span class=\"token punctuation\">:<\/span><br \/>\n        json<span class=\"token punctuation\">.<\/span>dump<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> f<span class=\"token punctuation\">,<\/span> indent<span class=\"token operator\">&#061;<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">add_todo<\/span><span class=\"token punctuation\">(<\/span>title<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">str<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Add a new todo to the list and return it.&#034;&#034;&#034;<\/span><br \/>\n    todo <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">max<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos <span class=\"token keyword\">if<\/span> <span class=\"token builtin\">isinstance<\/span><span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> default<span class=\"token operator\">&#061;<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> title<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    todos<span class=\"token punctuation\">.<\/span>append<span class=\"token punctuation\">(<\/span>todo<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> todo<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">list_todos<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Return todos sorted with incomplete items first, newest first.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token builtin\">sorted<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        todos<span class=\"token punctuation\">,<\/span><br \/>\n        key<span class=\"token operator\">&#061;<\/span><span class=\"token keyword\">lambda<\/span> t<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">(<\/span>t<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token operator\">&#8211;<\/span>t<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">mark_done<\/span><span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">dict<\/span> <span class=\"token operator\">|<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Mark a todo as done. Returns the todo, or None if not found.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n            todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">True<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> todo<br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">delete_todo<\/span><span class=\"token punctuation\">(<\/span>todo_id<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">dict<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">dict<\/span> <span class=\"token operator\">|<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Delete a todo. Returns the deleted todo, or None if not found.&#034;&#034;&#034;<\/span><br \/>\n    <span class=\"token keyword\">for<\/span> i<span class=\"token punctuation\">,<\/span> todo <span class=\"token keyword\">in<\/span> <span class=\"token builtin\">enumerate<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todo_id<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> todos<span class=\"token punctuation\">.<\/span>pop<span class=\"token punctuation\">(<\/span>i<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">:<\/span> <span class=\"token builtin\">list<\/span><span class=\"token punctuation\">[<\/span><span class=\"token builtin\">str<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">|<\/span> <span class=\"token boolean\">None<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token punctuation\">:<\/span> Path <span class=\"token operator\">|<\/span> <span class=\"token boolean\">None<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token builtin\">int<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Run the CLI. Returns a process exit code (0 &#061; success, 1 &#061; not found).&#034;&#034;&#034;<\/span><br \/>\n    parser <span class=\"token operator\">&#061;<\/span> argparse<span class=\"token punctuation\">.<\/span>ArgumentParser<span class=\"token punctuation\">(<\/span>description<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Simple CLI todo app&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    subparsers <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>add_subparsers<span class=\"token punctuation\">(<\/span>dest<span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;command&#034;<\/span><span class=\"token punctuation\">,<\/span> required<span class=\"token operator\">&#061;<\/span><span class=\"token boolean\">True<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    add_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Add a new todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    add_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Title of the todo&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;List all todos&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    done_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Mark a todo as done&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    done_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;ID of the todo&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    delete_parser <span class=\"token operator\">&#061;<\/span> subparsers<span class=\"token punctuation\">.<\/span>add_parser<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;Delete a todo&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    delete_parser<span class=\"token punctuation\">.<\/span>add_argument<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">type<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token builtin\">int<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token builtin\">help<\/span><span class=\"token operator\">&#061;<\/span><span class=\"token string\">&#034;ID of the todo&#034;<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    args <span class=\"token operator\">&#061;<\/span> parser<span class=\"token punctuation\">.<\/span>parse_args<span class=\"token punctuation\">(<\/span>argv<span class=\"token punctuation\">)<\/span><\/p>\n<p>    path <span class=\"token operator\">&#061;<\/span> data_file <span class=\"token keyword\">or<\/span> DEFAULT_DATA_FILE<br \/>\n    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">if<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> add_todo<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span>title<span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n        save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Added todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token keyword\">not<\/span> todos<span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;No todos yet.&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">else<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">for<\/span> todo <span class=\"token keyword\">in<\/span> list_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n                status <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#034;[x]&#034;<\/span> <span class=\"token keyword\">if<\/span> todo<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string\">&#034;[ ]&#034;<\/span><br \/>\n                <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;<\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>status<span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">.<\/span>get<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> mark_done<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;No todo with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n        save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Marked todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\"> as done: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">elif<\/span> args<span class=\"token punctuation\">.<\/span>command <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        todo <span class=\"token operator\">&#061;<\/span> delete_todo<span class=\"token punctuation\">(<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> todo <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><span class=\"token punctuation\">:<\/span><br \/>\n            <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;No todo with id <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>args<span class=\"token punctuation\">.<\/span><span class=\"token builtin\">id<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> <span class=\"token number\">1<\/span><br \/>\n        save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">print<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-interpolation\"><span class=\"token string\">f&#034;Deleted todo <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;id&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">: <\/span><span class=\"token interpolation\"><span class=\"token punctuation\">{<\/span>todo<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;title&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> <span class=\"token number\">0<\/span><\/p>\n<p><span class=\"token keyword\">if<\/span> __name__ <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;__main__&#034;<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    sys<span class=\"token punctuation\">.<\/span>exit<span class=\"token punctuation\">(<\/span>main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h4>Goose \u751f\u6210\u7684 test_todo.py (4285 bytes)<\/h4>\n<p><span class=\"token triple-quoted-string string\">&#034;&#034;&#034;Unit tests for the todo CLI app.&#034;&#034;&#034;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> pytest<\/p>\n<p><span class=\"token keyword\">from<\/span> todo <span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">(<\/span><br \/>\n    add_todo<span class=\"token punctuation\">,<\/span><br \/>\n    delete_todo<span class=\"token punctuation\">,<\/span><br \/>\n    list_todos<span class=\"token punctuation\">,<\/span><br \/>\n    load_todos<span class=\"token punctuation\">,<\/span><br \/>\n    main<span class=\"token punctuation\">,<\/span><br \/>\n    mark_done<span class=\"token punctuation\">,<\/span><br \/>\n    save_todos<span class=\"token punctuation\">,<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; persistence &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_todos_missing_file_returns_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_save_and_load_roundtrip<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    save_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">,<\/span> path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> todos<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_invalid_json_returns_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    path<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;not valid json {&#034;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_load_non_list_json_returns_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    path<span class=\"token punctuation\">.<\/span>write_text<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;{&#034;foo&#034;: &#034;bar&#034;}&#039;<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; model operations &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_todo_assigns_incrementing_ids<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    first <span class=\"token operator\">&#061;<\/span> add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n    second <span class=\"token operator\">&#061;<\/span> add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;second&#034;<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> first<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">2<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> first<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">False<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> second<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;second&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> todos<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;first&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;second&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_add_todo_continues_ids_after_existing<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">5<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;existing&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    new <span class=\"token operator\">&#061;<\/span> add_todo<span class=\"token punctuation\">(<\/span><span class=\"token string\">&#034;new&#034;<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> new<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">6<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_mark_done_flags_todo<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;a&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    result <span class=\"token operator\">&#061;<\/span> mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> result <span class=\"token operator\">&#061;&#061;<\/span> todos<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todos<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_mark_done_missing_returns_none<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> mark_done<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;a&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_todo_removes_it<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;a&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;b&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><br \/>\n    deleted <span class=\"token operator\">&#061;<\/span> delete_todo<span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> deleted<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string\">&#034;a&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todos <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;b&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_delete_missing_returns_none<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;a&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> delete_todo<span class=\"token punctuation\">(<\/span><span class=\"token number\">99<\/span><span class=\"token punctuation\">,<\/span> todos<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">None<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token builtin\">len<\/span><span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_list_todos_sorts_incomplete_first_newest_first<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    todos <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;oldest done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">True<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;older open&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">3<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;newest open&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">]<\/span><br \/>\n    listed <span class=\"token operator\">&#061;<\/span> list_todos<span class=\"token punctuation\">(<\/span>todos<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token comment\"># Incomplete todos first, then newest id first within each group.<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> listed<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;newest open&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;older open&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;oldest done&#034;<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token comment\"># &#8212; CLI end-to-end &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_add_writes_json_and_prints<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">{<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;title&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token boolean\">False<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;buy milk&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_list_empty<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;list&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todos yet&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_done_and_delete_flow<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;task one&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;add&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;task two&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><\/p>\n<p>    todos <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> todos<span class=\"token punctuation\">[<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">is<\/span> <span class=\"token boolean\">True<\/span><\/p>\n<p>    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;1&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    remaining <span class=\"token operator\">&#061;<\/span> load_todos<span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token punctuation\">[<\/span>t<span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;id&#034;<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">for<\/span> t <span class=\"token keyword\">in<\/span> remaining<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token number\">2<\/span><span class=\"token punctuation\">]<\/span><\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_done_missing_returns_nonzero<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;done&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;42&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todo with id 42&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_delete_missing_returns_nonzero<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">,<\/span> capsys<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;delete&#034;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#034;42&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n    <span class=\"token keyword\">assert<\/span> <span class=\"token string\">&#034;No todo with id 42&#034;<\/span> <span class=\"token keyword\">in<\/span> capsys<span class=\"token punctuation\">.<\/span>readouterr<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>out<\/p>\n<p><span class=\"token keyword\">def<\/span> <span class=\"token function\">test_cli_invalid_command_raises_system_exit<\/span><span class=\"token punctuation\">(<\/span>tmp_path<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n    path <span class=\"token operator\">&#061;<\/span> tmp_path <span class=\"token operator\">\/<\/span> <span class=\"token string\">&#034;todos.json&#034;<\/span><br \/>\n    <span class=\"token keyword\">with<\/span> pytest<span class=\"token punctuation\">.<\/span>raises<span class=\"token punctuation\">(<\/span>SystemExit<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">:<\/span><br \/>\n        main<span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string\">&#034;bogus&#034;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span> data_file<span class=\"token operator\">&#061;<\/span>path<span class=\"token punctuation\">)<\/span><\/p>\n<h4>Goose pytest \u590d\u9a8c\u8f93\u51fa<\/h4>\n<p>g-benchmark\/test-goose<br \/>\ncollecting &#8230; collected 17 items<\/p>\n<p>test_todo.py::test_load_todos_missing_file_returns_empty PASSED          [  5%]<br \/>\ntest_todo.py::test_save_and_load_roundtrip PASSED                        [ 11%]<br \/>\ntest_todo.py::test_load_invalid_json_returns_empty PASSED                [ 17%]<br \/>\ntest_todo.py::test_load_non_list_json_returns_empty PASSED               [ 23%]<br \/>\ntest_todo.py::test_add_todo_assigns_incrementing_ids PASSED              [ 29%]<br \/>\ntest_todo.py::test_add_todo_continues_ids_after_existing PASSED          [ 35%]<br \/>\ntest_todo.py::test_mark_done_flags_todo PASSED                           [ 41%]<br \/>\ntest_todo.py::test_mark_done_missing_returns_none PASSED                 [ 47%]<br \/>\ntest_todo.py::test_delete_todo_removes_it PASSED                         [ 52%]<br \/>\ntest_todo.py::test_delete_missing_returns_none PASSED                    [ 58%]<br \/>\ntest_todo.py::test_list_todos_sorts_incomplete_first_newest_first PASSED [ 64%]<br \/>\ntest_todo.py::test_cli_add_writes_json_and_prints PASSED                 [ 70%]<br \/>\ntest_todo.py::test_cli_list_empty PASSED                                 [ 76%]<br \/>\ntest_todo.py::test_cli_done_and_delete_flow PASSED                       [ 82%]<br \/>\ntest_todo.py::test_cli_done_missing_returns_nonzero PASSED               [ 88%]<br \/>\ntest_todo.py::test_cli_delete_missing_returns_nonzero PASSED             [ 94%]<br \/>\ntest_todo.py::test_cli_invalid_command_raises_system_exit PASSED         [100%]<\/p>\n<p>&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; 17 passed in 0.10s &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>AI \u7f16\u7a0b\u5de5\u5177\u6a2a\u8bc4\u5b9e\u6d4b\u62a5\u544a&#xff08;2026-08-04&#xff09; 7 \u6b3e AI \u7f16\u7a0b\u5de5\u5177&#xff0c;\u540c\u4e00\u6a21\u578b&#xff08;deepseek-v4-flash&#xff09;\u3001\u540c\u4e00\u6d4b\u8bd5\u9898\u3001\u540c\u4e00\u7f51\u5173\u5e76\u884c\u5b9e\u6d4b\u3002 \u9644\u5e26 token \u6d88\u8017\u5bf9\u6bd4  \u4ee3\u7801\u8d28\u91cf  \u901f\u5ea6  \u6613\u7528\u6027  \u5df2\u77e5 bug \u5168\u8bb0\u5f55\u3002 \u76ee\u5f55<br \/>\n\u5feb\u901f\u7ed3\u8bba&#xff08;30 \u79d2\u7248&#xff09;\u6d4b\u8bd5\u65b9\u6cd5&#xff08;\u5b8c\u6574\u7248&#xff09; \u6d4b\u8bd5\u9898\u539f\u6587 \/ \u7edf\u4e00\u73af\u5883 \/ \u6267\u884c\u547d\u4ee4 \/ \u5224\u5b9a\u6807\u51c6 \/ \u5c40\u9650\u4e0e<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[10187,666,50,86],"topic":[],"class_list":["post-90246","post","type-post","status-publish","format-standard","hentry","category-server","tag-codingplan","tag-microsoft","tag-50","tag-86"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/90246.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"AI \u7f16\u7a0b\u5de5\u5177\u6a2a\u8bc4\u5b9e\u6d4b\u62a5\u544a&#xff08;2026-08-04&#xff09; 7 \u6b3e AI \u7f16\u7a0b\u5de5\u5177&#xff0c;\u540c\u4e00\u6a21\u578b&#xff08;deepseek-v4-flash&#xff09;\u3001\u540c\u4e00\u6d4b\u8bd5\u9898\u3001\u540c\u4e00\u7f51\u5173\u5e76\u884c\u5b9e\u6d4b\u3002 \u9644\u5e26 token \u6d88\u8017\u5bf9\u6bd4 \u4ee3\u7801\u8d28\u91cf \u901f\u5ea6 \u6613\u7528\u6027 \u5df2\u77e5 bug \u5168\u8bb0\u5f55\u3002 \u76ee\u5f55 \u5feb\u901f\u7ed3\u8bba&#xff08;30 \u79d2\u7248&#xff09;\u6d4b\u8bd5\u65b9\u6cd5&#xff08;\u5b8c\u6574\u7248&#xff09; \u6d4b\u8bd5\u9898\u539f\u6587 \/ \u7edf\u4e00\u73af\u5883 \/ \u6267\u884c\u547d\u4ee4 \/ \u5224\u5b9a\u6807\u51c6 \/ \u5c40\u9650\u4e0e\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/90246.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-04T14:32:40+00:00\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"51 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/90246.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/90246.html\",\"name\":\"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-08-04T14:32:40+00:00\",\"dateModified\":\"2026-08-04T14:32:40+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/90246.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/90246.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/90246.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/90246.html","og_locale":"zh_CN","og_type":"article","og_title":"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"AI \u7f16\u7a0b\u5de5\u5177\u6a2a\u8bc4\u5b9e\u6d4b\u62a5\u544a&#xff08;2026-08-04&#xff09; 7 \u6b3e AI \u7f16\u7a0b\u5de5\u5177&#xff0c;\u540c\u4e00\u6a21\u578b&#xff08;deepseek-v4-flash&#xff09;\u3001\u540c\u4e00\u6d4b\u8bd5\u9898\u3001\u540c\u4e00\u7f51\u5173\u5e76\u884c\u5b9e\u6d4b\u3002 \u9644\u5e26 token \u6d88\u8017\u5bf9\u6bd4 \u4ee3\u7801\u8d28\u91cf \u901f\u5ea6 \u6613\u7528\u6027 \u5df2\u77e5 bug \u5168\u8bb0\u5f55\u3002 \u76ee\u5f55 \u5feb\u901f\u7ed3\u8bba&#xff08;30 \u79d2\u7248&#xff09;\u6d4b\u8bd5\u65b9\u6cd5&#xff08;\u5b8c\u6574\u7248&#xff09; \u6d4b\u8bd5\u9898\u539f\u6587 \/ \u7edf\u4e00\u73af\u5883 \/ \u6267\u884c\u547d\u4ee4 \/ \u5224\u5b9a\u6807\u51c6 \/ \u5c40\u9650\u4e0e","og_url":"https:\/\/www.wsisp.com\/helps\/90246.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-08-04T14:32:40+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"51 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/90246.html","url":"https:\/\/www.wsisp.com\/helps\/90246.html","name":"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-08-04T14:32:40+00:00","dateModified":"2026-08-04T14:32:40+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/90246.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/90246.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/90246.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u5b9e\u6218\u6a2a\u8bc4\u3011\u4e3b\u6d41 AI \u7f16\u7a0b\u5de5\u5177\u5b9e\u6d4b\u5bf9\u6bd4\uff0c\u770b\u5b8c\u4e0d\u518d\u76f2\u76ee\u9009\u578b"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/90246","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=90246"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/90246\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=90246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=90246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=90246"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=90246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}