openrewrite-migrate-python 0.13.1__tar.gz → 0.13.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/PKG-INFO +2 -2
  2. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/pyproject.toml +2 -6
  3. openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/_reindent.py +77 -0
  4. openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/_trivia.py +139 -0
  5. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/all_branches_identical.py +31 -32
  6. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py +69 -46
  7. openrewrite_migrate_python-0.13.2/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +172 -0
  8. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/remove_unconditional_value_overwrite.py +106 -55
  9. openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/_from_imports.py +68 -0
  10. openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/_langchain_tables.py +716 -0
  11. openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/_slots.py +14 -0
  12. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/_typing_imports.py +28 -5
  13. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +37 -25
  14. openrewrite_migrate_python-0.13.2/src/openrewrite_migrate_python/migrate/datetime_utc.py +274 -0
  15. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +26 -4
  16. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +44 -0
  17. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +52 -42
  18. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +35 -8
  19. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +8 -10
  20. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +47 -18
  21. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +13 -2
  22. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/string_formatting.py +98 -31
  23. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +109 -53
  24. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +14 -5
  25. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/PKG-INFO +2 -2
  26. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +5 -0
  27. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/requires.txt +1 -1
  28. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_asyncio_coroutine_to_async.py +52 -0
  29. openrewrite_migrate_python-0.13.2/tests/test_datetime_utc.py +225 -0
  30. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_gettext_deprecations.py +32 -0
  31. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_langchain_classic_imports.py +52 -0
  32. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_langchain_community_imports.py +69 -0
  33. openrewrite_migrate_python-0.13.2/tests/test_locale_deprecations.py +154 -0
  34. openrewrite_migrate_python-0.13.2/tests/test_locale_getdefaultlocale_deprecation.py +45 -0
  35. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_platform_deprecations.py +28 -8
  36. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_ssl_deprecations.py +16 -0
  37. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_string_formatting.py +155 -0
  38. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_deprecations.py +343 -0
  39. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_union_to_pipe.py +26 -0
  40. openrewrite_migrate_python-0.13.1/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +0 -152
  41. openrewrite_migrate_python-0.13.1/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -137
  42. openrewrite_migrate_python-0.13.1/tests/test_datetime_utc.py +0 -85
  43. openrewrite_migrate_python-0.13.1/tests/test_locale_deprecations.py +0 -53
  44. openrewrite_migrate_python-0.13.1/tests/test_locale_getdefaultlocale_deprecation.py +0 -26
  45. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/setup.cfg +0 -0
  46. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/__init__.py +0 -0
  47. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/__init__.py +0 -0
  48. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/_semantically_equal.py +0 -0
  49. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py +0 -0
  50. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py +0 -0
  51. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/merge_identical_branches.py +0 -0
  52. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py +0 -0
  53. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/simplify_boolean_literal.py +0 -0
  54. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_code_quality_python/codequality/simplify_redundant_logical_expression.py +0 -0
  55. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/__init__.py +0 -0
  56. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/__init__.py +0 -0
  57. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/_import_hygiene.py +0 -0
  58. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
  59. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
  60. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
  61. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
  62. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +0 -0
  63. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/avro_migrations.py +0 -0
  64. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
  65. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
  66. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +0 -0
  67. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
  68. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
  69. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
  70. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
  71. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
  72. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/future_imports.py +0 -0
  73. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +0 -0
  74. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
  75. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
  76. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
  77. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
  78. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
  79. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
  80. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
  81. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
  82. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
  83. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +0 -0
  84. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pydantic_deprecations.py +0 -0
  85. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pydantic_fields.py +0 -0
  86. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/pydantic_model_fields.py +0 -0
  87. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/re_deprecations.py +0 -0
  88. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
  89. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
  90. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
  91. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
  92. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -0
  93. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +0 -0
  94. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
  95. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +0 -0
  96. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
  97. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
  98. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
  99. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
  100. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
  101. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
  102. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_pydantic.py +0 -0
  103. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
  104. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
  105. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
  106. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
  107. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
  108. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +0 -0
  109. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +0 -0
  110. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +0 -0
  111. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
  112. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
  113. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +0 -0
  114. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
  115. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
  116. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
  117. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_aifc_migrations.py +0 -0
  118. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_array_deprecations.py +0 -0
  119. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_ast_deprecations.py +0 -0
  120. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_asyncio_deprecations.py +0 -0
  121. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_avro_migrations.py +0 -0
  122. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_calendar_deprecations.py +0 -0
  123. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_cgi_parse_deprecations.py +0 -0
  124. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_change_import_recipes.py +0 -0
  125. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_collections_abc_migrations.py +0 -0
  126. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_configparser_deprecations.py +0 -0
  127. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_distutils_deprecations.py +0 -0
  128. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_future_imports.py +0 -0
  129. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_html_parser_deprecations.py +0 -0
  130. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_imp_migrations.py +0 -0
  131. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_langchain_provider_imports.py +0 -0
  132. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_macpath_deprecations.py +0 -0
  133. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_os_deprecations.py +0 -0
  134. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pep594_migrations.py +0 -0
  135. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pep594_system_migrations.py +0 -0
  136. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pkgutil_deprecations.py +0 -0
  137. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pydantic_deprecations.py +0 -0
  138. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pydantic_fields.py +0 -0
  139. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_pydantic_model_fields.py +0 -0
  140. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_re_deprecations.py +0 -0
  141. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_removed_modules_312.py +0 -0
  142. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_shutil_deprecations.py +0 -0
  143. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_sys_deprecations.py +0 -0
  144. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_sys_last_deprecations.py +0 -0
  145. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_tarfile_deprecations.py +0 -0
  146. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_threading_deprecations.py +0 -0
  147. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_threading_extended.py +0 -0
  148. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_threading_is_alive_deprecation.py +0 -0
  149. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_alias_moves.py +0 -0
  150. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_typing_callable.py +0 -0
  151. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_unittest_deprecations.py +0 -0
  152. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_upgrade_recipes.py +0 -0
  153. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_upgrade_to_pydantic.py +0 -0
  154. {openrewrite_migrate_python-0.13.1 → openrewrite_migrate_python-0.13.2}/tests/test_xml_deprecations.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrewrite-migrate-python
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: OpenRewrite recipes for migrating Python codebases to newer Python versions.
5
5
  Author-email: "Moderne Inc." <support@moderne.io>
6
6
  License: Moderne Proprietary
@@ -21,7 +21,7 @@ Classifier: Typing :: Typed
21
21
  Requires-Python: >=3.10
22
22
  Description-Content-Type: text/markdown
23
23
  Provides-Extra: dev
24
- Requires-Dist: openrewrite>=8.89.1; extra == "dev"
24
+ Requires-Dist: openrewrite>=8.91.5; extra == "dev"
25
25
  Requires-Dist: pydantic>=2.11; extra == "dev"
26
26
  Requires-Dist: pytest>=8.0.0; extra == "dev"
27
27
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "openrewrite-migrate-python"
7
7
  description = "OpenRewrite recipes for migrating Python codebases to newer Python versions."
8
- version = "0.13.1" # Updated dynamically during release
8
+ version = "0.13.2" # Updated dynamically during release
9
9
  authors = [{ name = "Moderne Inc.", email = "support@moderne.io" }]
10
10
  license = { text = "Moderne Proprietary" }
11
11
  readme = "README.md"
@@ -30,11 +30,7 @@ dependencies = []
30
30
 
31
31
  [project.optional-dependencies]
32
32
  dev = [
33
- # 8.89.1 for `python.scope_utils.LocalBindings`, which tells a local apart from a
34
- # reference to an import: the PEP 585 recipes use it directly, and `ChangeImport`
35
- # and `RemoveImport` need it to see references inside functions. openrewrite is
36
- # host-provided at runtime, so this floor only affects dev/CI.
37
- "openrewrite>=8.89.1",
33
+ "openrewrite>=8.91.5",
38
34
  # Needed so type-attribution tests can resolve `pydantic` types.
39
35
  "pydantic>=2.11",
40
36
  "pytest>=8.0.0",
@@ -0,0 +1,77 @@
1
+ """Shared indentation helpers for recipes that lift a block out of its parent.
2
+
3
+ Python indentation lives in the ``Space`` before each token, so moving a block
4
+ to a shallower nesting level means rewriting every line it spans.
5
+ """
6
+
7
+ from typing import Optional, TypeVar
8
+
9
+ from rewrite.java.support_types import Space
10
+ from rewrite.python.visitor import PythonVisitor
11
+
12
+ T = TypeVar("T")
13
+
14
+
15
+ def inherited_prefix(dropped: Space, body: Space) -> Space:
16
+ """Prefix for the statement that takes the place of a dropped enclosing node.
17
+
18
+ It starts where the dropped node started, and the comments the dropped node
19
+ carried stay ahead of the body's own. Those comments' suffixes already
20
+ indent to the level the body now occupies.
21
+ """
22
+ return Space(
23
+ _comments=[*dropped.comments, *body.comments],
24
+ _whitespace=dropped.whitespace,
25
+ )
26
+
27
+
28
+ def line_indent(space: Space) -> Optional[str]:
29
+ """Indentation of the line the token following *space* starts on, or
30
+ ``None`` when that token shares a line with what precedes it.
31
+
32
+ A trailing comment puts the newline in the comment's suffix rather than in
33
+ ``Space.whitespace``; empty whitespace is a file's first token, at column 0.
34
+ """
35
+ text = space.comments[-1].suffix if space.comments else space.whitespace
36
+ if "\n" in text:
37
+ return text.rsplit("\n", 1)[-1]
38
+ return text if text == "" else None
39
+
40
+
41
+ def _rebase(text: str, old_base: str, new_base: str) -> str:
42
+ head, sep, indent = text.rpartition("\n")
43
+ if not sep or not indent.startswith(old_base):
44
+ return text
45
+ return head + sep + new_base + indent[len(old_base):]
46
+
47
+
48
+ class _Reindent(PythonVisitor[None]):
49
+ def __init__(self, old_base: str, new_base: str):
50
+ super().__init__()
51
+ self._old_base = old_base
52
+ self._new_base = new_base
53
+
54
+ def visit_space(self, space: Optional[Space], p: None) -> Space:
55
+ if space is None:
56
+ return Space.EMPTY
57
+ whitespace = _rebase(space.whitespace, self._old_base, self._new_base)
58
+ comments = [
59
+ c.replace(suffix=_rebase(c.suffix, self._old_base, self._new_base))
60
+ for c in space.comments
61
+ ]
62
+ if whitespace == space.whitespace and all(
63
+ c.suffix == o.suffix for c, o in zip(comments, space.comments)
64
+ ):
65
+ return space
66
+ return Space(_comments=comments, _whitespace=whitespace)
67
+
68
+
69
+ def reindent(tree: T, old_base: str, new_base: str) -> T:
70
+ """Re-base every line in *tree* that is indented at least to *old_base*.
71
+
72
+ Lines indented less deeply are continuation lines whose alignment is
73
+ independent of the block's nesting, so they are left alone.
74
+ """
75
+ if old_base == new_base:
76
+ return tree
77
+ return _Reindent(old_base, new_base).visit(tree, None)
@@ -0,0 +1,139 @@
1
+ """
2
+ Line-level trivia splicing for recipes that delete whole statements.
3
+
4
+ A statement's *trailing* comment is stored on whatever the printer emits
5
+ next -- the following statement's prefix, or, for a block's last statement,
6
+ trivia outside the block. Deleting a statement therefore moves trivia
7
+ between its neighbours.
8
+ """
9
+
10
+ from itertools import islice
11
+ from typing import Optional, Tuple
12
+
13
+ from rewrite import Cursor
14
+ from rewrite.java.support_types import Space
15
+ from rewrite.java.tree import Block, ClassDeclaration, If, MethodDeclaration
16
+ from rewrite.python.tree import CompilationUnit
17
+
18
+
19
+ def split_line(space: Space) -> Optional[Tuple[Space, Space]]:
20
+ """Split ``space`` at its first newline, or return None if it has no newline.
21
+
22
+ The head is the trivia that still belongs to the preceding line -- most
23
+ importantly that line's trailing comment. The tail starts with the
24
+ newline itself.
25
+ """
26
+ newline = space.whitespace.find("\n")
27
+ if newline != -1:
28
+ return (
29
+ Space(_comments=[], _whitespace=space.whitespace[:newline]),
30
+ Space(_comments=space.comments, _whitespace=space.whitespace[newline:]),
31
+ )
32
+ for i, comment in enumerate(space.comments):
33
+ newline = comment.suffix.find("\n")
34
+ if newline != -1:
35
+ return (
36
+ Space(
37
+ _comments=[
38
+ *space.comments[:i],
39
+ comment.replace(_suffix=comment.suffix[:newline]),
40
+ ],
41
+ _whitespace=space.whitespace,
42
+ ),
43
+ Space(
44
+ _comments=space.comments[i + 1:],
45
+ _whitespace=comment.suffix[newline:],
46
+ ),
47
+ )
48
+ return None
49
+
50
+
51
+ def concat(left: Space, right: Space) -> Space:
52
+ """Return the trivia that prints as ``left`` followed by ``right``."""
53
+ if not left.comments:
54
+ return Space(
55
+ _comments=right.comments,
56
+ _whitespace=left.whitespace + right.whitespace,
57
+ )
58
+ last = left.comments[-1]
59
+ return Space(
60
+ _comments=[
61
+ *left.comments[:-1],
62
+ last.replace(_suffix=last.suffix + right.whitespace),
63
+ *right.comments,
64
+ ],
65
+ _whitespace=left.whitespace,
66
+ )
67
+
68
+
69
+ def opens_with_trailing_comment(space: Space) -> bool:
70
+ """Return True when ``space`` opens with a comment on the line it continues."""
71
+ split = split_line(space)
72
+ return bool((split[0] if split else space).comments)
73
+
74
+
75
+ def space_after_block(cursor: Cursor) -> Optional[Space]:
76
+ """The trivia the printer emits after the block at ``cursor``.
77
+
78
+ A block's last statement keeps its trailing comment outside the block --
79
+ on the next statement of an enclosing block, on the `else` of an enclosing
80
+ `if`, or at end of file. Returns None for the containers this does not
81
+ know how to look past.
82
+ """
83
+ child = cursor.value
84
+ for parent in islice(cursor.get_path(), 1, None):
85
+ if isinstance(parent, (Block, CompilationUnit)):
86
+ statements = parent._statements
87
+ index = next(
88
+ (i for i, s in enumerate(statements) if s.element.id == child.id),
89
+ None,
90
+ )
91
+ if index is None:
92
+ return None
93
+ if index + 1 < len(statements):
94
+ return statements[index + 1].element.prefix
95
+ if isinstance(parent, CompilationUnit):
96
+ return parent.eof
97
+ elif isinstance(parent, If):
98
+ if parent.else_part is not None and parent.else_part.id != child.id:
99
+ return parent.else_part.prefix
100
+ elif not isinstance(parent, (ClassDeclaration, If.Else, MethodDeclaration)):
101
+ return None
102
+ child = parent
103
+ return None
104
+
105
+
106
+ def splice_out(
107
+ padded_statements: list, end: Space, to_remove: set[int]
108
+ ) -> Tuple[list, Space]:
109
+ """Return the statements without those at ``to_remove``, and the new end trivia.
110
+
111
+ The survivor takes the removed statement's place on the page: the trivia
112
+ up to the removed statement's own line, which holds the preceding
113
+ statement's trailing comment, then that line's break and indent. Only
114
+ comments standing on their own line before the survivor come from the
115
+ survivor; the removed statement's go with it.
116
+ """
117
+ result = []
118
+ pending: Optional[Tuple[Space, Space]] = None
119
+ for i, padded in enumerate(padded_statements):
120
+ if i in to_remove:
121
+ if pending is None:
122
+ prefix = padded.element.prefix
123
+ # A file's first statement starts a line without a break to show for it.
124
+ pending = split_line(prefix) or (prefix, Space.EMPTY)
125
+ continue
126
+ if pending is not None:
127
+ head, line = pending
128
+ _, tail = split_line(padded.element.prefix)
129
+ padded = padded.replace(
130
+ _element=padded.element.replace(
131
+ _prefix=concat(
132
+ head,
133
+ Space(_comments=tail.comments, _whitespace=line.whitespace),
134
+ )
135
+ )
136
+ )
137
+ pending = None
138
+ result.append(padded)
139
+ return result, end if pending is None else concat(pending[0], end)
@@ -16,12 +16,16 @@ from rewrite.category import CategoryDescriptor
16
16
  from rewrite.decorators import categorize
17
17
  from rewrite.marketplace import Python
18
18
  from rewrite.python.visitor import PythonVisitor
19
- from rewrite.java.support_types import Space
20
19
  from rewrite.java.tree import (
21
20
  Block,
22
21
  If,
23
22
  Statement,
24
23
  )
24
+ from openrewrite_code_quality_python.codequality._reindent import (
25
+ inherited_prefix,
26
+ line_indent,
27
+ reindent,
28
+ )
25
29
  from openrewrite_code_quality_python.codequality._semantically_equal import SemanticallyEqual
26
30
 
27
31
  _CodeQuality = [
@@ -152,9 +156,6 @@ def _replace_identical_ifs_padded(padded_stmts) -> Optional[list]:
152
156
  Works on a list of JRightPadded[Statement] and returns a new padded list,
153
157
  or None if nothing changed.
154
158
  """
155
- from rewrite.java.support_types import JRightPadded
156
- from rewrite.markers import Markers
157
-
158
159
  result = []
159
160
  changed = False
160
161
  for rp in padded_stmts:
@@ -170,36 +171,34 @@ def _replace_identical_ifs_padded(padded_stmts) -> Optional[list]:
170
171
  result.append(rp)
171
172
  continue
172
173
 
173
- # Extract the body statements from the then_part Block.
174
174
  body = s.then_part
175
- if isinstance(body, Block) and body._statements:
176
- first = True
177
- for body_rp in body._statements:
178
- bs = body_rp.element
179
- if first:
180
- # First body statement gets the if statement's prefix
181
- new_elem = bs.replace(_prefix=s.prefix)
182
- result.append(rp.replace(_element=new_elem))
183
- first = False
184
- else:
185
- # Subsequent body statements keep their whitespace
186
- # but with one indent level removed
187
- ws = bs.prefix.whitespace
188
- if_ws = s.prefix.whitespace
189
- base = if_ws.split("\n")[-1] if "\n" in if_ws else if_ws
190
- body_indent = ws.split("\n")[-1] if "\n" in ws else ws
191
- if len(body_indent) > len(base):
192
- new_ws = ws.replace(body_indent, base, 1)
193
- else:
194
- new_ws = ws
195
- new_elem = bs.replace(_prefix=Space(
196
- _comments=bs.prefix.comments,
197
- _whitespace=new_ws,
198
- ))
199
- result.append(body_rp.replace(_element=new_elem))
200
- changed = True
201
- else:
175
+ if not isinstance(body, Block) or not body._statements:
202
176
  result.append(rp)
177
+ continue
178
+
179
+ if_indent = line_indent(s.prefix)
180
+ body_indent = line_indent(body._statements[0].element.prefix)
181
+ if (
182
+ if_indent is None
183
+ or body_indent is None
184
+ or not body_indent.startswith(if_indent)
185
+ ):
186
+ result.append(rp)
187
+ continue
188
+
189
+ body = reindent(body, body_indent, if_indent)
190
+ first = body._statements[0]
191
+ # Each lifted statement keeps its own padding, which is where a `;`
192
+ # separating it from the next one is recorded.
193
+ result.append(
194
+ first.replace(
195
+ _element=first.element.replace(
196
+ _prefix=inherited_prefix(s.prefix, first.element.prefix)
197
+ )
198
+ )
199
+ )
200
+ result.extend(body._statements[1:])
201
+ changed = True
203
202
 
204
203
  if not changed:
205
204
  return None
@@ -16,43 +16,61 @@ from rewrite.category import CategoryDescriptor
16
16
  from rewrite.decorators import categorize
17
17
  from rewrite.marketplace import Python
18
18
  from rewrite.markers import Markers
19
+ from rewrite.python.tree import StatementExpression
19
20
  from rewrite.python.visitor import PythonVisitor
20
21
  from rewrite.java.support_types import JLeftPadded, JRightPadded, Space
21
22
  from rewrite.java.tree import (
23
+ Assignment,
22
24
  Binary as JBinary,
23
25
  Block,
24
26
  ControlParentheses,
25
27
  Expression,
26
28
  If,
29
+ Lambda,
27
30
  Parentheses,
31
+ Ternary,
28
32
  )
29
33
  from rewrite.utils import random_id
30
34
 
35
+ from openrewrite_code_quality_python.codequality._reindent import (
36
+ inherited_prefix,
37
+ line_indent,
38
+ reindent,
39
+ )
40
+
31
41
  _CodeQuality = [
32
42
  *Python,
33
43
  CategoryDescriptor(display_name="Code quality"),
34
44
  ]
35
45
 
36
46
 
37
- def _contains_or(expr: Expression) -> bool:
38
- """Return True if the top-level expression is an ``or`` binary."""
39
- return isinstance(expr, JBinary) and expr.operator == JBinary.Type.Or
47
+ def _binds_looser_than_and(expr: Expression) -> bool:
48
+ """Return True for the operand forms that ``and`` would capture.
40
49
 
41
-
42
- def _dedent_block(block: Block, indent: str) -> Block:
43
- """Remove one level of *indent* from every statement in *block*."""
44
- if not indent:
45
- return block
46
- new_stmts = []
47
- for rp in block._statements:
48
- s = rp.element
49
- ws = s.prefix.whitespace
50
- if indent in ws:
51
- ws = ws.replace(indent, "", 1)
52
- s = s.replace(_prefix=Space(_comments=s.prefix.comments, _whitespace=ws))
53
- rp = rp.replace(_element=s)
54
- new_stmts.append(rp)
55
- return block.replace(_statements=new_stmts)
50
+ Everything below ``and`` in Python's precedence table: ``or``, the
51
+ conditional expression, ``lambda``, ``:=`` (a ``J.Assignment`` here) and
52
+ ``yield`` (a ``Py.StatementExpression``).
53
+ """
54
+ if isinstance(expr, JBinary):
55
+ return expr.operator == JBinary.Type.Or
56
+ return isinstance(expr, (Ternary, Lambda, Assignment, StatementExpression))
57
+
58
+
59
+ def _operand(expr: Expression, prefix: Space) -> Expression:
60
+ """Prepare *expr* as an operand of the merged ``and``, parenthesizing it
61
+ when its own operator would otherwise be captured."""
62
+ if _binds_looser_than_and(expr):
63
+ return Parentheses(
64
+ _id=random_id(),
65
+ _prefix=prefix,
66
+ _markers=Markers.EMPTY,
67
+ _tree=JRightPadded(
68
+ _element=expr.replace(_prefix=Space.EMPTY),
69
+ _after=Space.EMPTY,
70
+ _markers=Markers.EMPTY,
71
+ ),
72
+ )
73
+ return expr.replace(_prefix=prefix)
56
74
 
57
75
 
58
76
  @categorize(_CodeQuality)
@@ -129,36 +147,34 @@ class CollapsibleIfStatements(Recipe):
129
147
  if inner.else_part is not None:
130
148
  return if_
131
149
 
132
- outer_cond = if_.if_condition.tree
133
- inner_cond = inner.if_condition.tree
150
+ inner_body = inner.then_part
151
+ if not isinstance(inner_body, Block) or not inner_body.statements:
152
+ return if_
134
153
 
135
- # Wrap inner condition in parens if it contains `or`
136
- # to preserve precedence with the new `and`
137
- if _contains_or(inner_cond):
138
- inner_cond = Parentheses(
139
- _id=random_id(),
140
- _prefix=Space.SINGLE_SPACE,
141
- _markers=Markers.EMPTY,
142
- _tree=JRightPadded(
143
- _element=inner_cond.replace(_prefix=Space.EMPTY),
144
- _after=Space.EMPTY,
145
- _markers=Markers.EMPTY,
146
- ),
147
- )
148
- else:
149
- inner_cond = inner_cond.replace(_prefix=Space.SINGLE_SPACE)
154
+ # The body rises to where the inner `if` header sat, which is
155
+ # always deeper than the surviving header whatever the file's
156
+ # indent unit -- and is a line start even when the outer `if`
157
+ # is an `elif`, whose own prefix holds no newline.
158
+ header_indent = line_indent(inner.prefix)
159
+ body_indent = line_indent(inner_body.statements[0].prefix)
160
+ if (
161
+ header_indent is None
162
+ or body_indent is None
163
+ or not body_indent.startswith(header_indent)
164
+ ):
165
+ return if_
150
166
 
151
167
  combined = JBinary(
152
168
  _id=random_id(),
153
- _prefix=outer_cond.prefix,
169
+ _prefix=if_.if_condition.tree.prefix,
154
170
  _markers=Markers.EMPTY,
155
- _left=outer_cond.replace(_prefix=Space.EMPTY),
171
+ _left=_operand(if_.if_condition.tree, Space.EMPTY),
156
172
  _operator=JLeftPadded(
157
173
  _before=Space.SINGLE_SPACE,
158
174
  _element=JBinary.Type.And,
159
175
  _markers=Markers.EMPTY,
160
176
  ),
161
- _right=inner_cond,
177
+ _right=_operand(inner.if_condition.tree, Space.SINGLE_SPACE),
162
178
  _type=None,
163
179
  )
164
180
 
@@ -173,14 +189,21 @@ class CollapsibleIfStatements(Recipe):
173
189
  ),
174
190
  )
175
191
 
176
- # Dedent the inner body by one level since it was
177
- # nested inside the inner if that we're removing.
178
- inner_body = inner.then_part
179
- if isinstance(inner_body, Block):
180
- # The inner if's prefix tells us the indent unit
181
- ws = inner.prefix.whitespace
182
- indent = ws.split("\n")[-1] if "\n" in ws else ws
183
- inner_body = _dedent_block(inner_body, indent)
192
+ # One level per visit: a chain of three or more `if`s merges a
193
+ # level at a time, and each pass rebases the comments the
194
+ # previous one left at the level it dropped.
195
+ inner_body = reindent(inner_body, body_indent, header_indent)
196
+ first = inner_body._statements[0]
197
+ inner_body = inner_body.replace(
198
+ _statements=[
199
+ first.replace(
200
+ _element=first.element.replace(
201
+ _prefix=inherited_prefix(inner.prefix, first.element.prefix)
202
+ )
203
+ ),
204
+ *inner_body._statements[1:],
205
+ ]
206
+ )
184
207
 
185
208
  return if_.replace(
186
209
  _if_condition=new_condition,