
背景: 当前python社区的各个分支状态如下,3.7和3.8分支均为稳定版本,其中3.9还未发布正式版本,3.8分支基于3.7合入了较多的新特性和bugfix。 [cid:image001.png@01D63E49.148DF270] 目标: 升级openeuler python3开源软件,准备从3.7.4版本更新到3.8.3稳定版本,两个版本间存在较多差异,需要适配的变更点罗列如下,具体详见附件,后期若有疑问请在该邮件中回复讨论。 差异描述 差异类型 差异引入原因 差异引入版本 影响分析 是否需要适配 适配方案 在函数调用中允许使用的关键字名称语法受到进一步的限制。 特别地,f((keyword)=arg) 不再被允许。 关键字参数赋值形式的左侧绝不允许一般标识符以外的其他内容 修改 bugfix 3.8 f((keyword)=arg) 不再被允许 Y 使用者适配该变更 当类似 [(10, 20) (30, 40)] 这样在代码中少了一个逗号时,编译器将显示 SyntaxWarning 并附带更有帮助的提示。 这相比原来用 TypeError 来提示第一个元组是不可调用的更容易被理解 修改 DFX增强 3.8 当类似 [(10, 20) (30, 40)] 这样在代码中少了一个逗号时,编译器将从原来的TypeError变为显示 SyntaxWarning Y 使用者适配该变更 datetime.date 或 datetime.datetime 和 datetime.timedelta 对象之间的算术运算现在将返回相应子类的实例而不是基类的实例 修改 bugfix 3.8 datetime.date 或 datetime.datetime 和 datetime.timedelta 对象之间的算术运算现在将返回相应子类的实例而不是基类的实例 Y 使用者适配该变更 字典推导式已与字典字面值实现同步,会先计算键再计算值
cast = {input('role? '): input('actor? ') for i in range(2)} role? King Arthur actor? Chapman role? Black Knight actor? Cleese
修改 bugfix 3.8 字典推导式已与字典字面值实现同步,会先计算键再计算值 Y 使用者适配该变更 异常 asyncio.CancelledError 现在继承自 BaseException 而不是 Exception 修改 DFX增强 3.8 异常 asyncio.CancelledError 现在继承自 BaseException 而不是 Exception Y 使用者适配该变更 collections.namedtuple() 的 _asdict() 方法现在将返回 dict 而不是 collections.OrderedDict。 修改 bugfix 3.8 collections.namedtuple() 的 _asdict() 方法现在将返回 dict 而不是 collections.OrderedDict。 Y 使用者适配该变更 csv.DictReader 现在将返回 dict 而不是 collections.OrderedDict 修改 bugfix 3.8 csv.DictReader 现在将返回 dict 而不是 collections.OrderedDict Y 使用者适配该变更 对于特定类型的无效或已损坏 gzip 文件现在将引发 BadGzipFile 而不是 OSError 修改 DFX增强 3.8 对于特定类型的无效或已损坏 gzip 文件现在将引发 BadGzipFile 而不是 OSError Y 使用者适配该变更 函数 math.factorial() 不再接受非整数类参数 修改 bugfix 3.8 函数 math.factorial() 不再接受非整数类参数 Y 使用者适配该变更 返回布尔值结果的 os.path 函数例如 exists(), lexists(), isdir(), isfile(), islink(), 以及 ismount() 现在对于包含在 OS 层级无法表示的字符或字节的路径将会返回 False 而不是引发 ValueError 或其子类 UnicodeEncodeError 和 UnicodeDecodeError。 修改 DFX增强 3.8 返回布尔值结果的 os.path 函数在对于包含在 OS 层级无法表示的字符或字节的路径将会返回 False 而不是引发 ValueError 或其子类 UnicodeEncodeError 和 UnicodeDecodeError。 Y 使用者适配该变更 返回布尔值结果的 pathlib.Path 方法例如 exists(), is_dir(), is_file(), is_mount(), is_symlink(), is_block_device(), is_char_device(), is_fifo(), is_socket() 现在对于包含在 OS 层级无法表示的字符或字节的路径将会返回 False 而不是引发 ValueError 或其子类 UnicodeEncodeError 修改 DFX增强 3.8 返回布尔值结果的 pathlib.Path 方法在对于包含在 OS 层级无法表示的字符或字节的路径将会返回 False 而不是引发 ValueError 或其子类 UnicodeEncodeError Y 使用者适配该变更 shutil.make_archive() 现在对于通过 format="tar" 创建的归档文件将使用新式的 pax (POSIX.1-2001) 格式而非旧式的 GNU 格式 修改 bugfix 3.8 shutil.make_archive() 现在对于通过 format="tar" 创建的归档文件将使用新式的 pax (POSIX.1-2001) 格式而非旧式的 GNU 格式 Y 使用者适配该变更 tarfile 模块现在对新的归档默认使用 modern pax (POSIX.1-2001) 格式而不再是之前的 GNU 专属格式 修改 bugfix 3.8 tarfile 模块现在对新的归档默认使用 modern pax (POSIX.1-2001) 格式而不再是之前的 GNU 专属格式 Y 使用者适配该变更 作为对 DTD 和外部实体检索的缓解,在默认情况下 xml.dom.minidom 和 xml.sax 模块不再处理外部实体 修改 bugfix 3.8 作为对 DTD 和外部实体检索的缓解,在默认情况下 xml.dom.minidom 和 xml.sax 模块不再处理外部实体 Y 使用者适配该变更 只会安装 python3.8 程序,不再有 python3.8m 程序 只会安装 python3.8-config 脚本,不再有 python3.8m-config 脚本 m 已经从动态库文件名后缀中移除:包括标准库中的扩展模块以及第三方包所产生和安装的模块例如从 PyPI 下载的模块。 以 Linux 为例,Python 3.7 的后缀 .cpython-37m-x86_64-linux-gnu.so ,在 Python 3.8 中改为 .cpython-38-x86_64-linux-gnu.so。 修改 bugfix 3.8 m 已经从动态库文件名后缀中移除:包括标准库中的扩展模块以及第三方包所产生和安装的模块 Y spec文件中需要修改 重新组织了所有头文件以更好地区分不同种类的 API: Include/*.h 应为可移植的公有稳定版 C API。 Include/cpython/*.h 应为 CPython 专属的不稳定版 C API;公有 API,部分私有 API 附加 _Py or _PY 前缀。 Include/internal/*.h 应为 CPython 特别专属的私有内部 C API。 此 API 不具备向下兼容保证并且不应在 CPython 以外被使用。 它们的公开仅适用于特别限定的需求例如调试器和性能分析等必须直接访问 CPython 内部数据而不通过调用函数的应用 修改 bugfix 3.8 Include/internal/*.h 应为 CPython 特别专属的私有内部 C API。 此 API 不具备向下兼容保证并且不应在 CPython 以外被使用 Y 使用者适配该变更 distutils 的 bdist_wininst 命令现在已弃用,请改用 bdist_wheel (wheel 包) 修改 bugfix 3.8 distutils 的 bdist_wininst 命令现在已弃用,请改用 bdist_wheel (wheel 包) Y 使用者适配该变更 ElementTree 模块中的已弃用方法 getchildren() 和 getiterator() 现在会引发 DeprecationWarning 而不是 PendingDeprecationWarning 修改 DFX增强 3.8 ElementTree 模块中的已弃用方法 getchildren() 和 getiterator() 现在会引发 DeprecationWarning 而不是 PendingDeprecationWarning Y 使用者适配该变更 将不是 concurrent.futures.ThreadPoolExecutor 的实例的对象传给 loop.set_default_executor() 已被弃用 修改 bugfix 3.8 将不是 concurrent.futures.ThreadPoolExecutor 的实例的对象传给 loop.set_default_executor() 已被弃用 Y 使用者适配该变更 xml.dom.pulldom.DOMEventStream, wsgiref.util.FileWrapper 和 fileinput.FileInput 的 __getitem__() 方法已被弃用 修改 bugfix 3.8 xml.dom.pulldom.DOMEventStream, wsgiref.util.FileWrapper 和 fileinput.FileInput 的 __getitem__() 方法已被弃用 Y 使用者适配该变更 typing.NamedTuple 类已弃用了 _field_types 属性而改用具有同样信息的 __annotations__ 属性 修改 bugfix 3.8 typing.NamedTuple 类已弃用了 _field_types 属性而改用具有同样信息的 __annotations__ 属性 Y 使用者适配该变更 ast 类 Num, Str, Bytes, NameConstant 和 Ellipsis 被视为已弃用,应当改用 Constant 修改 bugfix 3.8 ast 类 Num, Str, Bytes, NameConstant 和 Ellipsis 被视为已弃用,应当改用 Constant Y 使用者适配该变更 ast.NodeVisitor 的方法 visit_Num(), visit_Str(), visit_Bytes(), visit_NameConstant() 和 visit_Ellipsis() 现在已被弃用,添加 visit_Constant() 方法来处理所有常量节点 修改 bugfix 3.8 ast.NodeVisitor 的方法 visit_Num(), visit_Str(), visit_Bytes(), visit_NameConstant() 和 visit_Ellipsis() 现在已被弃用,添加 visit_Constant() 方法来处理所有常量节点 Y 使用者适配该变更 asyncio.coroutine() decorator 已弃用,原有的 @asyncio.coroutine 请改用 async def 来替代 修改 bugfix 3.8 asyncio.coroutine() decorator 已弃用,原有的 @asyncio.coroutine 请改用 async def 来替代 Y 使用者适配该变更 在 asyncio 中,loop 参数的显式传递已被弃用 修改 bugfix 3.8 在 asyncio 中,loop 参数的显式传递已被弃用 Y 使用者适配该变更 将协程对象显式传递给 asyncio.wait() 的做法已被弃用 修改 bugfix 3.8 将协程对象显式传递给 asyncio.wait() 的做法已被弃用 Y 使用者适配该变更 gettext 模块中的下列函数和方法已被弃用: lgettext(), ldgettext(), lngettext() 和 ldngettext() 修改 bugfix 3.8 gettext 模块中的下列函数和方法已被弃用: lgettext(), ldgettext(), lngettext() 和 ldngettext() Y 使用者适配该变更 函数 bind_textdomain_codeset(),方法 output_charset() 和 set_output_charset(),以及函数 translation() 和 install() 的 codeset 形参也被弃用 修改 bugfix 3.8 函数 bind_textdomain_codeset(),方法 output_charset() 和 set_output_charset(),以及函数 translation() 和 install() 的 codeset 形参也被弃用 Y 使用者适配该变更 threading.Thread 的 isAlive() 方法已弃用 修改 bugfix 3.8 threading.Thread 的 isAlive() 方法已弃用 Y 使用者适配该变更 macpath 模块,在 Python 3.7 中弃用,现已被移除 修改 bugfix 3.8 macpath 模块,在 Python 3.7 中弃用,现已被移除 Y 使用者适配该变更 函数 platform.popen() 已被移除,它自 Python 3.3 起就已被弃用:请改用 os.popen() 修改 bugfix 3.8 函数 platform.popen() 已被移除,它自 Python 3.3 起就已被弃用:请改用 os.popen() Y 使用者适配该变更 函数 time.clock() 已被移除,它自 Python 3.3 起就已被弃用:请根据具体需求改用 time.perf_counter() 或 time.process_time() 以获得具有良好定义的行为 修改 bugfix 3.8 函数 time.clock() 已被移除,它自 Python 3.3 起就已被弃用:请根据具体需求改用 time.perf_counter() 或 time.process_time() 以获得具有良好定义的行为 Y 使用者适配该变更 pyvenv 脚本已被移除,推荐改用 python3.8 -m venv 来帮助消除容易混淆 pyvenv 脚本所关联的 Python 解释器这一问题 修改 bugfix 3.8 pyvenv 脚本已被移除,推荐改用 python3.8 -m venv 来帮助消除容易混淆 pyvenv 脚本所关联的 Python 解释器这一问题 Y spec文件中需要修改 使用者需要适配 parse_qs, parse_qsl 和 escape 已从 cgi 模块中被移除。 这些函数自 Python 3.2 或更早就已被弃用。 它们应改为从 urllib.parse 和 html 模块导入 修改 bugfix 3.8 parse_qs, parse_qsl 和 escape 已从 cgi 模块中被移除。 这些函数自 Python 3.2 或更早就已被弃用。 它们应改为从 urllib.parse 和 html 模块导入 Y 使用者适配该变更 filemode 函数已从 tarfile 模块中被移除 修改 bugfix 3.8 filemode 函数已从 tarfile 模块中被移除 Y 使用者适配该变更 XMLParser 构造器不再接受 html 参数 修改 bugfix 3.8 XMLParser 构造器不再接受 html 参数 Y 使用者适配该变更 XMLParser 的 doctype() 方法已被移除 修改 bugfix 3.8 XMLParser 的 doctype() 方法已被移除 Y 使用者适配该变更 "unicode_internal" 编解码器已被移除 修改 bugfix 3.8 "unicode_internal" 编解码器已被移除 Y 使用者适配该变更 sqlite3 模块的 Cache 和 Statement 对象已不再公开给用户 修改 bugfix 3.8 sqlite3 模块的 Cache 和 Statement 对象已不再公开给用户 Y 使用者适配该变更 fileinput.input() 和 fileinput.FileInput() 中自 Python 3.6 起就已被忽略并弃用的 bufsize 关键字参数已被移除 修改 bugfix 3.8 fileinput.input() 和 fileinput.FileInput() 中自 Python 3.6 起就已被忽略并弃用的 bufsize 关键字参数已被移除 Y 使用者适配该变更 在 Python 3.7 中弃用的函数 sys.set_coroutine_wrapper() 和 sys.get_coroutine_wrapper() 已被移除 修改 bugfix 3.8 在 Python 3.7 中弃用的函数 sys.set_coroutine_wrapper() 和 sys.get_coroutine_wrapper() 已被移除 Y 使用者适配该变更 yield 表达式(包括 yield 和 yield from 子句)现在不允许在推导式和生成器表达式中使用(但 for 子句最左边的可迭代对象表达式除外) 修改 bugfix 3.8 yield 表达式(包括 yield 和 yield from 子句)现在不允许在推导式和生成器表达式中使用(但 for 子句最左边的可迭代对象表达式除外) Y 使用者适配该变更 当标识号检测 (is 和 is not) 与特定类型的字面值 (例如字符串和数字) 一同使用时编译器现在会产生 SyntaxWarning。 该警告会建议用户改用相等性检测 (== and !=) 修改 bugfix 3.8 当标识号检测 (is 和 is not) 与特定类型的字面值 (例如字符串和数字) 一同使用时编译器现在会产生 SyntaxWarning。 该警告会建议用户改用相等性检测 (== and !=) Y 使用者适配该变更 从内置类型 bool, int, float, complex 和标准库的一些类中移除了 __str__ 实现。 它们现在会从 object 继承 __str__()。 作为结果,在这些类的子类中定义 __repr__() 方法将会影响它们的字符串表示 修改 bugfix 3.8 从内置类型 bool, int, float, complex 和标准库的一些类中移除了 __str__ 实现。 它们现在会从 object 继承 __str__()。 作为结果,在这些类的子类中定义 __repr__() 方法将会影响它们的字符串表示 Y 使用者适配该变更 subprocess.Popen的preexec_fn参数不再与子解释器兼容。在子解释器中使用该参数会引起RuntimeError 修改 bugfix 3.8 subprocess.Popen的preexec_fn参数不再与子解释器兼容。在子解释器中使用该参数会引起RuntimeError Y 使用者适配该变更 当传入多模数据时 statistics.mode() 函数不会再引发异常 修改 bugfix 3.8 当传入多模数据时 statistics.mode() 函数不会再引发异常 Y 使用者适配该变更 tkinter.ttk.Treeview 类的 selection() 方法不再接受参数。 带参数调用该方法来改变选择在 Python 3.6 中已弃用。 请使用专门方法例如 selection_set() 来改变选择 修改 bugfix 3.8 tkinter.ttk.Treeview 类的 selection() 方法不再接受参数。 带参数调用该方法来改变选择在 Python 3.6 中已弃用。 请使用专门方法例如 selection_set() 来改变选择 Y 使用者适配该变更 附带 'r' 旗标打开的 dbm.dumb 数据库现在将是只读的。 如果数据库不存在,附带 'r' 和 'w' 旗标的 dbm.dumb.open() 不会再创建数据库 修改 bugfix 3.8 附带 'r' 旗标打开的 dbm.dumb 数据库现在将是只读的。 如果数据库不存在,附带 'r' 和 'w' 旗标的 dbm.dumb.open() 不会再创建数据库 Y 使用者适配该变更 现在当自定义元类未在传给 type.__new__ 的命名空间中提供 __classcell__ 入口时将引发 RuntimeError。 在 Python 3.6--3.7 中是则是引发 DeprecationWarning 修改 DFX增强 3.8 现在当自定义元类未在传给 type.__new__ 的命名空间中提供 __classcell__ 入口时将引发 RuntimeError。 在 Python 3.6--3.7 中是则是引发 DeprecationWarning Y 使用者适配该变更 现在所有平台下的 mmap.flush() 方法都会在成功时返回 None 并在错误时引发异常。 之前 Unix 下会在成功时返回零;在失败时引发错误。 修改 bugfix 3.8 现在所有平台下的 mmap.flush() 方法都会在成功时返回 None 并在错误时引发异常。 之前 Unix 下会在成功时返回零;在失败时引发错误。 Y 使用者适配该变更 从只读的 dbm 数据库 (dbm.dumb, dbm.gnu 或 dbm.ndbm) 删除键将会引发 error (dbm.dumb.error, dbm.gnu.error 或 dbm.ndbm.error) 而不是 KeyError 修改 DFX增强 3.8 从只读的 dbm 数据库 (dbm.dumb, dbm.gnu 或 dbm.ndbm) 删除键将会引发 error (dbm.dumb.error, dbm.gnu.error 或 dbm.ndbm.error) 而不是 KeyError Y 使用者适配该变更 当将 'socket' 作为 name 形参传入时,函数 asyncio.BaseTransport.get_extra_info() 现在会返回一个可安全使用的套接字对象 修改 bugfix 3.8 当将 'socket' 作为 name 形参传入时,函数 asyncio.BaseTransport.get_extra_info() 现在会返回一个可安全使用的套接字对象 Y 使用者适配该变更 PyEval_ReInitThreads() 函数已从 C API 中移除。 它不应当被显式地调用;请改用 PyOS_AfterFork_Child() 修改 bugfix 3.8 PyEval_ReInitThreads() 函数已从 C API 中移除。 它不应当被显式地调用;请改用 PyOS_AfterFork_Child() Y 使用者适配该变更 在 Unix 上,C 扩展不会再被链接到 libpython, 当 Python 被嵌入时,libpython 不可使用 RTLD_LOCAL 加载,而要改用 RTLD_GLOBAL。 修改 bugfix 3.8 在 Unix 上,C 扩展不会再被链接到 libpython, 当 Python 被嵌入时,libpython 不可使用 RTLD_LOCAL 加载,而要改用 RTLD_GLOBAL。 Y 使用者适配该变更 移除了操作码 BREAK_LOOP, CONTINUE_LOOP, SETUP_LOOP 和 SETUP_EXCEPT。 添加了新的操作码 ROT_FOUR, BEGIN_FINALLY, CALL_FINALLY 和 POP_FINALLY。 修改了 END_FINALLY 和 WITH_CLEANUP_START 的行为 修改 bugfix 3.8 移除了操作码 BREAK_LOOP, CONTINUE_LOOP, SETUP_LOOP 和 SETUP_EXCEPT。 添加了新的操作码 ROT_FOUR, BEGIN_FINALLY, CALL_FINALLY 和 POP_FINALLY。 修改了 END_FINALLY 和 WITH_CLEANUP_START 的行为 Y 使用者适配该变更 platform.dist()和linux_distribution()已经被删除 修改 bugfix 3.8 platform.dist()和linux_distribution()已经被删除 Y 使用者适配该变更