32 lines
2.0 KiB
Markdown
32 lines
2.0 KiB
Markdown
---
|
||
title: deploy.py / manage.py 兼容 Python 3.6 的改法与陷阱
|
||
type: experience
|
||
permalink: main/projects/d1932ed6-07d3-4463-a224-8534ffd69a07/deploy.py-manage.py-兼容-python-3.6-的改法与陷阱
|
||
stable_id: df7b18f9-490f-415f-a388-2332d1b7df87
|
||
scope: project
|
||
project_id: d1932ed6-07d3-4463-a224-8534ffd69a07
|
||
memory_type: experience
|
||
status: active
|
||
revision: 1
|
||
restored_from_commit: 6a6a895eafcca6052e81a14fca103a42635dd1c2
|
||
created_at: '2026-09-23T15:05:30.775086+00:00'
|
||
updated_at: '2026-09-23T15:05:30.775148+00:00'
|
||
tags:
|
||
- nextoffice
|
||
- python36
|
||
- compatibility
|
||
- deploy
|
||
- manage.py
|
||
---
|
||
|
||
背景:目标服务器 CentOS 8 系统 Python 仅 3.6.8,原脚本在其上直接 SyntaxError。提交 27fc41b 完成兼容,并在真实 3.6.8 上验证。
|
||
|
||
必须改的点(以后新代码也要守):
|
||
- 不能用 `from __future__ import annotations`(3.7+);因此函数参数/返回注解会在定义时求值,不能用 PEP 585/604 写法(dict[str,str]、str | None),改用 typing.Dict/Optional/Union/Tuple/FrozenSet。局部变量注解不求值,但统一改成 `x = {} # type: Dict[...]` 注释形式。
|
||
- `subprocess.CompletedProcess[str]` 不可下标(3.9+),去掉 [str]。
|
||
- `subprocess.run(text=True)` 是 3.7+,改 `universal_newlines=True`;cwd 传 str(ROOT)。
|
||
- `Path.write_text(newline=...)` 是 3.10+,改 `with path.open('w', encoding='utf-8', newline='\n')`。
|
||
- `argparse.add_subparsers(required=True)` 是 3.7+,去掉 required,在 main() 中 `if not hasattr(args, 'func'): parser.print_help(); return 2`。
|
||
- f-string、secrets、ipaddress、pathlib、dict 有序(CPython 3.6 实际有序)均可用。
|
||
|
||
验证方法:本地高版本 Python 用 `ast.parse(src, feature_version=(3, 6))` 先拦语法;但运行时 API 差异(text=、newline=、required=)只能靠真实 3.6 跑:把 mock 了 docker/occ 的行为测试脚本 sftp 到服务器 /tmp 用系统 python3 执行。manage.py 现从 deploy 导入 write_env,reconfigure 与安装共用 .env 写入(含 chmod 600)。 |