[{"data":1,"prerenderedAt":1908},["ShallowReactive",2],{"navigation":3,"posts-undefined-Python-0-999":20},[4,8,12,16],{"title":5,"path":6,"stem":7},"首页","\u002F","00.index",{"title":9,"path":10,"stem":11},"文章","\u002Fposts","01.posts",{"title":13,"path":14,"stem":15},"动态","\u002Fmoments","02.moments",{"title":17,"path":18,"stem":19},"关于","\u002Fabout","09.about",[21,707,1159],{"id":22,"title":23,"body":24,"class":687,"cover":688,"coverSize":687,"date":689,"description":30,"draft":690,"extension":691,"hideComments":690,"location":687,"meta":692,"navigation":70,"path":693,"readingTime":694,"seo":699,"sitemap":700,"stem":701,"tags":702,"time":687,"weather":687,"__hash__":706},"posts\u002Fposts\u002F2023\u002F20230423.gitlab-ci-auto-deploy-python-lib.md","GitLab CI 配置自动化打包上传 Python 库",{"type":25,"value":26,"toc":685},"minimark",[27,31,43,437,443,571,590,607,610,681],[28,29,30],"p",{},"自己之前有些 python 脚本类的项目，会用到一些通用的能力，如读取配置、打日志等，每次都 copy 一份 utils 目录有些不够优雅，于是撸了一个公共库，方便自己使用。",[28,32,33,34,38,39,42],{},"为了能配合 GitLab CI，",[35,36,37],"code",{},"setup.py"," 需要做一些小调整，版本号不需要手动输入了，直接读取 ",[35,40,41],{},"$CI_COMMIT_TAG","，代码如下：",[44,45,50],"pre",{"className":46,"code":47,"language":48,"meta":49,"style":49},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","import os\n\nimport setuptools\n\nwith open(\"README.md\", \"r\") as fh:\n    long_description = fh.read()\n\nsetuptools.setup(\n    name=\"yuanfen\",\n    version=os.environ.get(\"CI_COMMIT_TAG\", \"0.0.0\"),\n    author=\"Bean\",\n    author_email=\"bean@yuanfen.net\",\n    description=\"Yuanfen Python Library\",\n    long_description=long_description,\n    long_description_content_type=\"text\u002Fmarkdown\",\n    url=\"\",\n    install_requires=[\"pyyaml\", \"watchdog\"],\n    packages=setuptools.find_packages(),\n    classifiers=[\n        \"Programming Language :: Python :: 3\",\n        \"License :: OSI Approved :: MIT License\",\n        \"Operating System :: OS Independent\",\n    ],\n)\n\n","python","",[35,51,52,65,72,80,85,132,154,159,173,192,235,252,269,286,299,316,329,359,377,388,401,413,425,431],{"__ignoreMap":49},[53,54,57,61],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sVHd0","import",[53,62,64],{"class":63},"su5hD"," os\n",[53,66,68],{"class":55,"line":67},2,[53,69,71],{"emptyLinePlaceholder":70},true,"\n",[53,73,75,77],{"class":55,"line":74},3,[53,76,60],{"class":59},[53,78,79],{"class":63}," setuptools\n",[53,81,83],{"class":55,"line":82},4,[53,84,71],{"emptyLinePlaceholder":70},[53,86,88,91,95,99,103,107,109,112,115,118,120,123,126,129],{"class":55,"line":87},5,[53,89,90],{"class":59},"with",[53,92,94],{"class":93},"sptTA"," open",[53,96,98],{"class":97},"sP7_E","(",[53,100,102],{"class":101},"sjJ54","\"",[53,104,106],{"class":105},"s_sjI","README.md",[53,108,102],{"class":101},[53,110,111],{"class":97},",",[53,113,114],{"class":101}," \"",[53,116,117],{"class":105},"r",[53,119,102],{"class":101},[53,121,122],{"class":97},")",[53,124,125],{"class":59}," as",[53,127,128],{"class":63}," fh",[53,130,131],{"class":97},":\n",[53,133,135,138,142,144,147,151],{"class":55,"line":134},6,[53,136,137],{"class":63},"    long_description ",[53,139,141],{"class":140},"smGrS","=",[53,143,128],{"class":63},[53,145,146],{"class":97},".",[53,148,150],{"class":149},"slqww","read",[53,152,153],{"class":97},"()\n",[53,155,157],{"class":55,"line":156},7,[53,158,71],{"emptyLinePlaceholder":70},[53,160,162,165,167,170],{"class":55,"line":161},8,[53,163,164],{"class":63},"setuptools",[53,166,146],{"class":97},[53,168,169],{"class":149},"setup",[53,171,172],{"class":97},"(\n",[53,174,176,180,182,184,187,189],{"class":55,"line":175},9,[53,177,179],{"class":178},"s99_P","    name",[53,181,141],{"class":140},[53,183,102],{"class":101},[53,185,186],{"class":105},"yuanfen",[53,188,102],{"class":101},[53,190,191],{"class":97},",\n",[53,193,195,198,200,203,205,209,211,214,216,218,221,223,225,227,230,232],{"class":55,"line":194},10,[53,196,197],{"class":178},"    version",[53,199,141],{"class":140},[53,201,202],{"class":149},"os",[53,204,146],{"class":97},[53,206,208],{"class":207},"skxfh","environ",[53,210,146],{"class":97},[53,212,213],{"class":149},"get",[53,215,98],{"class":97},[53,217,102],{"class":101},[53,219,220],{"class":105},"CI_COMMIT_TAG",[53,222,102],{"class":101},[53,224,111],{"class":97},[53,226,114],{"class":101},[53,228,229],{"class":105},"0.0.0",[53,231,102],{"class":101},[53,233,234],{"class":97},"),\n",[53,236,238,241,243,245,248,250],{"class":55,"line":237},11,[53,239,240],{"class":178},"    author",[53,242,141],{"class":140},[53,244,102],{"class":101},[53,246,247],{"class":105},"Bean",[53,249,102],{"class":101},[53,251,191],{"class":97},[53,253,255,258,260,262,265,267],{"class":55,"line":254},12,[53,256,257],{"class":178},"    author_email",[53,259,141],{"class":140},[53,261,102],{"class":101},[53,263,264],{"class":105},"bean@yuanfen.net",[53,266,102],{"class":101},[53,268,191],{"class":97},[53,270,272,275,277,279,282,284],{"class":55,"line":271},13,[53,273,274],{"class":178},"    description",[53,276,141],{"class":140},[53,278,102],{"class":101},[53,280,281],{"class":105},"Yuanfen Python Library",[53,283,102],{"class":101},[53,285,191],{"class":97},[53,287,289,292,294,297],{"class":55,"line":288},14,[53,290,291],{"class":178},"    long_description",[53,293,141],{"class":140},[53,295,296],{"class":149},"long_description",[53,298,191],{"class":97},[53,300,302,305,307,309,312,314],{"class":55,"line":301},15,[53,303,304],{"class":178},"    long_description_content_type",[53,306,141],{"class":140},[53,308,102],{"class":101},[53,310,311],{"class":105},"text\u002Fmarkdown",[53,313,102],{"class":101},[53,315,191],{"class":97},[53,317,319,322,324,327],{"class":55,"line":318},16,[53,320,321],{"class":178},"    url",[53,323,141],{"class":140},[53,325,326],{"class":101},"\"\"",[53,328,191],{"class":97},[53,330,332,335,337,340,342,345,347,349,351,354,356],{"class":55,"line":331},17,[53,333,334],{"class":178},"    install_requires",[53,336,141],{"class":140},[53,338,339],{"class":97},"[",[53,341,102],{"class":101},[53,343,344],{"class":105},"pyyaml",[53,346,102],{"class":101},[53,348,111],{"class":97},[53,350,114],{"class":101},[53,352,353],{"class":105},"watchdog",[53,355,102],{"class":101},[53,357,358],{"class":97},"],\n",[53,360,362,365,367,369,371,374],{"class":55,"line":361},18,[53,363,364],{"class":178},"    packages",[53,366,141],{"class":140},[53,368,164],{"class":149},[53,370,146],{"class":97},[53,372,373],{"class":149},"find_packages",[53,375,376],{"class":97},"(),\n",[53,378,380,383,385],{"class":55,"line":379},19,[53,381,382],{"class":178},"    classifiers",[53,384,141],{"class":140},[53,386,387],{"class":97},"[\n",[53,389,391,394,397,399],{"class":55,"line":390},20,[53,392,393],{"class":101},"        \"",[53,395,396],{"class":105},"Programming Language :: Python :: 3",[53,398,102],{"class":101},[53,400,191],{"class":97},[53,402,404,406,409,411],{"class":55,"line":403},21,[53,405,393],{"class":101},[53,407,408],{"class":105},"License :: OSI Approved :: MIT License",[53,410,102],{"class":101},[53,412,191],{"class":97},[53,414,416,418,421,423],{"class":55,"line":415},22,[53,417,393],{"class":101},[53,419,420],{"class":105},"Operating System :: OS Independent",[53,422,102],{"class":101},[53,424,191],{"class":97},[53,426,428],{"class":55,"line":427},23,[53,429,430],{"class":97},"    ],\n",[53,432,434],{"class":55,"line":433},24,[53,435,436],{"class":97},")\n",[28,438,439,442],{},[35,440,441],{},".gitlab-ci.yml"," 代码如下：",[44,444,448],{"className":445,"code":446,"language":447,"meta":49,"style":49},"language-yaml shiki shiki-themes material-theme-lighter github-light github-dark","image: python:3\n\nstages:\n  - deploy\n\ndeploy:\n  stage: deploy\n  variables:\n    TWINE_USERNAME: $TWINE_USERNAME\n    TWINE_PASSWORD: $TWINE_PASSWORD\n  script:\n    - python setup.py sdist bdist_wheel\n    - pip install twine -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n    - twine upload dist\u002F*\n  only:\n    - tags\n","yaml",[35,449,450,462,466,473,481,485,492,501,508,518,528,535,543,550,557,564],{"__ignoreMap":49},[53,451,452,456,459],{"class":55,"line":56},[53,453,455],{"class":454},"sQzsp","image",[53,457,458],{"class":97},":",[53,460,461],{"class":105}," python:3\n",[53,463,464],{"class":55,"line":67},[53,465,71],{"emptyLinePlaceholder":70},[53,467,468,471],{"class":55,"line":74},[53,469,470],{"class":454},"stages",[53,472,131],{"class":97},[53,474,475,478],{"class":55,"line":82},[53,476,477],{"class":97},"  -",[53,479,480],{"class":105}," deploy\n",[53,482,483],{"class":55,"line":87},[53,484,71],{"emptyLinePlaceholder":70},[53,486,487,490],{"class":55,"line":134},[53,488,489],{"class":454},"deploy",[53,491,131],{"class":97},[53,493,494,497,499],{"class":55,"line":156},[53,495,496],{"class":454},"  stage",[53,498,458],{"class":97},[53,500,480],{"class":105},[53,502,503,506],{"class":55,"line":161},[53,504,505],{"class":454},"  variables",[53,507,131],{"class":97},[53,509,510,513,515],{"class":55,"line":175},[53,511,512],{"class":454},"    TWINE_USERNAME",[53,514,458],{"class":97},[53,516,517],{"class":105}," $TWINE_USERNAME\n",[53,519,520,523,525],{"class":55,"line":194},[53,521,522],{"class":454},"    TWINE_PASSWORD",[53,524,458],{"class":97},[53,526,527],{"class":105}," $TWINE_PASSWORD\n",[53,529,530,533],{"class":55,"line":237},[53,531,532],{"class":454},"  script",[53,534,131],{"class":97},[53,536,537,540],{"class":55,"line":254},[53,538,539],{"class":97},"    -",[53,541,542],{"class":105}," python setup.py sdist bdist_wheel\n",[53,544,545,547],{"class":55,"line":271},[53,546,539],{"class":97},[53,548,549],{"class":105}," pip install twine -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n",[53,551,552,554],{"class":55,"line":288},[53,553,539],{"class":97},[53,555,556],{"class":105}," twine upload dist\u002F*\n",[53,558,559,562],{"class":55,"line":301},[53,560,561],{"class":454},"  only",[53,563,131],{"class":97},[53,565,566,568],{"class":55,"line":318},[53,567,539],{"class":97},[53,569,570],{"class":105}," tags\n",[28,572,573,574,577,578,581,582,585,586,589],{},"其中，需要在 GitLab 项目 ",[35,575,576],{},"Setting -> CI\u002FCD -> Variables"," 中配置 ",[35,579,580],{},"TWINE_USERNAME"," 和 ",[35,583,584],{},"TWINE_PASSWORD","，这个是你在 ",[35,587,588],{},"pypi.org"," 上的用户名和密码。",[28,591,592,593,595,596,599,600,603,604,606],{},"另外需要注意的是，仓库的目录结构，",[35,594,37],{}," 中指定的 ",[35,597,598],{},"name"," 是包名，而 ",[35,601,602],{},"__init__.py"," 所在的文件夹名是实际 ",[35,605,60],{}," 的导入名。上传包时，PyPI 会检查报名是否重复，但不会检查导入名，所以如果定义了一个容易导致重复的导入名的话，就有可能有冲突。所以一般情况下该文件夹尽量是与包名统一，这样不容易有冲突。",[28,608,609],{},"以下是 ChatGPT 给出的目录结构的建议：",[611,612,613,616,624,643,649,655,664,669,675],"blockquote",{},[28,614,615],{},"当你创建一个 Python 库时，通常需要遵循一些标准的目录结构和文件命名规范。下面是一个常见的建议目录结构，包括了一些常见文件和目录：",[44,617,622],{"className":618,"code":620,"language":621},[619],"language-text","your_library\u002F\n   your_library\u002F\n       __init__.py\n       module1.py\n       module2.py\n       ...\n   examples\u002F\n       example1.py\n       example2.py\n       ...\n   tests\u002F\n       test_module1.py\n       test_module2.py\n       ...\n   README.md\n   LICENSE\n   setup.py\n   requirements.txt\n   .gitignore\n\n","text",[35,623,620],{"__ignoreMap":49},[28,625,626,627,630,631,633,634,636,637,639,640,642],{},"在这个目录结构中，",[35,628,629],{},"your_library"," 是你的库的名称，它应该与 ",[35,632,37],{}," 文件中定义的名称相同。",[35,635,629],{}," 目录包含了你的库的所有源代码和模块文件，以及 ",[35,638,602],{}," 文件，用于将 ",[35,641,629],{}," 目录转换为 Python 包。",[28,644,645,648],{},[35,646,647],{},"examples"," 目录包含了一些示例代码，用于演示如何使用你的库。这些示例代码可以帮助用户更快地了解和使用你的库。",[28,650,651,654],{},[35,652,653],{},"tests"," 目录包含了单元测试和集成测试代码，用于确保你的库的功能和质量。在这个目录中，你可以为每个模块编写一个或多个测试文件，并使用测试框架运行这些测试。",[28,656,657,659,660,663],{},[35,658,106],{}," 文件是你的库的说明文档，用于介绍你的库的功能、用法和示例。",[35,661,662],{},"LICENSE"," 文件包含了你的库的许可证信息，用于明确你的库的使用和分发条件。",[28,665,666,668],{},[35,667,37],{}," 文件是你的库的安装脚本，用于将你的库安装到 Python 环境中。在这个文件中，你需要指定库的名称、版本、作者、描述、依赖等信息。",[28,670,671,674],{},[35,672,673],{},"requirements.txt"," 文件包含了你的库依赖的其他 Python 包的名称和版本号。在使用 pip 安装你的库时，pip 将自动安装这些依赖包。",[28,676,677,680],{},[35,678,679],{},".gitignore"," 文件是 Git 版本控制系统的忽略文件，用于指定哪些文件或目录不需要被 Git 跟踪和提交。",[682,683,684],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":49,"searchDepth":67,"depth":67,"links":686},[],null,"jpg","2023-04-23",false,"md",{},"\u002Fposts\u002F2023\u002Fgitlab-ci-auto-deploy-python-lib",{"text":695,"minutes":696,"time":697,"words":698},"4 min read",3.835,230100,767,{"title":23,"description":30},{"loc":693},"posts\u002F2023\u002F20230423.gitlab-ci-auto-deploy-python-lib",[703,704,705],"技术","DevOps","Python","o6Yb6IDvjBzm2kTY_GeQKG92soCUwh_mh3f6D78Xm-s",{"id":708,"title":709,"body":710,"class":687,"cover":688,"coverSize":687,"date":689,"description":714,"draft":690,"extension":691,"hideComments":690,"location":687,"meta":1147,"navigation":70,"path":1148,"readingTime":1149,"seo":1154,"sitemap":1155,"stem":1156,"tags":1157,"time":687,"weather":687,"__hash__":1158},"posts\u002Fposts\u002F2023\u002F20230423.timedrotatingfilehandler-backupcount-problem.md","TimedRotatingFileHandler 不会自动清除旧日志的问题",{"type":25,"value":711,"toc":1145},[712,715,836,846,1052,1062,1073,1076,1126,1129,1142],[28,713,714],{},"话不多说，直接贴代码：",[44,716,718],{"className":46,"code":717,"language":48,"meta":49,"style":49},"file_handler = TimedRotatingFileHandler(\n    \"logs\u002Flog\",\n    when=\"midnight\",\n    backupCount=365,\n    encoding=\"utf-8\",\n)\nfile_handler.suffix = \"%Y%m%d.log\"\nfile_handler.setFormatter(log_formatter)\n",[35,719,720,732,744,760,773,789,793,820],{"__ignoreMap":49},[53,721,722,725,727,730],{"class":55,"line":56},[53,723,724],{"class":63},"file_handler ",[53,726,141],{"class":140},[53,728,729],{"class":149}," TimedRotatingFileHandler",[53,731,172],{"class":97},[53,733,734,737,740,742],{"class":55,"line":67},[53,735,736],{"class":101},"    \"",[53,738,739],{"class":105},"logs\u002Flog",[53,741,102],{"class":101},[53,743,191],{"class":97},[53,745,746,749,751,753,756,758],{"class":55,"line":74},[53,747,748],{"class":178},"    when",[53,750,141],{"class":140},[53,752,102],{"class":101},[53,754,755],{"class":105},"midnight",[53,757,102],{"class":101},[53,759,191],{"class":97},[53,761,762,765,767,771],{"class":55,"line":82},[53,763,764],{"class":178},"    backupCount",[53,766,141],{"class":140},[53,768,770],{"class":769},"srdBf","365",[53,772,191],{"class":97},[53,774,775,778,780,782,785,787],{"class":55,"line":87},[53,776,777],{"class":178},"    encoding",[53,779,141],{"class":140},[53,781,102],{"class":101},[53,783,784],{"class":105},"utf-8",[53,786,102],{"class":101},[53,788,191],{"class":97},[53,790,791],{"class":55,"line":134},[53,792,436],{"class":97},[53,794,795,798,800,803,806,808,811,814,817],{"class":55,"line":156},[53,796,797],{"class":63},"file_handler",[53,799,146],{"class":97},[53,801,802],{"class":207},"suffix",[53,804,805],{"class":140}," =",[53,807,114],{"class":101},[53,809,810],{"class":105},"%Y%m",[53,812,813],{"class":769},"%d",[53,815,816],{"class":105},".log",[53,818,819],{"class":101},"\"\n",[53,821,822,824,826,829,831,834],{"class":55,"line":161},[53,823,797],{"class":63},[53,825,146],{"class":97},[53,827,828],{"class":149},"setFormatter",[53,830,98],{"class":97},[53,832,833],{"class":149},"log_formatter",[53,835,436],{"class":97},[28,837,838,839,842,843,845],{},"这是我几年前写的一段写日志文件的代码，前几天发现并没有按照预期只保留 365 个日志文件。研究了一下，发现了问题所在。",[35,840,841],{},"TimedRotatingFileHandler"," 中对于 ",[35,844,755],{}," 的操作是这样的：",[44,847,849],{"className":46,"code":848,"language":48,"meta":49,"style":49},"elif self.when == 'D' or self.when == 'MIDNIGHT':\n    self.interval = 60 * 60 * 24 # one day\n    self.suffix = \"%Y-%m-%d\"\n    self.extMatch = r\"^\\d{4}-\\d{2}-\\d{2}(\\.\\w+)?$\"\n# ... other code\nself.extMatch = re.compile(self.extMatch, re.ASCII)\n",[35,850,851,897,926,945,1008,1013],{"__ignoreMap":49},[53,852,853,856,860,862,865,868,871,874,877,880,882,884,886,888,890,893,895],{"class":55,"line":56},[53,854,855],{"class":59},"elif",[53,857,859],{"class":858},"s_hVV"," self",[53,861,146],{"class":97},[53,863,864],{"class":207},"when",[53,866,867],{"class":140}," ==",[53,869,870],{"class":101}," '",[53,872,873],{"class":105},"D",[53,875,876],{"class":101},"'",[53,878,879],{"class":140}," or",[53,881,859],{"class":858},[53,883,146],{"class":97},[53,885,864],{"class":207},[53,887,867],{"class":140},[53,889,870],{"class":101},[53,891,892],{"class":105},"MIDNIGHT",[53,894,876],{"class":101},[53,896,131],{"class":97},[53,898,899,902,904,907,909,912,915,917,919,922],{"class":55,"line":67},[53,900,901],{"class":858},"    self",[53,903,146],{"class":97},[53,905,906],{"class":207},"interval",[53,908,805],{"class":140},[53,910,911],{"class":769}," 60",[53,913,914],{"class":140}," *",[53,916,911],{"class":769},[53,918,914],{"class":140},[53,920,921],{"class":769}," 24",[53,923,925],{"class":924},"sutJx"," # one day\n",[53,927,928,930,932,934,936,938,941,943],{"class":55,"line":74},[53,929,901],{"class":858},[53,931,146],{"class":97},[53,933,802],{"class":207},[53,935,805],{"class":140},[53,937,114],{"class":101},[53,939,940],{"class":105},"%Y-%m-",[53,942,813],{"class":769},[53,944,819],{"class":101},[53,946,947,949,951,954,956,960,962,966,969,973,976,979,981,983,985,988,992,995,998,1000,1003,1006],{"class":55,"line":82},[53,948,901],{"class":858},[53,950,146],{"class":97},[53,952,953],{"class":207},"extMatch",[53,955,805],{"class":140},[53,957,959],{"class":958},"sbsja"," r",[53,961,102],{"class":101},[53,963,965],{"class":964},"stzsN","^\\d",[53,967,968],{"class":140},"{4}",[53,970,972],{"class":971},"sQRbd","-",[53,974,975],{"class":964},"\\d",[53,977,978],{"class":140},"{2}",[53,980,972],{"class":971},[53,982,975],{"class":964},[53,984,978],{"class":140},[53,986,98],{"class":987},"s39Yj",[53,989,991],{"class":990},"sjYin","\\.",[53,993,994],{"class":964},"\\w",[53,996,997],{"class":140},"+",[53,999,122],{"class":987},[53,1001,1002],{"class":140},"?",[53,1004,1005],{"class":964},"$",[53,1007,819],{"class":101},[53,1009,1010],{"class":55,"line":87},[53,1011,1012],{"class":924},"# ... other code\n",[53,1014,1015,1018,1020,1022,1024,1027,1029,1032,1034,1036,1038,1040,1042,1044,1046,1050],{"class":55,"line":134},[53,1016,1017],{"class":858},"self",[53,1019,146],{"class":97},[53,1021,953],{"class":207},[53,1023,805],{"class":140},[53,1025,1026],{"class":63}," re",[53,1028,146],{"class":97},[53,1030,1031],{"class":149},"compile",[53,1033,98],{"class":97},[53,1035,1017],{"class":858},[53,1037,146],{"class":97},[53,1039,953],{"class":207},[53,1041,111],{"class":97},[53,1043,1026],{"class":149},[53,1045,146],{"class":97},[53,1047,1049],{"class":1048},"swQdS","ASCII",[53,1051,436],{"class":97},[28,1053,1054,1055,1058,1059,1061],{},"可以看到，其默认的 suffix 是 ",[35,1056,1057],{},"%Y-%m-%d","，我之所以要加 ",[35,1060,816],{}," 后缀，是因为如果不带后缀的话，群晖的文本编辑器默认不能直接打开这个文件，不太方便看日志。",[28,1063,1064,1065,1068,1069,1072],{},"它默认的匹配正则是 ",[35,1066,1067],{},"r\"^\\d{4}-\\d{2}-\\d{2}(\\.\\w+)?$\"","，当我把 suffix 改成 ",[35,1070,1071],{},"%Y%m%d.log"," 之后，它就无法匹配到旧日志的数量了，所以保留日志个数的功能会失效。有两种办法解决：",[28,1074,1075],{},"一是加一行：",[44,1077,1079],{"className":46,"code":1078,"language":48,"meta":49,"style":49},"self.extMatch = re.compile(r\"^\\d{4}\\d{2}\\d{2}\\.log$\")\n",[35,1080,1081],{"__ignoreMap":49},[53,1082,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1120,1122,1124],{"class":55,"line":56},[53,1084,1017],{"class":858},[53,1086,146],{"class":97},[53,1088,953],{"class":207},[53,1090,805],{"class":140},[53,1092,1026],{"class":63},[53,1094,146],{"class":97},[53,1096,1031],{"class":149},[53,1098,98],{"class":97},[53,1100,117],{"class":958},[53,1102,102],{"class":101},[53,1104,965],{"class":964},[53,1106,968],{"class":140},[53,1108,975],{"class":964},[53,1110,978],{"class":140},[53,1112,975],{"class":964},[53,1114,978],{"class":140},[53,1116,991],{"class":990},[53,1118,1119],{"class":971},"log",[53,1121,1005],{"class":964},[53,1123,102],{"class":101},[53,1125,436],{"class":97},[28,1127,1128],{},"另一种更简单：",[28,1130,1131,1132,1134,1135,1138,1139,1141],{},"把 ",[35,1133,802],{}," 改成 ",[35,1136,1137],{},"%Y-%m-%d.log"," 即可，因为默认的 ",[35,1140,953],{}," 是可以匹配到后缀名的。",[682,1143,1144],{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sQRbd, html code.shiki .sQRbd{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjYin, html code.shiki .sjYin{--shiki-light:#90A4AE;--shiki-light-font-weight:inherit;--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}html pre.shiki code .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":49,"searchDepth":67,"depth":67,"links":1146},[],{},"\u002Fposts\u002F2023\u002Ftimedrotatingfilehandler-backupcount-problem",{"text":1150,"minutes":1151,"time":1152,"words":1153},"2 min read",1.28,76800,256,{"title":709,"description":714},{"loc":1148},"posts\u002F2023\u002F20230423.timedrotatingfilehandler-backupcount-problem",[703,705],"4wede-nsE8KJljBACI9w26cVkEu6w_4hgpuuTibyohw",{"id":1160,"title":1161,"body":1162,"class":687,"cover":1894,"coverSize":687,"date":1895,"description":1166,"draft":690,"extension":691,"hideComments":690,"location":687,"meta":1896,"navigation":70,"path":1897,"readingTime":1898,"seo":1903,"sitemap":1904,"stem":1905,"tags":1906,"time":687,"weather":687,"__hash__":1907},"posts\u002Fposts\u002F2019\u002F20190719.solve-pycharm-adding-pipenv-error.md","解决 PyCharm 设置 pipenv 报错的问题",{"type":25,"value":1163,"toc":1892},[1164,1167,1385,1389,1392,1395,1848,1859,1866,1886,1889],[28,1165,1166],{},"使用 PyCharm 添加 pipenv 会报如下错误：",[44,1168,1171],{"className":1169,"code":1170,"language":1119,"meta":49,"style":49},"language-log shiki shiki-themes material-theme-lighter github-light github-dark","Executed command:\n\u002Fusr\u002Flocal\u002Fbin\u002Fpipenv --python \u002Fusr\u002Flocal\u002Fbin\u002Fpython3.6 install --dev\n\nError occurred:\nError Running Pipenv\n\nCommand output:\nTraceback (most recent call last):\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpipenv\u002F2018.11.26_2\u002Flibexec\u002Fbin\u002Fpipenv\", line 6, in \u003Cmodule>\n    from pkg_resources import load_entry_point\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\", line 3241, in \u003Cmodule>\n    @_call_aside\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\", line 3225, in _call_aside\n    f(*args, **kwargs)\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\", line 3254, in _initialize_master_working_set\n    working_set = WorkingSet._build_master()\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\", line 583, in _build_master\n    ws.require(__requires__)\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\", line 900, in require\n    needed = self.resolve(parse_requirements(requirements))\n  File \"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\", line 786, in resolve\n    raise DistributionNotFound(req, requirers)\npkg_resources.DistributionNotFound: The 'pipenv==2018.11.26' distribution was not found and is required by the application\n\n",[35,1172,1173,1178,1189,1193,1201,1208,1212,1217,1222,1238,1243,1257,1262,1276,1281,1295,1305,1319,1327,1341,1352,1366,1371],{"__ignoreMap":49},[53,1174,1175],{"class":55,"line":56},[53,1176,1177],{"class":63},"Executed command:\n",[53,1179,1180,1183,1186],{"class":55,"line":67},[53,1181,1182],{"class":63},"\u002Fusr\u002Flocal\u002Fbin\u002Fpipenv --python \u002Fusr\u002Flocal\u002Fbin\u002Fpython3.",[53,1184,1185],{"class":987},"6",[53,1187,1188],{"class":63}," install --dev\n",[53,1190,1191],{"class":55,"line":74},[53,1192,71],{"emptyLinePlaceholder":70},[53,1194,1195,1198],{"class":55,"line":82},[53,1196,1197],{"class":105},"Error",[53,1199,1200],{"class":63}," occurred:\n",[53,1202,1203,1205],{"class":55,"line":87},[53,1204,1197],{"class":105},[53,1206,1207],{"class":63}," Running Pipenv\n",[53,1209,1210],{"class":55,"line":134},[53,1211,71],{"emptyLinePlaceholder":70},[53,1213,1214],{"class":55,"line":156},[53,1215,1216],{"class":63},"Command output:\n",[53,1218,1219],{"class":55,"line":161},[53,1220,1221],{"class":63},"Traceback (most recent call last):\n",[53,1223,1224,1227,1230,1233,1235],{"class":55,"line":175},[53,1225,1226],{"class":63},"  File ",[53,1228,1229],{"class":105},"\"\u002Fusr\u002Flocal\u002FCellar\u002Fpipenv\u002F2018.11.26_2\u002Flibexec\u002Fbin\u002Fpipenv\"",[53,1231,1232],{"class":63},", line ",[53,1234,1185],{"class":987},[53,1236,1237],{"class":63},", in \u003Cmodule>\n",[53,1239,1240],{"class":55,"line":194},[53,1241,1242],{"class":63},"    from pkg_resources import load_entry_point\n",[53,1244,1245,1247,1250,1252,1255],{"class":55,"line":237},[53,1246,1226],{"class":63},[53,1248,1249],{"class":105},"\"\u002Fusr\u002Flocal\u002FCellar\u002Fpython\u002F3.7.3\u002FFrameworks\u002FPython.framework\u002FVersions\u002F3.7\u002Flib\u002Fpython3.7\u002Fsite-packages\u002Fpkg_resources\u002F__init__.py\"",[53,1251,1232],{"class":63},[53,1253,1254],{"class":987},"3241",[53,1256,1237],{"class":63},[53,1258,1259],{"class":55,"line":254},[53,1260,1261],{"class":63},"    @_call_aside\n",[53,1263,1264,1266,1268,1270,1273],{"class":55,"line":271},[53,1265,1226],{"class":63},[53,1267,1249],{"class":105},[53,1269,1232],{"class":63},[53,1271,1272],{"class":987},"3225",[53,1274,1275],{"class":63},", in _call_aside\n",[53,1277,1278],{"class":55,"line":288},[53,1279,1280],{"class":63},"    f(*args, **kwargs)\n",[53,1282,1283,1285,1287,1289,1292],{"class":55,"line":301},[53,1284,1226],{"class":63},[53,1286,1249],{"class":105},[53,1288,1232],{"class":63},[53,1290,1291],{"class":987},"3254",[53,1293,1294],{"class":63},", in _initialize_master_working_set\n",[53,1296,1297,1300,1303],{"class":55,"line":318},[53,1298,1299],{"class":63},"    working_set = ",[53,1301,1302],{"class":987},"WorkingSet._build_master",[53,1304,153],{"class":63},[53,1306,1307,1309,1311,1313,1316],{"class":55,"line":331},[53,1308,1226],{"class":63},[53,1310,1249],{"class":105},[53,1312,1232],{"class":63},[53,1314,1315],{"class":987},"583",[53,1317,1318],{"class":63},", in _build_master\n",[53,1320,1321,1324],{"class":55,"line":361},[53,1322,1323],{"class":987},"    ws.require",[53,1325,1326],{"class":63},"(__requires__)\n",[53,1328,1329,1331,1333,1335,1338],{"class":55,"line":379},[53,1330,1226],{"class":63},[53,1332,1249],{"class":105},[53,1334,1232],{"class":63},[53,1336,1337],{"class":987},"900",[53,1339,1340],{"class":63},", in require\n",[53,1342,1343,1346,1349],{"class":55,"line":390},[53,1344,1345],{"class":63},"    needed = ",[53,1347,1348],{"class":987},"self.resolve",[53,1350,1351],{"class":63},"(parse_requirements(requirements))\n",[53,1353,1354,1356,1358,1360,1363],{"class":55,"line":403},[53,1355,1226],{"class":63},[53,1357,1249],{"class":105},[53,1359,1232],{"class":63},[53,1361,1362],{"class":987},"786",[53,1364,1365],{"class":63},", in resolve\n",[53,1367,1368],{"class":55,"line":415},[53,1369,1370],{"class":63},"    raise DistributionNotFound(req, requirers)\n",[53,1372,1373,1376,1379,1382],{"class":55,"line":427},[53,1374,1375],{"class":987},"pkg_resources.DistributionNotFound",[53,1377,1378],{"class":63},": The ",[53,1380,1381],{"class":105},"'pipenv==2018.11.26'",[53,1383,1384],{"class":63}," distribution was not found and is required by the application\n",[1386,1387],"post-image",{"filename":1388},"01.png",[28,1390,1391],{},"这个问题是因为系统同时存在 Python 3.6 和 Python 3.7 导致的，查看了下，Homebrew 安装的 Python 3.7，而通过官网的 dmg 安装的 Python 3.6。我觉得这个与 PyCharm 内部的运行环境有关，即使我默认的已经是 Python 3.6 了，它不知为何依然调用了 Python 3.7 来执行。尝试卸掉了一个，发现这个问题解决了。",[28,1393,1394],{},"再次尝试，报了另外的错：",[44,1396,1398],{"className":1169,"code":1397,"language":1119,"meta":49,"style":49},"Executed command:\n\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Fbin\u002Fpipenv --python \u002Fusr\u002Flocal\u002Fbin\u002Fpython3.6 install --dev\n\nError occurred:\nRuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment. Consult https:\u002F\u002Fclick.palletsprojects.com\u002Fen\u002F7.x\u002Fpython3\u002F for mitigation steps.\n\nTraceback (most recent call last):\n  File \"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Fbin\u002Fpipenv\", line 10, in \u003Cmodule>\n    sys.exit(cli())\n  File \"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Flib\u002Fpython\u002Fsite-packages\u002Fpipenv\u002Fvendor\u002Fclick\u002Fcore.py\", line 764, in __call__\n    return self.main(*args, **kwargs)\n  File \"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Flib\u002Fpython\u002Fsite-packages\u002Fpipenv\u002Fvendor\u002Fclick\u002Fcore.py\", line 696, in main\n    _verify_python3_env()\n  File \"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Flib\u002Fpython\u002Fsite-packages\u002Fpipenv\u002Fvendor\u002Fclick\u002F_unicodefun.py\", line 124, in _verify_python3_env\n    ' mitigation steps.' + extra\nRuntimeError: Click will abort further execution because Python 3 was configured to use ASCII as encoding for the environment. Consult https:\u002F\u002Fclick.palletsprojects.com\u002Fen\u002F7.x\u002Fpython3\u002F for mitigation steps.\n\nThis system lists a couple of UTF-8 supporting locales that\nyou can pick from.  The following suitable locales were\ndiscovered: af_ZA.UTF-8, am_ET.UTF-8, be_BY.UTF-8, bg_BG.UTF-8, ca_ES.UTF-8, cs_CZ.UTF-8, da_DK.UTF-8, de_AT.UTF-8, de_CH.UTF-8, de_DE.UTF-8, el_GR.UTF-8, en_AU.UTF-8, en_CA.UTF-8, en_GB.UTF-8, en_IE.UTF-8, en_NZ.UTF-8, en_US.UTF-8, es_ES.UTF-8, et_EE.UTF-8, eu_ES.UTF-8, fi_FI.UTF-8, fr_BE.UTF-8, fr_CA.UTF-8, fr_CH.UTF-8, fr_FR.UTF-8, he_IL.UTF-8, hr_HR.UTF-8, hu_HU.UTF-8, hy_AM.UTF-8, is_IS.UTF-8, it_CH.UTF-8, it_IT.UTF-8, ja_JP.UTF-8, kk_KZ.UTF-8, ko_KR.UTF-8, lt_LT.UTF-8, nl_BE.UTF-8, nl_NL.UTF-8, no_NO.UTF-8, pl_PL.UTF-8, pt_BR.UTF-8, pt_PT.UTF-8, ro_RO.UTF-8, ru_RU.UTF-8, sk_SK.UTF-8, sl_SI.UTF-8, sr_YU.UTF-8, sv_SE.UTF-8, tr_TR.UTF-8, uk_UA.UTF-8, zh_CN.UTF-8, zh_HK.UTF-8, zh_TW.UTF-8\n\n",[35,1399,1400,1404,1423,1427,1433,1449,1453,1457,1471,1479,1494,1505,1519,1524,1539,1547,1559,1563,1574,1579],{"__ignoreMap":49},[53,1401,1402],{"class":55,"line":56},[53,1403,1177],{"class":63},[53,1405,1406,1409,1412,1414,1416,1419,1421],{"class":55,"line":67},[53,1407,1408],{"class":63},"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F",[53,1410,1411],{"class":987},"3",[53,1413,146],{"class":63},[53,1415,1185],{"class":987},[53,1417,1418],{"class":63},"\u002Fbin\u002Fpipenv --python \u002Fusr\u002Flocal\u002Fbin\u002Fpython3.",[53,1420,1185],{"class":987},[53,1422,1188],{"class":63},[53,1424,1425],{"class":55,"line":74},[53,1426,71],{"emptyLinePlaceholder":70},[53,1428,1429,1431],{"class":55,"line":82},[53,1430,1197],{"class":105},[53,1432,1200],{"class":63},[53,1434,1435,1438,1440,1443,1446],{"class":55,"line":87},[53,1436,1437],{"class":63},"RuntimeError: Click will abort further execution because Python ",[53,1439,1411],{"class":987},[53,1441,1442],{"class":63}," was configured to use ASCII as encoding for the environment. Consult ",[53,1444,1445],{"class":987},"https:\u002F\u002Fclick.palletsprojects.com\u002Fen\u002F7.x\u002Fpython3\u002F",[53,1447,1448],{"class":63}," for mitigation steps.\n",[53,1450,1451],{"class":55,"line":134},[53,1452,71],{"emptyLinePlaceholder":70},[53,1454,1455],{"class":55,"line":156},[53,1456,1221],{"class":63},[53,1458,1459,1461,1464,1466,1469],{"class":55,"line":161},[53,1460,1226],{"class":63},[53,1462,1463],{"class":105},"\"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Fbin\u002Fpipenv\"",[53,1465,1232],{"class":63},[53,1467,1468],{"class":987},"10",[53,1470,1237],{"class":63},[53,1472,1473,1476],{"class":55,"line":175},[53,1474,1475],{"class":987},"    sys.exit",[53,1477,1478],{"class":63},"(cli())\n",[53,1480,1481,1483,1486,1488,1491],{"class":55,"line":194},[53,1482,1226],{"class":63},[53,1484,1485],{"class":105},"\"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Flib\u002Fpython\u002Fsite-packages\u002Fpipenv\u002Fvendor\u002Fclick\u002Fcore.py\"",[53,1487,1232],{"class":63},[53,1489,1490],{"class":987},"764",[53,1492,1493],{"class":63},", in __call__\n",[53,1495,1496,1499,1502],{"class":55,"line":237},[53,1497,1498],{"class":63},"    return ",[53,1500,1501],{"class":987},"self.main",[53,1503,1504],{"class":63},"(*args, **kwargs)\n",[53,1506,1507,1509,1511,1513,1516],{"class":55,"line":254},[53,1508,1226],{"class":63},[53,1510,1485],{"class":105},[53,1512,1232],{"class":63},[53,1514,1515],{"class":987},"696",[53,1517,1518],{"class":63},", in main\n",[53,1520,1521],{"class":55,"line":271},[53,1522,1523],{"class":63},"    _verify_python3_env()\n",[53,1525,1526,1528,1531,1533,1536],{"class":55,"line":288},[53,1527,1226],{"class":63},[53,1529,1530],{"class":105},"\"\u002FUsers\u002Fbean\u002FLibrary\u002FPython\u002F3.6\u002Flib\u002Fpython\u002Fsite-packages\u002Fpipenv\u002Fvendor\u002Fclick\u002F_unicodefun.py\"",[53,1532,1232],{"class":63},[53,1534,1535],{"class":987},"124",[53,1537,1538],{"class":63},", in _verify_python3_env\n",[53,1540,1541,1544],{"class":55,"line":301},[53,1542,1543],{"class":105},"    ' mitigation steps.'",[53,1545,1546],{"class":63}," + extra\n",[53,1548,1549,1551,1553,1555,1557],{"class":55,"line":318},[53,1550,1437],{"class":63},[53,1552,1411],{"class":987},[53,1554,1442],{"class":63},[53,1556,1445],{"class":987},[53,1558,1448],{"class":63},[53,1560,1561],{"class":55,"line":331},[53,1562,71],{"emptyLinePlaceholder":70},[53,1564,1565,1568,1571],{"class":55,"line":361},[53,1566,1567],{"class":63},"This system lists a couple of UTF-",[53,1569,1570],{"class":987},"8",[53,1572,1573],{"class":63}," supporting locales that\n",[53,1575,1576],{"class":55,"line":379},[53,1577,1578],{"class":63},"you can pick from.  The following suitable locales were\n",[53,1580,1581,1584,1587,1590,1593,1595,1598,1600,1603,1605,1608,1610,1613,1615,1618,1620,1623,1625,1628,1630,1633,1635,1638,1640,1643,1645,1648,1650,1653,1655,1658,1660,1663,1665,1668,1670,1673,1675,1678,1680,1683,1685,1688,1690,1693,1695,1698,1700,1703,1705,1708,1710,1713,1715,1718,1720,1723,1725,1728,1730,1733,1735,1738,1740,1743,1745,1748,1750,1753,1755,1758,1760,1763,1765,1768,1770,1773,1775,1778,1780,1783,1785,1788,1790,1793,1795,1798,1800,1803,1805,1808,1810,1813,1815,1818,1820,1823,1825,1828,1830,1833,1835,1838,1840,1843,1845],{"class":55,"line":390},[53,1582,1583],{"class":63},"discovered: ",[53,1585,1586],{"class":987},"af_ZA.UTF-8",[53,1588,1589],{"class":63},", ",[53,1591,1592],{"class":987},"am_ET.UTF-8",[53,1594,1589],{"class":63},[53,1596,1597],{"class":987},"be_BY.UTF-8",[53,1599,1589],{"class":63},[53,1601,1602],{"class":987},"bg_BG.UTF-8",[53,1604,1589],{"class":63},[53,1606,1607],{"class":987},"ca_ES.UTF-8",[53,1609,1589],{"class":63},[53,1611,1612],{"class":987},"cs_CZ.UTF-8",[53,1614,1589],{"class":63},[53,1616,1617],{"class":987},"da_DK.UTF-8",[53,1619,1589],{"class":63},[53,1621,1622],{"class":987},"de_AT.UTF-8",[53,1624,1589],{"class":63},[53,1626,1627],{"class":987},"de_CH.UTF-8",[53,1629,1589],{"class":63},[53,1631,1632],{"class":987},"de_DE.UTF-8",[53,1634,1589],{"class":63},[53,1636,1637],{"class":987},"el_GR.UTF-8",[53,1639,1589],{"class":63},[53,1641,1642],{"class":987},"en_AU.UTF-8",[53,1644,1589],{"class":63},[53,1646,1647],{"class":987},"en_CA.UTF-8",[53,1649,1589],{"class":63},[53,1651,1652],{"class":987},"en_GB.UTF-8",[53,1654,1589],{"class":63},[53,1656,1657],{"class":987},"en_IE.UTF-8",[53,1659,1589],{"class":63},[53,1661,1662],{"class":987},"en_NZ.UTF-8",[53,1664,1589],{"class":63},[53,1666,1667],{"class":987},"en_US.UTF-8",[53,1669,1589],{"class":63},[53,1671,1672],{"class":987},"es_ES.UTF-8",[53,1674,1589],{"class":63},[53,1676,1677],{"class":987},"et_EE.UTF-8",[53,1679,1589],{"class":63},[53,1681,1682],{"class":987},"eu_ES.UTF-8",[53,1684,1589],{"class":63},[53,1686,1687],{"class":987},"fi_FI.UTF-8",[53,1689,1589],{"class":63},[53,1691,1692],{"class":987},"fr_BE.UTF-8",[53,1694,1589],{"class":63},[53,1696,1697],{"class":987},"fr_CA.UTF-8",[53,1699,1589],{"class":63},[53,1701,1702],{"class":987},"fr_CH.UTF-8",[53,1704,1589],{"class":63},[53,1706,1707],{"class":987},"fr_FR.UTF-8",[53,1709,1589],{"class":63},[53,1711,1712],{"class":987},"he_IL.UTF-8",[53,1714,1589],{"class":63},[53,1716,1717],{"class":987},"hr_HR.UTF-8",[53,1719,1589],{"class":63},[53,1721,1722],{"class":987},"hu_HU.UTF-8",[53,1724,1589],{"class":63},[53,1726,1727],{"class":987},"hy_AM.UTF-8",[53,1729,1589],{"class":63},[53,1731,1732],{"class":987},"is_IS.UTF-8",[53,1734,1589],{"class":63},[53,1736,1737],{"class":987},"it_CH.UTF-8",[53,1739,1589],{"class":63},[53,1741,1742],{"class":987},"it_IT.UTF-8",[53,1744,1589],{"class":63},[53,1746,1747],{"class":987},"ja_JP.UTF-8",[53,1749,1589],{"class":63},[53,1751,1752],{"class":987},"kk_KZ.UTF-8",[53,1754,1589],{"class":63},[53,1756,1757],{"class":987},"ko_KR.UTF-8",[53,1759,1589],{"class":63},[53,1761,1762],{"class":987},"lt_LT.UTF-8",[53,1764,1589],{"class":63},[53,1766,1767],{"class":987},"nl_BE.UTF-8",[53,1769,1589],{"class":63},[53,1771,1772],{"class":987},"nl_NL.UTF-8",[53,1774,1589],{"class":63},[53,1776,1777],{"class":987},"no_NO.UTF-8",[53,1779,1589],{"class":63},[53,1781,1782],{"class":987},"pl_PL.UTF-8",[53,1784,1589],{"class":63},[53,1786,1787],{"class":987},"pt_BR.UTF-8",[53,1789,1589],{"class":63},[53,1791,1792],{"class":987},"pt_PT.UTF-8",[53,1794,1589],{"class":63},[53,1796,1797],{"class":987},"ro_RO.UTF-8",[53,1799,1589],{"class":63},[53,1801,1802],{"class":987},"ru_RU.UTF-8",[53,1804,1589],{"class":63},[53,1806,1807],{"class":987},"sk_SK.UTF-8",[53,1809,1589],{"class":63},[53,1811,1812],{"class":987},"sl_SI.UTF-8",[53,1814,1589],{"class":63},[53,1816,1817],{"class":987},"sr_YU.UTF-8",[53,1819,1589],{"class":63},[53,1821,1822],{"class":987},"sv_SE.UTF-8",[53,1824,1589],{"class":63},[53,1826,1827],{"class":987},"tr_TR.UTF-8",[53,1829,1589],{"class":63},[53,1831,1832],{"class":987},"uk_UA.UTF-8",[53,1834,1589],{"class":63},[53,1836,1837],{"class":987},"zh_CN.UTF-8",[53,1839,1589],{"class":63},[53,1841,1842],{"class":987},"zh_HK.UTF-8",[53,1844,1589],{"class":63},[53,1846,1847],{"class":987},"zh_TW.UTF-8\n",[28,1849,1850,1851,1854,1855,1858],{},"Google 了半天，没找到有效的答案，大多数是让重新安装之类的，没意义。后来在 JetBrains 的 Issues 平台上提交了问题，最终发现这是一个已知问题，并且与 mac 上使用了 ",[35,1852,1853],{},"zsh"," 终端相关，可能 ",[35,1856,1857],{},"oh-my-zsh"," 重置了编码，导致 PyCharm 的运行环境中存在问题，最终解决方法如下：",[28,1860,1861,1862,1865],{},"在 ",[35,1863,1864],{},".zshrc"," 文件最后指定编码：",[44,1867,1871],{"className":1868,"code":1869,"language":1870,"meta":49,"style":49},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","export LANG=zh_CN.UTF-8\n","bash",[35,1872,1873],{"__ignoreMap":49},[53,1874,1875,1878,1881,1883],{"class":55,"line":56},[53,1876,1877],{"class":958},"export",[53,1879,1880],{"class":63}," LANG",[53,1882,141],{"class":140},[53,1884,1885],{"class":63},"zh_CN.UTF-8\n",[28,1887,1888],{},"重启 PyCharm，问题解决！",[682,1890,1891],{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":49,"searchDepth":67,"depth":67,"links":1893},[],"png","2019-07-19",{},"\u002Fposts\u002F2019\u002Fsolve-pycharm-adding-pipenv-error",{"text":1899,"minutes":1900,"time":1901,"words":1902},"3 min read",2.475,148500,495,{"title":1161,"description":1166},{"loc":1897},"posts\u002F2019\u002F20190719.solve-pycharm-adding-pipenv-error",[703,705],"evfrZW5UIS6uc56-A3l7RyWC1PkguQKJQ3MsPghGai8",1777580269940]