openrewrite-migrate-python 0.1.1__tar.gz → 0.2.0__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 (116) hide show
  1. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/PKG-INFO +2 -2
  2. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/pyproject.toml +2 -2
  3. openrewrite_migrate_python-0.2.0/src/openrewrite_migrate_python/migrate/_markers.py +16 -0
  4. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/aifc_migrations.py +19 -29
  5. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/asyncio_deprecations.py +2 -13
  6. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/cgi_migrations.py +7 -17
  7. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/cgi_parse_deprecations.py +3 -13
  8. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/distutils_deprecations.py +2 -13
  9. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/distutils_migrations.py +2 -13
  10. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/functools_deprecations.py +2 -12
  11. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/html_parser_deprecations.py +2 -12
  12. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/imp_migrations.py +4 -15
  13. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/langchain_classic_imports.py +3 -13
  14. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/locale_getdefaultlocale_deprecation.py +2 -12
  15. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/macpath_deprecations.py +4 -14
  16. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/mailcap_migrations.py +4 -14
  17. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/nntplib_migrations.py +4 -14
  18. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/os_deprecations.py +3 -13
  19. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/pathlib_deprecations.py +2 -12
  20. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/pep594_system_migrations.py +16 -26
  21. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/pipes_migrations.py +4 -14
  22. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/pkgutil_deprecations.py +3 -14
  23. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/platform_deprecations.py +2 -12
  24. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/re_deprecations.py +3 -13
  25. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/shutil_deprecations.py +2 -12
  26. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/socket_deprecations.py +2 -12
  27. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/ssl_deprecations.py +2 -13
  28. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/sys_deprecations.py +2 -12
  29. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/sys_last_deprecations.py +2 -12
  30. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/tarfile_deprecations.py +3 -13
  31. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/telnetlib_migrations.py +4 -14
  32. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/tempfile_deprecations.py +2 -12
  33. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/typing_callable.py +3 -14
  34. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/typing_deprecations.py +5 -16
  35. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/urllib_deprecations.py +4 -14
  36. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/uu_migrations.py +4 -14
  37. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/xdrlib_migrations.py +4 -14
  38. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/xml_deprecations.py +2 -12
  39. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python.egg-info/PKG-INFO +2 -2
  40. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python.egg-info/SOURCES.txt +1 -0
  41. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python.egg-info/requires.txt +1 -1
  42. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/setup.cfg +0 -0
  43. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/__init__.py +0 -0
  44. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/__init__.py +0 -0
  45. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/array_deprecations.py +0 -0
  46. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/ast_deprecations.py +0 -0
  47. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/asyncio_coroutine_to_async.py +0 -0
  48. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/calendar_deprecations.py +0 -0
  49. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/collections_abc_migrations.py +0 -0
  50. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/configparser_deprecations.py +0 -0
  51. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/datetime_utc.py +0 -0
  52. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/gettext_deprecations.py +0 -0
  53. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/langchain_community_imports.py +0 -0
  54. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/langchain_provider_imports.py +0 -0
  55. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/locale_deprecations.py +0 -0
  56. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/removed_modules_312.py +0 -0
  57. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/string_formatting.py +0 -0
  58. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/threading_deprecations.py +0 -0
  59. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/threading_is_alive_deprecation.py +0 -0
  60. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/typing_union_to_pipe.py +0 -0
  61. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/unittest_deprecations.py +0 -0
  62. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain02.py +0 -0
  63. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_langchain1.py +0 -0
  64. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python310.py +0 -0
  65. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python311.py +0 -0
  66. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python312.py +0 -0
  67. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python313.py +0 -0
  68. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python314.py +0 -0
  69. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python38.py +0 -0
  70. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python/migrate/upgrade_to_python39.py +0 -0
  71. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python.egg-info/dependency_links.txt +0 -0
  72. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python.egg-info/entry_points.txt +0 -0
  73. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/src/openrewrite_migrate_python.egg-info/top_level.txt +0 -0
  74. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_aifc_migrations.py +0 -0
  75. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_array_deprecations.py +0 -0
  76. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_ast_deprecations.py +0 -0
  77. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_asyncio_coroutine_to_async.py +0 -0
  78. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_asyncio_deprecations.py +0 -0
  79. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_calendar_deprecations.py +0 -0
  80. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_cgi_parse_deprecations.py +0 -0
  81. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_change_import_recipes.py +0 -0
  82. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_collections_abc_migrations.py +0 -0
  83. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_configparser_deprecations.py +0 -0
  84. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_datetime_utc.py +0 -0
  85. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_distutils_deprecations.py +0 -0
  86. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_gettext_deprecations.py +0 -0
  87. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_html_parser_deprecations.py +0 -0
  88. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_imp_migrations.py +0 -0
  89. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_langchain_classic_imports.py +0 -0
  90. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_langchain_community_imports.py +0 -0
  91. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_langchain_provider_imports.py +0 -0
  92. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_locale_deprecations.py +0 -0
  93. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_locale_getdefaultlocale_deprecation.py +0 -0
  94. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_macpath_deprecations.py +0 -0
  95. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_os_deprecations.py +0 -0
  96. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_pep594_migrations.py +0 -0
  97. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_pep594_system_migrations.py +0 -0
  98. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_pkgutil_deprecations.py +0 -0
  99. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_platform_deprecations.py +0 -0
  100. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_re_deprecations.py +0 -0
  101. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_removed_modules_312.py +0 -0
  102. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_shutil_deprecations.py +0 -0
  103. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_ssl_deprecations.py +0 -0
  104. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_string_formatting.py +0 -0
  105. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_sys_deprecations.py +0 -0
  106. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_sys_last_deprecations.py +0 -0
  107. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_tarfile_deprecations.py +0 -0
  108. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_threading_deprecations.py +0 -0
  109. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_threading_extended.py +0 -0
  110. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_threading_is_alive_deprecation.py +0 -0
  111. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_typing_callable.py +0 -0
  112. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_typing_deprecations.py +0 -0
  113. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_typing_union_to_pipe.py +0 -0
  114. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_unittest_deprecations.py +0 -0
  115. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/tests/test_upgrade_recipes.py +0 -0
  116. {openrewrite_migrate_python-0.1.1 → openrewrite_migrate_python-0.2.0}/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.1.1
3
+ Version: 0.2.0
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.74.0.dev20260224100132; extra == "dev"
24
+ Requires-Dist: openrewrite>=8.74.3; extra == "dev"
25
25
  Requires-Dist: pytest>=8.0.0; extra == "dev"
26
26
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
27
27
  Requires-Dist: black>=24.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.1.1" # Updated dynamically during release
8
+ version = "0.2.0" # 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,7 +30,7 @@ dependencies = []
30
30
 
31
31
  [project.optional-dependencies]
32
32
  dev = [
33
- "openrewrite>=8.74.0.dev20260224100132",
33
+ "openrewrite>=8.74.3",
34
34
  "pytest>=8.0.0",
35
35
  "pytest-cov>=4.0.0",
36
36
  "black>=24.0.0",
@@ -0,0 +1,16 @@
1
+ """Shared marker utilities for deprecation recipes."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ from rewrite.markers import Markers, SearchResult
6
+ from rewrite.utils import random_id
7
+
8
+
9
+ def mark_deprecated(tree: Any, message: str, detail: Optional[str] = None) -> Any:
10
+ """Add a SearchResult marker for a deprecation warning."""
11
+ full_message = f"{message}: {detail}" if detail else message
12
+ search_marker = SearchResult(random_id(), full_message)
13
+ current_markers = tree.markers
14
+ new_markers_list = list(current_markers.markers) + [search_marker]
15
+ new_markers = Markers(current_markers.id, new_markers_list)
16
+ return tree.replace(_markers=new_markers)
@@ -17,11 +17,10 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
17
17
  from rewrite.category import CategoryDescriptor
18
18
  from rewrite.decorators import categorize
19
19
  from rewrite.marketplace import Python
20
- from rewrite.markers import Markers, SearchResult
21
- from rewrite.utils import random_id
22
20
  from rewrite.python.visitor import PythonVisitor
23
21
  from rewrite.python.tree import MultiImport, Import
24
22
  from rewrite.java.tree import Identifier, FieldAccess
23
+ from ._markers import mark_deprecated
25
24
 
26
25
  # Define category path: Python > Migrate > Python 3.13
27
26
  _Python313 = [
@@ -31,15 +30,6 @@ _Python313 = [
31
30
  ]
32
31
 
33
32
 
34
- def _mark_deprecated(tree: Any, message: str) -> Any:
35
- """Add a SearchResult marker for a deprecation warning."""
36
- search_marker = SearchResult(random_id(), message)
37
- current_markers = tree.markers
38
- new_markers_list = list(current_markers.markers) + [search_marker]
39
- new_markers = Markers(current_markers.id, new_markers_list)
40
- return tree.replace(_markers=new_markers)
41
-
42
-
43
33
  def _get_import_name(import_node: Any) -> Optional[str]:
44
34
  """Extract the module name from an import node's qualid."""
45
35
  qualid = import_node.qualid
@@ -94,7 +84,7 @@ class FindAifcModule(Recipe):
94
84
  from_part = multi.from_
95
85
  if from_part is not None:
96
86
  if isinstance(from_part, Identifier) and from_part.simple_name == "aifc":
97
- return _mark_deprecated(
87
+ return mark_deprecated(
98
88
  multi,
99
89
  "The `aifc` module was removed in Python 3.13. "
100
90
  "Use third-party audio libraries instead."
@@ -103,7 +93,7 @@ class FindAifcModule(Recipe):
103
93
  for import_node in multi.names:
104
94
  name = _get_import_name(import_node)
105
95
  if name == "aifc":
106
- return _mark_deprecated(
96
+ return mark_deprecated(
107
97
  multi,
108
98
  "The `aifc` module was removed in Python 3.13. "
109
99
  "Use third-party audio libraries instead."
@@ -119,7 +109,7 @@ class FindAifcModule(Recipe):
119
109
  return import_stmt
120
110
  name = _get_import_name(import_stmt)
121
111
  if name == "aifc":
122
- return _mark_deprecated(
112
+ return mark_deprecated(
123
113
  import_stmt,
124
114
  "The `aifc` module was removed in Python 3.13. "
125
115
  "Use third-party audio libraries instead."
@@ -172,7 +162,7 @@ class FindAudioopModule(Recipe):
172
162
  from_part = multi.from_
173
163
  if from_part is not None:
174
164
  if isinstance(from_part, Identifier) and from_part.simple_name == "audioop":
175
- return _mark_deprecated(
165
+ return mark_deprecated(
176
166
  multi,
177
167
  "The `audioop` module was removed in Python 3.13. "
178
168
  "Use pydub, numpy, or scipy instead."
@@ -181,7 +171,7 @@ class FindAudioopModule(Recipe):
181
171
  for import_node in multi.names:
182
172
  name = _get_import_name(import_node)
183
173
  if name == "audioop":
184
- return _mark_deprecated(
174
+ return mark_deprecated(
185
175
  multi,
186
176
  "The `audioop` module was removed in Python 3.13. "
187
177
  "Use pydub, numpy, or scipy instead."
@@ -197,7 +187,7 @@ class FindAudioopModule(Recipe):
197
187
  return import_stmt
198
188
  name = _get_import_name(import_stmt)
199
189
  if name == "audioop":
200
- return _mark_deprecated(
190
+ return mark_deprecated(
201
191
  import_stmt,
202
192
  "The `audioop` module was removed in Python 3.13. "
203
193
  "Use pydub, numpy, or scipy instead."
@@ -247,7 +237,7 @@ class FindChunkModule(Recipe):
247
237
  from_part = multi.from_
248
238
  if from_part is not None:
249
239
  if isinstance(from_part, Identifier) and from_part.simple_name == "chunk":
250
- return _mark_deprecated(
240
+ return mark_deprecated(
251
241
  multi,
252
242
  "The `chunk` module was removed in Python 3.13."
253
243
  )
@@ -255,7 +245,7 @@ class FindChunkModule(Recipe):
255
245
  for import_node in multi.names:
256
246
  name = _get_import_name(import_node)
257
247
  if name == "chunk":
258
- return _mark_deprecated(
248
+ return mark_deprecated(
259
249
  multi,
260
250
  "The `chunk` module was removed in Python 3.13."
261
251
  )
@@ -270,7 +260,7 @@ class FindChunkModule(Recipe):
270
260
  return import_stmt
271
261
  name = _get_import_name(import_stmt)
272
262
  if name == "chunk":
273
- return _mark_deprecated(
263
+ return mark_deprecated(
274
264
  import_stmt,
275
265
  "The `chunk` module was removed in Python 3.13."
276
266
  )
@@ -324,7 +314,7 @@ class FindImghdrModule(Recipe):
324
314
  from_part = multi.from_
325
315
  if from_part is not None:
326
316
  if isinstance(from_part, Identifier) and from_part.simple_name == "imghdr":
327
- return _mark_deprecated(
317
+ return mark_deprecated(
328
318
  multi,
329
319
  "The `imghdr` module was removed in Python 3.13. "
330
320
  "Use `filetype`, `python-magic`, or `Pillow` instead."
@@ -333,7 +323,7 @@ class FindImghdrModule(Recipe):
333
323
  for import_node in multi.names:
334
324
  name = _get_import_name(import_node)
335
325
  if name == "imghdr":
336
- return _mark_deprecated(
326
+ return mark_deprecated(
337
327
  multi,
338
328
  "The `imghdr` module was removed in Python 3.13. "
339
329
  "Use `filetype`, `python-magic`, or `Pillow` instead."
@@ -349,7 +339,7 @@ class FindImghdrModule(Recipe):
349
339
  return import_stmt
350
340
  name = _get_import_name(import_stmt)
351
341
  if name == "imghdr":
352
- return _mark_deprecated(
342
+ return mark_deprecated(
353
343
  import_stmt,
354
344
  "The `imghdr` module was removed in Python 3.13. "
355
345
  "Use `filetype`, `python-magic`, or `Pillow` instead."
@@ -403,7 +393,7 @@ class FindSndhdrModule(Recipe):
403
393
  from_part = multi.from_
404
394
  if from_part is not None:
405
395
  if isinstance(from_part, Identifier) and from_part.simple_name == "sndhdr":
406
- return _mark_deprecated(
396
+ return mark_deprecated(
407
397
  multi,
408
398
  "The `sndhdr` module was removed in Python 3.13. "
409
399
  "Use `filetype` or audio libraries instead."
@@ -412,7 +402,7 @@ class FindSndhdrModule(Recipe):
412
402
  for import_node in multi.names:
413
403
  name = _get_import_name(import_node)
414
404
  if name == "sndhdr":
415
- return _mark_deprecated(
405
+ return mark_deprecated(
416
406
  multi,
417
407
  "The `sndhdr` module was removed in Python 3.13. "
418
408
  "Use `filetype` or audio libraries instead."
@@ -428,7 +418,7 @@ class FindSndhdrModule(Recipe):
428
418
  return import_stmt
429
419
  name = _get_import_name(import_stmt)
430
420
  if name == "sndhdr":
431
- return _mark_deprecated(
421
+ return mark_deprecated(
432
422
  import_stmt,
433
423
  "The `sndhdr` module was removed in Python 3.13. "
434
424
  "Use `filetype` or audio libraries instead."
@@ -482,7 +472,7 @@ class FindSunauModule(Recipe):
482
472
  from_part = multi.from_
483
473
  if from_part is not None:
484
474
  if isinstance(from_part, Identifier) and from_part.simple_name == "sunau":
485
- return _mark_deprecated(
475
+ return mark_deprecated(
486
476
  multi,
487
477
  "The `sunau` module was removed in Python 3.13. "
488
478
  "Use `soundfile` or `pydub` instead."
@@ -491,7 +481,7 @@ class FindSunauModule(Recipe):
491
481
  for import_node in multi.names:
492
482
  name = _get_import_name(import_node)
493
483
  if name == "sunau":
494
- return _mark_deprecated(
484
+ return mark_deprecated(
495
485
  multi,
496
486
  "The `sunau` module was removed in Python 3.13. "
497
487
  "Use `soundfile` or `pydub` instead."
@@ -507,7 +497,7 @@ class FindSunauModule(Recipe):
507
497
  return import_stmt
508
498
  name = _get_import_name(import_stmt)
509
499
  if name == "sunau":
510
- return _mark_deprecated(
500
+ return mark_deprecated(
511
501
  import_stmt,
512
502
  "The `sunau` module was removed in Python 3.13. "
513
503
  "Use `soundfile` or `pydub` instead."
@@ -22,10 +22,9 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
22
22
  from rewrite.category import CategoryDescriptor
23
23
  from rewrite.decorators import categorize
24
24
  from rewrite.marketplace import Python
25
- from rewrite.markers import Markers, SearchResult
26
25
  from rewrite.python.visitor import PythonVisitor
27
26
  from rewrite.java.tree import Identifier, MethodInvocation, FieldAccess
28
- from rewrite.utils import random_id
27
+ from ._markers import mark_deprecated
29
28
 
30
29
  # Define category path: Python > Migrate > Python 3.11
31
30
  _Python311 = [
@@ -35,16 +34,6 @@ _Python311 = [
35
34
  ]
36
35
 
37
36
 
38
- def _mark_deprecated(tree: Any, message: str, detail: Optional[str] = None) -> Any:
39
- """Add a SearchResult marker for a deprecation warning."""
40
- full_message = f"{message}: {detail}" if detail else message
41
- search_marker = SearchResult(random_id(), full_message)
42
- current_markers = tree.markers
43
- new_markers_list = list(current_markers.markers) + [search_marker]
44
- new_markers = Markers(current_markers.id, new_markers_list)
45
- return tree.replace(_markers=new_markers)
46
-
47
-
48
37
  def _is_asyncio_coroutine_access(node: Any) -> bool:
49
38
  """Check if this is an asyncio.coroutine access."""
50
39
  # Check for asyncio.coroutine pattern
@@ -106,7 +95,7 @@ class FindAsyncioCoroutineDecorator(Recipe):
106
95
  field_access = super().visit_field_access(field_access, p)
107
96
 
108
97
  if _is_asyncio_coroutine_access(field_access):
109
- return _mark_deprecated(
98
+ return mark_deprecated(
110
99
  field_access,
111
100
  "@asyncio.coroutine is deprecated",
112
101
  "Use 'async def' instead (removed in Python 3.11)"
@@ -20,11 +20,10 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
20
20
  from rewrite.category import CategoryDescriptor
21
21
  from rewrite.decorators import categorize
22
22
  from rewrite.marketplace import Python
23
- from rewrite.markers import Markers, SearchResult
24
- from rewrite.utils import random_id
25
23
  from rewrite.python.visitor import PythonVisitor
26
24
  from rewrite.python.tree import MultiImport, Import
27
25
  from rewrite.java.tree import Identifier, FieldAccess
26
+ from ._markers import mark_deprecated
28
27
 
29
28
  # Define category path: Python > Migrate > Python 3.13
30
29
  _Python313 = [
@@ -34,15 +33,6 @@ _Python313 = [
34
33
  ]
35
34
 
36
35
 
37
- def _mark_deprecated(tree: Any, message: str) -> Any:
38
- """Add a SearchResult marker for a deprecation warning."""
39
- search_marker = SearchResult(random_id(), message)
40
- current_markers = tree.markers
41
- new_markers_list = list(current_markers.markers) + [search_marker]
42
- new_markers = Markers(current_markers.id, new_markers_list)
43
- return tree.replace(_markers=new_markers)
44
-
45
-
46
36
  def _get_import_name(import_node: Any) -> Optional[str]:
47
37
  """Extract the module name from an import node's qualid."""
48
38
  qualid = import_node.qualid
@@ -100,7 +90,7 @@ class FindCgiModule(Recipe):
100
90
  if from_part is not None:
101
91
  # Handle 'from cgi import ...' pattern
102
92
  if isinstance(from_part, Identifier) and from_part.simple_name == "cgi":
103
- return _mark_deprecated(
93
+ return mark_deprecated(
104
94
  multi,
105
95
  "The `cgi` module was removed in Python 3.13. "
106
96
  "Use urllib.parse for query parsing, html.escape() for escaping."
@@ -110,7 +100,7 @@ class FindCgiModule(Recipe):
110
100
  for import_node in multi.names:
111
101
  name = _get_import_name(import_node)
112
102
  if name == "cgi":
113
- return _mark_deprecated(
103
+ return mark_deprecated(
114
104
  multi,
115
105
  "The `cgi` module was removed in Python 3.13. "
116
106
  "Use urllib.parse for query parsing, html.escape() for escaping."
@@ -126,7 +116,7 @@ class FindCgiModule(Recipe):
126
116
  return import_stmt
127
117
  name = _get_import_name(import_stmt)
128
118
  if name == "cgi":
129
- return _mark_deprecated(
119
+ return mark_deprecated(
130
120
  import_stmt,
131
121
  "The `cgi` module was removed in Python 3.13. "
132
122
  "Use urllib.parse for query parsing, html.escape() for escaping."
@@ -178,7 +168,7 @@ class FindCgitbModule(Recipe):
178
168
  from_part = multi.from_
179
169
  if from_part is not None:
180
170
  if isinstance(from_part, Identifier) and from_part.simple_name == "cgitb":
181
- return _mark_deprecated(
171
+ return mark_deprecated(
182
172
  multi,
183
173
  "The `cgitb` module was removed in Python 3.13. "
184
174
  "Use logging and traceback modules instead."
@@ -187,7 +177,7 @@ class FindCgitbModule(Recipe):
187
177
  for import_node in multi.names:
188
178
  name = _get_import_name(import_node)
189
179
  if name == "cgitb":
190
- return _mark_deprecated(
180
+ return mark_deprecated(
191
181
  multi,
192
182
  "The `cgitb` module was removed in Python 3.13. "
193
183
  "Use logging and traceback modules instead."
@@ -203,7 +193,7 @@ class FindCgitbModule(Recipe):
203
193
  return import_stmt
204
194
  name = _get_import_name(import_stmt)
205
195
  if name == "cgitb":
206
- return _mark_deprecated(
196
+ return mark_deprecated(
207
197
  import_stmt,
208
198
  "The `cgitb` module was removed in Python 3.13. "
209
199
  "Use logging and traceback modules instead."
@@ -16,10 +16,9 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
16
16
  from rewrite.category import CategoryDescriptor
17
17
  from rewrite.decorators import categorize
18
18
  from rewrite.marketplace import Python
19
- from rewrite.markers import Markers, SearchResult
20
- from rewrite.utils import random_id
21
19
  from rewrite.python.visitor import PythonVisitor
22
20
  from rewrite.java.tree import Identifier, MethodInvocation
21
+ from ._markers import mark_deprecated
23
22
 
24
23
  # Define category path: Python > Migrate > Python 3.8
25
24
  _Python38 = [
@@ -29,15 +28,6 @@ _Python38 = [
29
28
  ]
30
29
 
31
30
 
32
- def _mark_deprecated(tree: Any, message: str) -> Any:
33
- """Add a SearchResult marker for a deprecation warning."""
34
- search_marker = SearchResult(random_id(), message)
35
- current_markers = tree.markers
36
- new_markers_list = list(current_markers.markers) + [search_marker]
37
- new_markers = Markers(current_markers.id, new_markers_list)
38
- return tree.replace(_markers=new_markers)
39
-
40
-
41
31
  @categorize(_Python38)
42
32
  class FindCgiParseQs(Recipe):
43
33
  """
@@ -95,7 +85,7 @@ class FindCgiParseQs(Recipe):
95
85
  if select.simple_name != "cgi":
96
86
  return method
97
87
 
98
- return _mark_deprecated(
88
+ return mark_deprecated(
99
89
  method,
100
90
  "cgi.parse_qs() was removed in Python 3.8. "
101
91
  "Use urllib.parse.parse_qs() instead."
@@ -161,7 +151,7 @@ class FindCgiParseQsl(Recipe):
161
151
  if select.simple_name != "cgi":
162
152
  return method
163
153
 
164
- return _mark_deprecated(
154
+ return mark_deprecated(
165
155
  method,
166
156
  "cgi.parse_qsl() was removed in Python 3.8. "
167
157
  "Use urllib.parse.parse_qsl() instead."
@@ -19,10 +19,9 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
19
19
  from rewrite.category import CategoryDescriptor
20
20
  from rewrite.decorators import categorize
21
21
  from rewrite.marketplace import Python
22
- from rewrite.markers import Markers, SearchResult
23
22
  from rewrite.python.visitor import PythonVisitor
24
23
  from rewrite.python.tree import MultiImport
25
- from rewrite.utils import random_id
24
+ from ._markers import mark_deprecated
26
25
 
27
26
  # Define category path: Python > Migrate > Python 3.12
28
27
  _Python312 = [
@@ -32,16 +31,6 @@ _Python312 = [
32
31
  ]
33
32
 
34
33
 
35
- def _mark_deprecated(tree: Any, message: str, detail: Optional[str] = None) -> Any:
36
- """Add a SearchResult marker for a deprecation warning."""
37
- full_message = f"{message}: {detail}" if detail else message
38
- search_marker = SearchResult(random_id(), full_message)
39
- current_markers = tree.markers
40
- new_markers_list = list(current_markers.markers) + [search_marker]
41
- new_markers = Markers(current_markers.id, new_markers_list)
42
- return tree.replace(_markers=new_markers)
43
-
44
-
45
34
  @categorize(_Python312)
46
35
  class FindDistutilsUsage(Recipe):
47
36
  """
@@ -96,7 +85,7 @@ class FindDistutilsUsage(Recipe):
96
85
  # Get the string representation of the from part
97
86
  from_str = from_part.print_all() if hasattr(from_part, 'print_all') else str(from_part)
98
87
  if 'distutils' in from_str:
99
- return _mark_deprecated(
88
+ return mark_deprecated(
100
89
  multi,
101
90
  "distutils is deprecated",
102
91
  "Migrate to setuptools (removed in Python 3.12)"
@@ -23,10 +23,9 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
23
23
  from rewrite.category import CategoryDescriptor
24
24
  from rewrite.decorators import categorize
25
25
  from rewrite.marketplace import Python
26
- from rewrite.markers import Markers, SearchResult
27
26
  from rewrite.python.visitor import PythonVisitor
28
27
  from rewrite.python.tree import MultiImport
29
- from rewrite.utils import random_id
28
+ from ._markers import mark_deprecated
30
29
 
31
30
  # Define category path: Python > Migrate > Python 3.12
32
31
  _Python312 = [
@@ -36,16 +35,6 @@ _Python312 = [
36
35
  ]
37
36
 
38
37
 
39
- def _mark_deprecated(tree: Any, message: str, detail: Optional[str] = None) -> Any:
40
- """Add a SearchResult marker for a deprecation warning."""
41
- full_message = f"{message}: {detail}" if detail else message
42
- search_marker = SearchResult(random_id(), full_message)
43
- current_markers = tree.markers
44
- new_markers_list = list(current_markers.markers) + [search_marker]
45
- new_markers = Markers(current_markers.id, new_markers_list)
46
- return tree.replace(_markers=new_markers)
47
-
48
-
49
38
  @categorize(_Python312)
50
39
  class ReplaceDistutilsVersion(Recipe):
51
40
  """
@@ -113,7 +102,7 @@ class ReplaceDistutilsVersion(Recipe):
113
102
  # Check what's being imported
114
103
  imports_str = multi.print_all() if hasattr(multi, 'print_all') else str(multi)
115
104
  if 'LooseVersion' in imports_str or 'StrictVersion' in imports_str:
116
- return _mark_deprecated(
105
+ return mark_deprecated(
117
106
  multi,
118
107
  "distutils.version is deprecated",
119
108
  "Migrate to packaging.version.Version (removed in Python 3.12). "
@@ -15,10 +15,9 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
15
15
  from rewrite.category import CategoryDescriptor
16
16
  from rewrite.decorators import categorize
17
17
  from rewrite.marketplace import Python
18
- from rewrite.markers import Markers, SearchResult
19
- from rewrite.utils import random_id
20
18
  from rewrite.python.visitor import PythonVisitor
21
19
  from rewrite.java.tree import Identifier, MethodInvocation
20
+ from ._markers import mark_deprecated
22
21
 
23
22
  # Define category path: Python > Migrate > Python 3.8
24
23
  _Python38 = [
@@ -28,15 +27,6 @@ _Python38 = [
28
27
  ]
29
28
 
30
29
 
31
- def _mark_deprecated(tree: Any, message: str) -> Any:
32
- """Add a SearchResult marker for a deprecation warning."""
33
- search_marker = SearchResult(random_id(), message)
34
- current_markers = tree.markers
35
- new_markers_list = list(current_markers.markers) + [search_marker]
36
- new_markers = Markers(current_markers.id, new_markers_list)
37
- return tree.replace(_markers=new_markers)
38
-
39
-
40
30
  @categorize(_Python38)
41
31
  class FindFunctoolsCmpToKey(Recipe):
42
32
  """
@@ -87,7 +77,7 @@ class FindFunctoolsCmpToKey(Recipe):
87
77
 
88
78
  select = method.select
89
79
  if isinstance(select, Identifier) and select.simple_name == "functools":
90
- return _mark_deprecated(
80
+ return mark_deprecated(
91
81
  method,
92
82
  "functools.cmp_to_key() is a Python 2 compatibility function. "
93
83
  "Consider using a key function directly."
@@ -13,10 +13,9 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
13
13
  from rewrite.category import CategoryDescriptor
14
14
  from rewrite.decorators import categorize
15
15
  from rewrite.marketplace import Python
16
- from rewrite.markers import Markers, SearchResult
17
- from rewrite.utils import random_id
18
16
  from rewrite.python.visitor import PythonVisitor
19
17
  from rewrite.java.tree import Identifier, MethodInvocation
18
+ from ._markers import mark_deprecated
20
19
 
21
20
  # Define category path: Python > Migrate > Python 3.9
22
21
  _Python39 = [
@@ -26,15 +25,6 @@ _Python39 = [
26
25
  ]
27
26
 
28
27
 
29
- def _mark_deprecated(tree: Any, message: str) -> Any:
30
- """Add a SearchResult marker for a deprecation warning."""
31
- search_marker = SearchResult(random_id(), message)
32
- current_markers = tree.markers
33
- new_markers_list = list(current_markers.markers) + [search_marker]
34
- new_markers = Markers(current_markers.id, new_markers_list)
35
- return tree.replace(_markers=new_markers)
36
-
37
-
38
28
  @categorize(_Python39)
39
29
  class FindHtmlParserUnescape(Recipe):
40
30
  """
@@ -101,7 +91,7 @@ class FindHtmlParserUnescape(Recipe):
101
91
  if method.select is None:
102
92
  return method
103
93
 
104
- return _mark_deprecated(
94
+ return mark_deprecated(
105
95
  method,
106
96
  "HTMLParser.unescape() was removed in Python 3.9. "
107
97
  "Use html.unescape() instead."
@@ -21,11 +21,10 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
21
21
  from rewrite.category import CategoryDescriptor
22
22
  from rewrite.decorators import categorize
23
23
  from rewrite.marketplace import Python
24
- from rewrite.markers import Markers, SearchResult
25
24
  from rewrite.python.visitor import PythonVisitor
26
25
  from rewrite.python.tree import MultiImport, Import
27
26
  from rewrite.java.tree import FieldAccess, Identifier
28
- from rewrite.utils import random_id
27
+ from ._markers import mark_deprecated
29
28
 
30
29
  # Define category path: Python > Migrate > Python 3.12
31
30
  _Python312 = [
@@ -35,16 +34,6 @@ _Python312 = [
35
34
  ]
36
35
 
37
36
 
38
- def _mark_deprecated(tree: Any, message: str, detail: Optional[str] = None) -> Any:
39
- """Add a SearchResult marker for a deprecation warning."""
40
- full_message = f"{message}: {detail}" if detail else message
41
- search_marker = SearchResult(random_id(), full_message)
42
- current_markers = tree.markers
43
- new_markers_list = list(current_markers.markers) + [search_marker]
44
- new_markers = Markers(current_markers.id, new_markers_list)
45
- return tree.replace(_markers=new_markers)
46
-
47
-
48
37
  def _get_import_name(import_node: Any) -> Optional[str]:
49
38
  """Extract the module name from an import node's qualid."""
50
39
  qualid = import_node.qualid
@@ -100,7 +89,7 @@ class FindImpUsage(Recipe):
100
89
  from_part = multi.from_
101
90
  if from_part is not None:
102
91
  if isinstance(from_part, Identifier) and from_part.simple_name == 'imp':
103
- return _mark_deprecated(
92
+ return mark_deprecated(
104
93
  multi,
105
94
  "imp module is deprecated",
106
95
  "Migrate to importlib (removed in Python 3.12)"
@@ -109,7 +98,7 @@ class FindImpUsage(Recipe):
109
98
  for import_node in multi.names:
110
99
  name = _get_import_name(import_node)
111
100
  if name == 'imp':
112
- return _mark_deprecated(
101
+ return mark_deprecated(
113
102
  multi,
114
103
  "imp module is deprecated",
115
104
  "Migrate to importlib (removed in Python 3.12)"
@@ -125,7 +114,7 @@ class FindImpUsage(Recipe):
125
114
  return import_stmt
126
115
  name = _get_import_name(import_stmt)
127
116
  if name == 'imp':
128
- return _mark_deprecated(
117
+ return mark_deprecated(
129
118
  import_stmt,
130
119
  "imp module is deprecated",
131
120
  "Migrate to importlib (removed in Python 3.12)"
@@ -18,11 +18,10 @@ from rewrite import ExecutionContext, Recipe, TreeVisitor
18
18
  from rewrite.category import CategoryDescriptor
19
19
  from rewrite.decorators import categorize
20
20
  from rewrite.marketplace import Python
21
- from rewrite.markers import Markers, SearchResult
22
21
  from rewrite.python.visitor import PythonVisitor
23
22
  from rewrite.python.tree import MultiImport
24
23
  from rewrite.java.tree import FieldAccess, Identifier
25
- from rewrite.utils import random_id
24
+ from ._markers import mark_deprecated
26
25
 
27
26
  _LangChain1 = [
28
27
  *Python,
@@ -80,15 +79,6 @@ def _get_import_names(multi: MultiImport) -> List[str]:
80
79
  return names
81
80
 
82
81
 
83
- def _mark_deprecated(tree: Any, message: str) -> Any:
84
- """Add a SearchResult marker for a deprecation warning."""
85
- search_marker = SearchResult(random_id(), message)
86
- current_markers = tree.markers
87
- new_markers_list = list(current_markers.markers) + [search_marker]
88
- new_markers = Markers(current_markers.id, new_markers_list)
89
- return tree.replace(_markers=new_markers)
90
-
91
-
92
82
  @categorize(_LangChain1)
93
83
  class ReplaceLangchainClassicImports(Recipe):
94
84
  """
@@ -228,7 +218,7 @@ class FindDeprecatedLangchainAgents(Recipe):
228
218
 
229
219
  if found_deprecated:
230
220
  names_str = ", ".join(found_deprecated)
231
- return _mark_deprecated(
221
+ return mark_deprecated(
232
222
  multi,
233
223
  f"Deprecated LangChain API: {names_str} "
234
224
  f"(use create_agent / LangGraph in v1.0)",
@@ -300,7 +290,7 @@ class FindLangchainCreateReactAgent(Recipe):
300
290
  if "create_react_agent" not in imported_names:
301
291
  return multi
302
292
 
303
- return _mark_deprecated(
293
+ return mark_deprecated(
304
294
  multi,
305
295
  "Migrate to `from langchain.agents import create_agent` (LangChain v1.0)",
306
296
  )