openrewrite-migrate-python 0.17.0.dev20261022210307__tar.gz → 0.17.0.dev20261022214418__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 (231) hide show
  1. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/PKG-INFO +1 -1
  2. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/pyproject.toml +1 -1
  3. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/__init__.py +10 -2
  4. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_module_imports.py +4 -0
  5. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +96 -2
  6. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/cgi_escape_deprecations.py +12 -6
  7. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/glob_deprecations.py +11 -5
  8. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/module_cached_attribute.py +5 -3
  9. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/string_formatting.py +31 -13
  10. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +4 -4
  11. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +8 -0
  12. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/typing_functional_syntax.py +79 -20
  13. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +12 -0
  14. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +8 -1
  15. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python315.py +7 -2
  16. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +4 -1
  17. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +7 -7
  18. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +68 -2
  19. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python.egg-info/PKG-INFO +1 -1
  20. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_asyncio_deprecations.py +104 -0
  21. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_cgi_escape_deprecations.py +20 -0
  22. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_glob_deprecations.py +31 -10
  23. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_module_cached_attribute.py +2 -1
  24. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_profile_deprecations.py +7 -0
  25. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_string_formatting.py +52 -0
  26. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_tempfile_deprecations.py +1 -1
  27. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_typing_deprecations.py +21 -0
  28. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_typing_functional_syntax.py +37 -0
  29. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_typing_union_to_pipe.py +23 -0
  30. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_urllib_deprecations.py +1 -1
  31. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_xml_deprecations.py +62 -0
  32. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/setup.cfg +0 -0
  33. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/__init__.py +0 -0
  34. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/__init__.py +0 -0
  35. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/_literals.py +0 -0
  36. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/_negation.py +0 -0
  37. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/assign_return.py +0 -0
  38. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/attr_access.py +0 -0
  39. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/boolean_simplification.py +0 -0
  40. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/collection_literals.py +0 -0
  41. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/comparison_simplification.py +0 -0
  42. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/complex_transforms.py +0 -0
  43. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/comprehension_cleanup.py +0 -0
  44. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/conditionals.py +0 -0
  45. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/datetime_cleanup.py +0 -0
  46. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/dict_cleanup.py +0 -0
  47. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/exception_cleanup.py +0 -0
  48. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/expression_simplification.py +0 -0
  49. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/logger_warn.py +0 -0
  50. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/loop_cleanup.py +0 -0
  51. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/merge_nested_with.py +0 -0
  52. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/merge_startswith_endswith.py +0 -0
  53. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/naming_conventions.py +0 -0
  54. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/negated_operators.py +0 -0
  55. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/none_and_identity.py +0 -0
  56. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/object_inheritance.py +0 -0
  57. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/pandas_cleanup.py +0 -0
  58. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/python_best_practices.py +0 -0
  59. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/range_cleanup.py +0 -0
  60. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/redundant_code.py +0 -0
  61. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/remove_trailing_return_none.py +0 -0
  62. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/string_cleanup.py +0 -0
  63. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/unreachable_code.py +0 -0
  64. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/use_items.py +0 -0
  65. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/use_list_clear.py +0 -0
  66. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/cleanup/yoda_conditions.py +0 -0
  67. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/__init__.py +0 -0
  68. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/_reindent.py +0 -0
  69. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/_semantically_equal.py +0 -0
  70. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/_side_effects.py +0 -0
  71. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/_trivia.py +0 -0
  72. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/_truth_value.py +0 -0
  73. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/all_branches_identical.py +0 -0
  74. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/boolean_checks_not_inverted.py +0 -0
  75. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/code_quality.py +0 -0
  76. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/collapsible_if_statements.py +0 -0
  77. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/find_suspicious_chained_comparison.py +0 -0
  78. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/merge_identical_branches.py +0 -0
  79. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/remove_duplicate_conditions.py +0 -0
  80. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/remove_self_assignment.py +0 -0
  81. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/remove_unconditional_value_overwrite.py +0 -0
  82. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/simplify_boolean_literal.py +0 -0
  83. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_code_quality_python/codequality/simplify_redundant_logical_expression.py +0 -0
  84. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/__init__.py +0 -0
  85. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_decorators.py +0 -0
  86. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_finders.py +0 -0
  87. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_langchain_tables.py +0 -0
  88. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_markers.py +0 -0
  89. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_method_renames.py +0 -0
  90. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/_slots.py +0 -0
  91. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +0 -0
  92. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
  93. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
  94. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +0 -0
  95. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/avro_migrations.py +0 -0
  96. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/backoff_to_tenacity.py +0 -0
  97. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/builtins_deprecations.py +0 -0
  98. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
  99. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +0 -0
  100. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +0 -0
  101. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
  102. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
  103. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/ctypes_deprecations.py +0 -0
  104. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -0
  105. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +0 -0
  106. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +0 -0
  107. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +0 -0
  108. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/future_imports.py +0 -0
  109. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +0 -0
  110. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +0 -0
  111. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/http_server_deprecations.py +0 -0
  112. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/imp_migrations.py +0 -0
  113. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/importlib_deprecations.py +0 -0
  114. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/importlib_resources_deprecations.py +0 -0
  115. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/inspect_deprecations.py +0 -0
  116. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +0 -0
  117. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +0 -0
  118. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
  119. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +0 -0
  120. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +0 -0
  121. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +0 -0
  122. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +0 -0
  123. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +0 -0
  124. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/os_deprecations.py +0 -0
  125. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +0 -0
  126. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +0 -0
  127. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +0 -0
  128. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +0 -0
  129. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +0 -0
  130. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/profile_deprecations.py +0 -0
  131. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pydantic_deprecations.py +0 -0
  132. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pydantic_fields.py +0 -0
  133. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/pydantic_model_fields.py +0 -0
  134. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/re_deprecations.py +0 -0
  135. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
  136. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +0 -0
  137. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +0 -0
  138. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/sre_migrations.py +0 -0
  139. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +0 -0
  140. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +0 -0
  141. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +0 -0
  142. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +0 -0
  143. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +0 -0
  144. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/text_encoding.py +0 -0
  145. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
  146. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
  147. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/types_deprecations.py +0 -0
  148. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/typing_callable.py +0 -0
  149. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
  150. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
  151. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
  152. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_pandas.py +0 -0
  153. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_pydantic.py +0 -0
  154. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
  155. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
  156. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
  157. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
  158. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +0 -0
  159. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/uu_migrations.py +0 -0
  160. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/wave_deprecations.py +0 -0
  161. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/webbrowser_deprecations.py +0 -0
  162. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +0 -0
  163. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +0 -0
  164. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
  165. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
  166. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python.egg-info/requires.txt +0 -0
  167. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
  168. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_aifc_migrations.py +0 -0
  169. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_array_deprecations.py +0 -0
  170. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_ast_deprecations.py +0 -0
  171. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_asyncio_coroutine_to_async.py +0 -0
  172. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_avro_migrations.py +0 -0
  173. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_backoff_to_tenacity.py +0 -0
  174. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_builtins_deprecations.py +0 -0
  175. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_calendar_deprecations.py +0 -0
  176. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_cgi_parse_deprecations.py +0 -0
  177. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_change_import_recipes.py +0 -0
  178. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_collections_abc_migrations.py +0 -0
  179. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_configparser_deprecations.py +0 -0
  180. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_ctypes_deprecations.py +0 -0
  181. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_datetime_utc.py +0 -0
  182. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_distutils_deprecations.py +0 -0
  183. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_distutils_migrations.py +0 -0
  184. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_functools_deprecations.py +0 -0
  185. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_future_imports.py +0 -0
  186. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_gettext_deprecations.py +0 -0
  187. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_html_parser_deprecations.py +0 -0
  188. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_http_server_deprecations.py +0 -0
  189. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_imp_migrations.py +0 -0
  190. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_importlib_deprecations.py +0 -0
  191. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_importlib_resources_deprecations.py +0 -0
  192. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_inspect_deprecations.py +0 -0
  193. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_langchain_classic_imports.py +0 -0
  194. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_langchain_community_imports.py +0 -0
  195. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_langchain_provider_imports.py +0 -0
  196. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_locale_deprecations.py +0 -0
  197. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_locale_getdefaultlocale_deprecation.py +0 -0
  198. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_macpath_deprecations.py +0 -0
  199. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_mailcap_migrations.py +0 -0
  200. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_markers.py +0 -0
  201. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_os_deprecations.py +0 -0
  202. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pathlib_deprecations.py +0 -0
  203. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pep594_migrations.py +0 -0
  204. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pep594_system_migrations.py +0 -0
  205. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pkgutil_deprecations.py +0 -0
  206. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_platform_deprecations.py +0 -0
  207. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pydantic_deprecations.py +0 -0
  208. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pydantic_fields.py +0 -0
  209. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_pydantic_model_fields.py +0 -0
  210. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_re_deprecations.py +0 -0
  211. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_removed_modules_312.py +0 -0
  212. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_shutil_deprecations.py +0 -0
  213. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_socket_deprecations.py +0 -0
  214. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_sre_migrations.py +0 -0
  215. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_ssl_deprecations.py +0 -0
  216. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_sys_deprecations.py +0 -0
  217. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_sys_last_deprecations.py +0 -0
  218. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_tarfile_deprecations.py +0 -0
  219. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_text_encoding.py +0 -0
  220. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_threading_deprecations.py +0 -0
  221. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_threading_extended.py +0 -0
  222. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_threading_is_alive_deprecation.py +0 -0
  223. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_types_deprecations.py +0 -0
  224. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_typing_alias_moves.py +0 -0
  225. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_typing_callable.py +0 -0
  226. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_unittest_deprecations.py +0 -0
  227. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_upgrade_recipes.py +0 -0
  228. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_upgrade_to_pydantic.py +0 -0
  229. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_wave_deprecations.py +0 -0
  230. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_webbrowser_deprecations.py +0 -0
  231. {openrewrite_migrate_python-0.17.0.dev20261022210307 → openrewrite_migrate_python-0.17.0.dev20261022214418}/tests/test_xdrlib_migrations.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openrewrite-migrate-python
3
- Version: 0.17.0.dev20261022210307
3
+ Version: 0.17.0.dev20261022214418
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
@@ -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.17.0.dev20261022210307" # Updated dynamically during release
8
+ version = "0.17.0.dev20261022214418" # 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"
@@ -32,6 +32,7 @@ from .asyncio_coroutine_to_async import MigrateAsyncioCoroutine
32
32
  from .asyncio_deprecations import (
33
33
  FindAsyncioCoroutineDecorator,
34
34
  FindAsyncioEventLoopPolicy,
35
+ ReplaceAsyncioGetEventLoop,
35
36
  ReplaceAsyncioIscoroutinefunction,
36
37
  )
37
38
  from .avro_migrations import MigrateAvroPython3ToAvro
@@ -129,7 +130,11 @@ from .typing_deprecations import (
129
130
  ReplaceTypingTupleWithTuple,
130
131
  ReplaceTypingTypeWithType,
131
132
  )
132
- from .typing_functional_syntax import ReplaceNamedTupleKeywordFields, ReplaceTypedDictWithoutFields
133
+ from .typing_functional_syntax import (
134
+ ReplaceNamedTupleKeywordFields,
135
+ ReplaceNamedTupleWithoutFields,
136
+ ReplaceTypedDictWithoutFields,
137
+ )
133
138
  from .typing_union_to_pipe import (
134
139
  ReplaceTypingOptionalWithUnion,
135
140
  ReplaceTypingUnionWithPipe,
@@ -156,7 +161,7 @@ from .uu_migrations import FindUuModule
156
161
  from .wave_deprecations import FindWaveMarkers
157
162
  from .webbrowser_deprecations import FindWebbrowserMacOSXOSAScript
158
163
  from .xdrlib_migrations import FindXdrlibModule
159
- from .xml_deprecations import ReplaceElementGetchildren, ReplaceElementGetiterator
164
+ from .xml_deprecations import ReplaceCElementTree, ReplaceElementGetchildren, ReplaceElementGetiterator
160
165
 
161
166
  __all__ = [
162
167
  # String formatting auto-fix recipes
@@ -173,6 +178,7 @@ __all__ = [
173
178
  "FindCryptModule",
174
179
  "FindDistutilsUsage",
175
180
  "ReplaceElementGetchildren",
181
+ "ReplaceCElementTree",
176
182
  "FindFunctoolsCmpToKey",
177
183
  "RemoveFutureImports",
178
184
  "ReplaceHtmlParserUnescape",
@@ -274,6 +280,7 @@ __all__ = [
274
280
  "ReplaceModuleCachedAttribute",
275
281
  "ReplaceNamedTupleKeywordFields",
276
282
  "ReplaceTypedDictWithoutFields",
283
+ "ReplaceNamedTupleWithoutFields",
277
284
  # Detection: Python 3.15
278
285
  "FindCgiHttpRequestHandler",
279
286
  "FindCodeObjectCoLnotab",
@@ -288,6 +295,7 @@ __all__ = [
288
295
  "FindWaveMarkers",
289
296
  # Auto-fix: Python 3.16 and 3.17 removals
290
297
  "ReplaceAsyncioIscoroutinefunction",
298
+ "ReplaceAsyncioGetEventLoop",
291
299
  # Detection: Python 3.16 and 3.17 removals
292
300
  "FindArrayUnicodeTypecode",
293
301
  "FindAsyncioEventLoopPolicy",
@@ -4,6 +4,7 @@ from typing import Any, Dict
4
4
 
5
5
  from rewrite import ExecutionContext, Preconditions, TreeVisitor
6
6
  from rewrite.java.tree import Import, J
7
+ from rewrite.python.binding_utils import dotted_path
7
8
  from rewrite.python.import_utils import get_name_string, get_qualid_name
8
9
  from rewrite.python.preconditions import uses_import
9
10
  from rewrite.python.tree import MultiImport
@@ -34,6 +35,9 @@ def find_imports_of_modules(
34
35
  if not isinstance(mi, MultiImport):
35
36
  return mi
36
37
  if mi.from_ is not None:
38
+ if dotted_path(mi.from_).startswith("."):
39
+ # A relative import names a module of the project, never the standard library's.
40
+ return mi
37
41
  package = get_name_string(mi.from_)
38
42
  # `from a import b` imports the submodule `a.b` where one exists.
39
43
  found = module_of(package) or next(filter(None, (
@@ -16,6 +16,9 @@ becomes:
16
16
  ``asyncio.iscoroutinefunction()`` and the event loop policy system were
17
17
  deprecated in Python 3.14 and are scheduled for removal in Python 3.16.
18
18
 
19
+ ``asyncio.get_event_loop()`` raises a ``RuntimeError`` in Python 3.14 where no
20
+ event loop is set, rather than creating one.
21
+
19
22
  See: https://docs.python.org/3/library/asyncio-task.html
20
23
  See: https://docs.python.org/3/deprecations/pending-removal-in-3.16.html
21
24
  """
@@ -27,10 +30,20 @@ from rewrite.category import CategoryDescriptor
27
30
  from rewrite.decorators import categorize
28
31
  from rewrite.marketplace import Python
29
32
  from rewrite.python.binding_utils import import_bindings
30
- from rewrite.python.preconditions import uses_import
33
+ from rewrite.python.method_matcher import MethodMatcher
34
+ from rewrite.python.preconditions import uses_import, uses_method
31
35
  from rewrite.python.recipes import ChangeImport
32
36
  from rewrite.python.visitor import PythonVisitor
33
- from rewrite.java.tree import FieldAccess, Identifier, J
37
+ from rewrite.java.tree import (
38
+ ClassDeclaration,
39
+ FieldAccess,
40
+ Identifier,
41
+ J,
42
+ Lambda,
43
+ MethodDeclaration,
44
+ MethodInvocation,
45
+ Modifier,
46
+ )
34
47
  from ._finders import find_member_references
35
48
  from ._markers import mark_deprecated
36
49
 
@@ -220,3 +233,84 @@ class FindAsyncioEventLoopPolicy(Recipe):
220
233
 
221
234
  def editor(self) -> TreeVisitor[Any, ExecutionContext]:
222
235
  return find_member_references({f"asyncio.{member}": _POLICY_MESSAGE for member in _POLICY_MEMBERS})
236
+
237
+
238
+ # typeshed declares `get_event_loop` in the `_asyncio` accelerator and `asyncio.events`, and
239
+ # `asyncio` re-exports it.
240
+ _GET_EVENT_LOOP = ["asyncio get_event_loop()", "asyncio.events get_event_loop()", "_asyncio get_event_loop()"]
241
+ _GET_EVENT_LOOP_MATCHERS = [MethodMatcher.create(p) for p in _GET_EVENT_LOOP]
242
+ _GET_EVENT_LOOP_MESSAGE = (
243
+ "asyncio.get_event_loop() raises a RuntimeError from Python 3.14 where no event loop is set, "
244
+ "instead of creating one. Use asyncio.run(), or asyncio.new_event_loop() with "
245
+ "asyncio.set_event_loop()."
246
+ )
247
+
248
+
249
+ def _in_coroutine(cursor: Any) -> bool:
250
+ """Whether the code at ``cursor`` runs in the body of an ``async def`` itself."""
251
+ for node in cursor.get_path():
252
+ if isinstance(node, (Lambda, ClassDeclaration)):
253
+ return False
254
+ if isinstance(node, MethodDeclaration):
255
+ return any(m.type == Modifier.Type.Async for m in node.modifiers)
256
+ return False
257
+
258
+
259
+ @categorize(_Python314)
260
+ class ReplaceAsyncioGetEventLoop(Recipe):
261
+ """
262
+ Replace `asyncio.get_event_loop()` in a coroutine with
263
+ `asyncio.get_running_loop()`, and find it elsewhere.
264
+
265
+ Python 3.14 no longer creates an event loop in `get_event_loop()`, and
266
+ raises a `RuntimeError` where none is set. A coroutine always runs in a
267
+ loop, which `get_running_loop()` returns.
268
+
269
+ Example:
270
+ Before:
271
+ import asyncio
272
+
273
+ async def fetch():
274
+ loop = asyncio.get_event_loop()
275
+
276
+ After:
277
+ import asyncio
278
+
279
+ async def fetch():
280
+ loop = asyncio.get_running_loop()
281
+ """
282
+
283
+ @property
284
+ def name(self) -> str:
285
+ return "org.openrewrite.python.migrate.ReplaceAsyncioGetEventLoop"
286
+
287
+ @property
288
+ def display_name(self) -> str:
289
+ return "Replace `asyncio.get_event_loop()` with `asyncio.get_running_loop()` in coroutines"
290
+
291
+ @property
292
+ def description(self) -> str:
293
+ return (
294
+ "`asyncio.get_event_loop()` raises a `RuntimeError` in Python 3.14 where no event loop is "
295
+ "set, rather than creating one. In the body of an `async def`, where a loop is always "
296
+ "running, the call is replaced with `asyncio.get_running_loop()`. Elsewhere it is marked "
297
+ "for review, as is a call through a name imported with `from asyncio import get_event_loop`."
298
+ )
299
+
300
+ @property
301
+ def tags(self) -> List[str]:
302
+ return ["python", "migration", "3.14", "asyncio"]
303
+
304
+ def editor(self) -> TreeVisitor[Any, ExecutionContext]:
305
+ class Visitor(PythonVisitor[ExecutionContext]):
306
+ def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
307
+ m = super().visit_method_invocation(method, p)
308
+ if not isinstance(m, MethodInvocation) or not any(
309
+ mm.matches(m, cursor=self.cursor) for mm in _GET_EVENT_LOOP_MATCHERS
310
+ ):
311
+ return m
312
+ if m.select is not None and _in_coroutine(self.cursor):
313
+ return m.replace(_name=m.name.replace(_simple_name="get_running_loop"))
314
+ return mark_deprecated(m, _GET_EVENT_LOOP_MESSAGE)
315
+
316
+ return Preconditions.check(Preconditions.or_(*(uses_method(p) for p in _GET_EVENT_LOOP)), Visitor())
@@ -80,7 +80,8 @@ class ReplaceCgiEscape(Recipe):
80
80
  "`html.escape()` escapes quotes by default and `cgi.escape()` did not. An explicit "
81
81
  "`quote` argument is kept as it is. A file that also refers to `cgi.escape` other than "
82
82
  "by calling it, or calls it with unpacked `*args` or `**kwargs`, is left as it is, with "
83
- "those references marked for a manual change. A file that never calls it is not visited."
83
+ "those references marked for a manual change, as are the calls in a file that binds `html` "
84
+ "to something else. A file that never calls it is not visited."
84
85
  )
85
86
 
86
87
  @property
@@ -90,15 +91,16 @@ class ReplaceCgiEscape(Recipe):
90
91
  def editor(self) -> TreeVisitor[Any, ExecutionContext]:
91
92
  class Visitor(PythonVisitor[ExecutionContext]):
92
93
  unsafe: Set[Any] = set()
94
+ rebound = False
93
95
 
94
96
  def visit_compilation_unit(self, cu: CompilationUnit, p: ExecutionContext) -> J:
95
97
  finder = _EscapeReferences()
96
98
  finder.visit(cu, p)
97
99
  self.unsafe = finder.unsafe
98
- visited = super().visit_compilation_unit(cu, p)
99
- if finder.found and not finder.unsafe:
100
- maybe_rebind(self, "cgi", "html", from_member="escape")
101
- return visited
100
+ # Refused where the move can't be expressed, as when the file binds `html` itself.
101
+ self.rebound = (finder.found and not finder.unsafe
102
+ and maybe_rebind(self, "cgi", "html", from_member="escape") is not None)
103
+ return super().visit_compilation_unit(cu, p)
102
104
 
103
105
  def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
104
106
  m = super().visit_method_invocation(method, p)
@@ -106,7 +108,11 @@ class ReplaceCgiEscape(Recipe):
106
108
  return m
107
109
  if self.unsafe:
108
110
  return mark_deprecated(m, _MANUAL) if m.id in self.unsafe else m
109
- if not _ESCAPE.matches(m, cursor=self.cursor) or not _relies_on_default_quote(m):
111
+ if not _ESCAPE.matches(m, cursor=self.cursor):
112
+ return m
113
+ if not self.rebound:
114
+ return mark_deprecated(m, _MANUAL)
115
+ if not _relies_on_default_quote(m):
110
116
  return m
111
117
  quote = _quote_false(self.cursor)
112
118
  if quote is None:
@@ -24,6 +24,7 @@ from rewrite.python.tree import NamedArgument
24
24
  from rewrite.python.visitor import PythonVisitor
25
25
 
26
26
  from ._finders import find_calls
27
+ from ._markers import mark_deprecated
27
28
 
28
29
  # Define category path: Python > Migrate > Python 3.15
29
30
  _Python315 = [
@@ -38,6 +39,11 @@ _GLOB1_MATCHER = MethodMatcher.create(_GLOB1)
38
39
  _dirname = capture("dirname")
39
40
  _pattern = capture("pattern")
40
41
  _GLOB = template(f"glob.glob({_pattern}, root_dir={_dirname})", context=["import glob"])
42
+ _GLOB1_MESSAGE = (
43
+ "glob.glob1() was removed in Python 3.15. Use glob.glob(pattern, root_dir=dirname), which also "
44
+ "matches a pattern's path separators and checks a pattern without wildcards case-insensitively "
45
+ "where the filesystem is."
46
+ )
41
47
 
42
48
 
43
49
  def _matches_like_glob1(pattern: J) -> bool:
@@ -86,8 +92,8 @@ class ReplaceGlobGlob1(Recipe):
86
92
  "The undocumented `glob.glob1()` was removed in Python 3.15. Replace "
87
93
  "`glob1(dirname, pattern)` with `glob.glob(pattern, root_dir=dirname)`, which returns "
88
94
  "the same names. Only calls whose pattern is a string literal with a wildcard and no path "
89
- "separator are rewritten; calls passing keyword arguments or any other pattern are left "
90
- "unchanged."
95
+ "separator are rewritten; calls passing keyword arguments or any other pattern are marked "
96
+ "for review."
91
97
  )
92
98
 
93
99
  @property
@@ -102,14 +108,14 @@ class ReplaceGlobGlob1(Recipe):
102
108
  return m
103
109
  args = m.arguments
104
110
  if len(args) != 2 or any(isinstance(a, NamedArgument) for a in args) or not _matches_like_glob1(args[1]):
105
- return m
111
+ return mark_deprecated(m, _GLOB1_MESSAGE)
106
112
  try:
107
113
  replaced = _GLOB.apply(self.cursor, visitor=self, values={"dirname": args[0], "pattern": args[1]})
108
114
  except ValueError:
109
115
  # The template refuses a file where `glob` is bound to something else.
110
- return m
116
+ replaced = None
111
117
  if replaced is None:
112
- return m
118
+ return mark_deprecated(m, _GLOB1_MESSAGE)
113
119
  maybe_remove_import(self, RemoveImportOptions(module="glob", name="glob1", only_if_unused=True))
114
120
  return replaced
115
121
 
@@ -29,7 +29,8 @@ _Python315 = [
29
29
 
30
30
  _CACHED = "__cached__"
31
31
  _module = capture("module")
32
- _OWN_SPEC = template("__spec__.cached")
32
+ # A module run as a script has no spec, where `__cached__` was None.
33
+ _OWN_SPEC = template('getattr(__spec__, "cached", None)')
33
34
  _MODULE_SPEC = template(f"{_module}.__spec__.cached")
34
35
 
35
36
 
@@ -45,7 +46,7 @@ class ReplaceModuleCachedAttribute(Recipe):
45
46
 
46
47
  After:
47
48
  import os
48
- print(__spec__.cached, os.__spec__.cached)
49
+ print(getattr(__spec__, "cached", None), os.__spec__.cached)
49
50
  """
50
51
 
51
52
  @property
@@ -61,7 +62,8 @@ class ReplaceModuleCachedAttribute(Recipe):
61
62
  return (
62
63
  "The import system no longer sets a module's `__cached__` attribute in Python 3.15. "
63
64
  "Read `__spec__.cached` instead. Rewrites the bare name where the file does not assign "
64
- "it, and the attribute on a module an import binds or whose type resolves to a module."
65
+ "it, through `getattr` since a module run as a script has no `__spec__`, and the attribute "
66
+ "on a module an import binds or whose type resolves to a module."
65
67
  )
66
68
 
67
69
  @property
@@ -22,7 +22,7 @@ from rewrite.python.method_matcher import MethodMatcher
22
22
  from rewrite.python.preconditions import uses_method
23
23
  from rewrite.python.visitor import PythonVisitor
24
24
  from rewrite.java.support_types import JavaType, JRightPadded, Space
25
- from rewrite.java.tree import Binary, Expression, J, Literal, MethodInvocation, Parentheses
25
+ from rewrite.java.tree import Binary, Empty, Expression, J, Literal, MethodInvocation, Parentheses
26
26
  from rewrite.python.printer import PrintOutputCapture, PythonPrinter
27
27
  from rewrite.python.type_utils import is_of_class_type
28
28
  from rewrite.python.tree import (
@@ -229,22 +229,40 @@ def _convert_format_to_fstring(method: MethodInvocation) -> FormattedString | No
229
229
  for arg in raw_args:
230
230
  if isinstance(arg, NamedArgument):
231
231
  named_args[arg.name.simple_name] = arg.value
232
- else:
232
+ elif not isinstance(arg, Empty):
233
233
  positional_args.append(arg)
234
234
 
235
- # Check repeated explicit positional indices with side-effect expressions
236
- index_usage: dict[int, int] = {}
237
- for _, field_name, _, _ in parsed:
238
- if field_name is not None and field_name.isdigit():
239
- idx = int(field_name)
240
- index_usage[idx] = index_usage.get(idx, 0) + 1
241
-
242
- for idx, count in index_usage.items():
243
- if count > 1:
244
- if idx >= len(positional_args):
235
+ field_names = [f for _, f, _, _ in parsed if f is not None]
236
+ if '' in field_names and any(f.isdigit() for f in field_names):
237
+ # `str.format` raises on mixed automatic and manual numbering.
238
+ return None
239
+ references: List[Expression] = []
240
+ next_auto = 0
241
+ for field_name in field_names:
242
+ if field_name == '':
243
+ if next_auto >= len(positional_args):
245
244
  return None
246
- if not is_side_effect_free(positional_args[idx]):
245
+ references.append(positional_args[next_auto])
246
+ next_auto += 1
247
+ elif field_name.isdigit():
248
+ if int(field_name) >= len(positional_args):
247
249
  return None
250
+ references.append(positional_args[int(field_name)])
251
+ elif field_name in named_args:
252
+ references.append(named_args[field_name])
253
+ else:
254
+ return None
255
+
256
+ # `.format` evaluates every argument once, in order; the f-string evaluates each field in turn.
257
+ evaluated = positional_args + list(named_args.values())
258
+ first_uses = list({id(r): r for r in references}.values())
259
+ if len(first_uses) != len(evaluated):
260
+ # An argument no field uses would no longer be evaluated, nor raise.
261
+ return None
262
+ if (len(references) != len(evaluated) or any(a is not b for a, b in zip(first_uses, evaluated))) and not all(
263
+ is_side_effect_free(a) for a in evaluated
264
+ ):
265
+ return None
248
266
 
249
267
  # Build f-string parts
250
268
  parts: List[Expression] = []
@@ -2,8 +2,8 @@
2
2
  Recipes for migrating deprecated tempfile module functions.
3
3
 
4
4
  tempfile.mktemp() has been deprecated since Python 2.3 due to security
5
- concerns (race condition between file creation and use). It was removed
6
- in Python 3.14.
5
+ concerns (race condition between file creation and use). It still exists,
6
+ but the documentation recommends against it.
7
7
 
8
8
  Alternatives:
9
9
  - tempfile.mkstemp() - returns (fd, name) tuple
@@ -41,7 +41,7 @@ class FindTempfileMktemp(Recipe):
41
41
  Find usage of `tempfile.mktemp()`.
42
42
 
43
43
  The `mktemp()` function was deprecated in Python 2.3 due to a security
44
- vulnerability (race condition) and removed in Python 3.14.
44
+ vulnerability (race condition).
45
45
 
46
46
  Alternatives:
47
47
  - Use `tempfile.mkstemp()` which returns (fd, name) and creates the file
@@ -89,7 +89,7 @@ class FindTempfileMktemp(Recipe):
89
89
  return m
90
90
  return mark_deprecated(
91
91
  m,
92
- "tempfile.mktemp() is deprecated (security issue) and removed in Python 3.14. "
92
+ "tempfile.mktemp() is deprecated because the name it returns can be taken before it is used. "
93
93
  "Use tempfile.mkstemp() or NamedTemporaryFile() instead."
94
94
  )
95
95
 
@@ -32,6 +32,7 @@ from rewrite.marketplace import Python
32
32
  from rewrite.python.binding_utils import import_bindings
33
33
  from rewrite.python.import_utils import referenced_names
34
34
  from rewrite.python.markers import Quoted
35
+ from rewrite.python.scope_utils import scope_of
35
36
  from rewrite.visitor import Cursor
36
37
 
37
38
  from rewrite.python.tree import (
@@ -210,6 +211,7 @@ def _make_builtin_alias_editor(
210
211
  if (
211
212
  binding is not None and binding.module == "typing" and binding.member is None
212
213
  and (not type_positions_only or _in_type_position(self.cursor))
214
+ and not self._shadowed()
213
215
  ):
214
216
  self._rewrote_qualified = True
215
217
  return field_access.name.replace(_simple_name=new_name, _type=None, _field_type=None).replace(
@@ -232,8 +234,14 @@ def _make_builtin_alias_editor(
232
234
  return ident
233
235
  if type_positions_only and not _in_type_position(self.cursor):
234
236
  return ident
237
+ if self._shadowed():
238
+ return ident
235
239
  return ident.replace(_simple_name=new_name, _type=None, _field_type=None)
236
240
 
241
+ def _shadowed(self) -> bool:
242
+ """Whether the file binds the builtin's name where the cursor stands, as a `list` command does."""
243
+ return scope_of(self.cursor).declaring_scope(new_name) is not None
244
+
237
245
  return BuiltinAliasVisitor()
238
246
 
239
247
 
@@ -4,6 +4,7 @@ Python 3.15.
4
4
 
5
5
  - `NamedTuple("P", x=int)`, the undocumented keyword-argument syntax
6
6
  - `TypedDict("TD")` and `TypedDict("TD", None)`, a `TypedDict` with no fields
7
+ - `NamedTuple("NT")` and `NamedTuple("NT", None)`, a `NamedTuple` with no fields
7
8
 
8
9
  See: https://docs.python.org/3/whatsnew/3.15.html#typing
9
10
  """
@@ -58,6 +59,35 @@ def _is_none(arg: J) -> bool:
58
59
  )
59
60
 
60
61
 
62
+ # Keywords `TypedDict` takes as options. Any other keyword names a field, in the syntax
63
+ # Python 3.13 removed, so passing it alongside `{}` raises.
64
+ _TYPED_DICT_OPTIONS = frozenset({"total", "closed", "extra_items"})
65
+
66
+
67
+ def _pass_empty_fields(visitor: PythonVisitor, call: MethodInvocation, empty: str, options: frozenset[str]) -> J:
68
+ """``call`` with ``empty`` passed as its fields, where it passes none or ``None``."""
69
+ # A call without arguments holds a single `Empty`.
70
+ positional = [a for a in call.arguments if not isinstance(a, (NamedArgument, Empty))]
71
+ keywords = [a for a in call.arguments if isinstance(a, NamedArgument)]
72
+ fields: Optional[J] = positional[1] if len(positional) == 2 else None
73
+ if (
74
+ len(positional) not in (1, 2)
75
+ or (fields is not None and not _is_none(fields))
76
+ or call.arguments[: len(positional)] != positional
77
+ or not all(isinstance(k.name, Identifier) and k.name.simple_name in options for k in keywords)
78
+ or has_comments(call)
79
+ ):
80
+ return call
81
+ values: Dict[str, Any] = {"typename": positional[0]}
82
+ arguments = [f"{capture('typename')}", empty]
83
+ for index, keyword in enumerate(keywords):
84
+ assert isinstance(keyword.name, Identifier)
85
+ key = f"keyword{index}"
86
+ values[key] = keyword.value
87
+ arguments.append(f"{keyword.name.simple_name}={capture(key)}")
88
+ return _rebuild_call(visitor, call, ", ".join(arguments), values)
89
+
90
+
61
91
  @categorize(_Python315)
62
92
  class ReplaceNamedTupleKeywordFields(Recipe):
63
93
  """
@@ -162,25 +192,54 @@ class ReplaceTypedDictWithoutFields(Recipe):
162
192
  m = super().visit_method_invocation(method, p)
163
193
  if not isinstance(m, MethodInvocation) or not _TYPED_DICT_MATCHER.matches(m, cursor=self.cursor):
164
194
  return m
165
- # A call without arguments holds a single `Empty`.
166
- positional = [a for a in m.arguments if not isinstance(a, (NamedArgument, Empty))]
167
- keywords = [a for a in m.arguments if isinstance(a, NamedArgument)]
168
- fields: Optional[J] = positional[1] if len(positional) == 2 else None
169
- if (
170
- len(positional) not in (1, 2)
171
- or (fields is not None and not _is_none(fields))
172
- or m.arguments[: len(positional)] != positional
173
- or not all(isinstance(k.name, Identifier) for k in keywords)
174
- or has_comments(m)
175
- ):
176
- return m
177
- values: Dict[str, Any] = {"typename": positional[0]}
178
- arguments = [f"{capture('typename')}", "{}"]
179
- for index, keyword in enumerate(keywords):
180
- assert isinstance(keyword.name, Identifier)
181
- key = f"keyword{index}"
182
- values[key] = keyword.value
183
- arguments.append(f"{keyword.name.simple_name}={capture(key)}")
184
- return _rebuild_call(self, m, ", ".join(arguments), values)
195
+ return _pass_empty_fields(self, m, "{}", _TYPED_DICT_OPTIONS)
185
196
 
186
197
  return Preconditions.check(uses_method(_TYPED_DICT), Visitor())
198
+
199
+
200
+ @categorize(_Python315)
201
+ class ReplaceNamedTupleWithoutFields(Recipe):
202
+ """
203
+ Pass an empty list to a functional `NamedTuple` with no fields.
204
+
205
+ Example:
206
+ Before:
207
+ from typing import NamedTuple
208
+
209
+ Empty = NamedTuple("Empty")
210
+
211
+ After:
212
+ from typing import NamedTuple
213
+
214
+ Empty = NamedTuple("Empty", [])
215
+ """
216
+
217
+ @property
218
+ def name(self) -> str:
219
+ return "org.openrewrite.python.migrate.ReplaceNamedTupleWithoutFields"
220
+
221
+ @property
222
+ def display_name(self) -> str:
223
+ return "Pass `[]` to a `NamedTuple` with no fields"
224
+
225
+ @property
226
+ def description(self) -> str:
227
+ return (
228
+ "`NamedTuple(\"NT\")` and `NamedTuple(\"NT\", None)` raise a `TypeError` in Python 3.15. "
229
+ "Pass an empty list, as in `NamedTuple(\"NT\", [])`. Calls holding comments are left "
230
+ "unchanged."
231
+ )
232
+
233
+ @property
234
+ def tags(self) -> List[str]:
235
+ return ["python", "migration", "3.15", "typing"]
236
+
237
+ def editor(self) -> TreeVisitor[Any, ExecutionContext]:
238
+ class Visitor(PythonVisitor[ExecutionContext]):
239
+ def visit_method_invocation(self, method: MethodInvocation, p: ExecutionContext) -> J:
240
+ m = super().visit_method_invocation(method, p)
241
+ if not isinstance(m, MethodInvocation) or not _NAMED_TUPLE_MATCHER.matches(m, cursor=self.cursor):
242
+ return m
243
+ return _pass_empty_fields(self, m, "[]", frozenset())
244
+
245
+ return Preconditions.check(uses_method(_NAMED_TUPLE), Visitor())
@@ -47,6 +47,16 @@ _Python310 = [
47
47
  ]
48
48
 
49
49
 
50
+ # Builtin functions, not classes, so `|` raises a TypeError on them before Python 3.14's deferred
51
+ # annotations; `Optional[callable]` and `Optional[any]` are slips for `Callable` and `Any`.
52
+ _BUILTIN_FUNCTIONS = frozenset({
53
+ "abs", "aiter", "all", "anext", "any", "ascii", "bin", "breakpoint", "callable", "chr", "compile",
54
+ "delattr", "dir", "divmod", "eval", "exec", "format", "getattr", "globals", "hasattr", "hash", "hex",
55
+ "id", "input", "isinstance", "issubclass", "iter", "len", "locals", "max", "min", "next", "oct",
56
+ "open", "ord", "pow", "print", "repr", "round", "setattr", "sorted", "sum", "vars",
57
+ })
58
+
59
+
50
60
  class _PipeSyntaxVisitor(PythonVisitor[ExecutionContext]):
51
61
  """Base for the PEP 604 visitors: resolving the typing member and the shared guards."""
52
62
 
@@ -68,12 +78,14 @@ class _PipeSyntaxVisitor(PythonVisitor[ExecutionContext]):
68
78
 
69
79
  A string forward reference (a ``Quoted``-marked identifier or a string
70
80
  literal) would evaluate ``"Foo" | X`` at runtime and raise TypeError.
81
+ A builtin function such as ``callable`` raises the same TypeError.
71
82
  The rebuilt union keeps only the subscript's own prefix, so a comment
72
83
  anywhere else in it would be lost.
73
84
  """
74
85
  return not has_comments(subscript.replace(prefix=Space.EMPTY)) and not any(
75
86
  (isinstance(arg, Literal) and isinstance(arg.value, str))
76
87
  or arg.markers.find_first(Quoted) is not None
88
+ or (isinstance(arg, Identifier) and arg.simple_name in _BUILTIN_FUNCTIONS)
77
89
  for arg in args
78
90
  )
79
91
 
@@ -25,6 +25,8 @@ class UpgradeToPython314(Recipe):
25
25
  removed (deprecated since 3.8, use ``ast.Constant`` instead)
26
26
  - ``tempfile.mktemp()``, deprecated since 2.3 as unsafe, is flagged (use ``mkstemp()``)
27
27
  - ``urllib.parse`` split functions, deprecated since 3.8, are flagged
28
+ - ``asyncio.get_event_loop()`` no longer creates a loop; in coroutines it becomes
29
+ ``asyncio.get_running_loop()``, and elsewhere it is flagged
28
30
 
29
31
  See: https://docs.python.org/3/whatsnew/3.14.html
30
32
  """
@@ -59,7 +61,11 @@ class UpgradeToPython314(Recipe):
59
61
  ReplaceAstNum,
60
62
  ReplaceAstStr,
61
63
  )
62
- from .asyncio_deprecations import FindAsyncioEventLoopPolicy, ReplaceAsyncioIscoroutinefunction
64
+ from .asyncio_deprecations import (
65
+ FindAsyncioEventLoopPolicy,
66
+ ReplaceAsyncioGetEventLoop,
67
+ ReplaceAsyncioIscoroutinefunction,
68
+ )
63
69
  from .tempfile_deprecations import FindTempfileMktemp
64
70
  from .upgrade_to_python313 import UpgradeToPython313
65
71
  from .urllib_deprecations import (
@@ -83,6 +89,7 @@ class UpgradeToPython314(Recipe):
83
89
  FindUrllibParseToBytes(),
84
90
  # Deprecated in 3.14, removed in 3.16
85
91
  ReplaceAsyncioIscoroutinefunction(),
92
+ ReplaceAsyncioGetEventLoop(),
86
93
  FindAsyncioEventLoopPolicy(),
87
94
  # Target version in project metadata, packaging, Dockerfiles, CI, docs and infrastructure files
88
95
  RpcRecipe("org.openrewrite.python.migrate.UpgradePythonVersionTo314"),