openrewrite-remote 0.13.4__tar.gz → 0.13.5__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 (28) hide show
  1. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/PKG-INFO +1 -1
  2. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/openrewrite_remote.egg-info/PKG-INFO +1 -1
  3. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/pyproject.toml +9 -6
  4. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/__init__.py +1 -3
  5. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/handler_helpers.py +1 -1
  6. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/project_helper.py +6 -13
  7. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/pypi_manager.py +13 -16
  8. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/recipe_install_handler.py +1 -3
  9. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/run_recipe_load_and_visitor_handler.py +3 -7
  10. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/receiver.py +26 -33
  11. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/remote_utils.py +21 -15
  12. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/remoting.py +11 -10
  13. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/sender.py +80 -113
  14. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/server.py +21 -10
  15. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/README.md +0 -0
  16. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/openrewrite_remote.egg-info/SOURCES.txt +0 -0
  17. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/openrewrite_remote.egg-info/dependency_links.txt +0 -0
  18. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/openrewrite_remote.egg-info/entry_points.txt +0 -0
  19. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/openrewrite_remote.egg-info/requires.txt +0 -0
  20. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/openrewrite_remote.egg-info/top_level.txt +0 -0
  21. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/client.py +0 -0
  22. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/event.py +0 -0
  23. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/__init__.py +0 -0
  24. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/hello_world_handler.py +0 -0
  25. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/list_projects_handler.py +0 -0
  26. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/handlers/types.py +0 -0
  27. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/rewrite_remote/type_utils.py +0 -0
  28. {openrewrite_remote-0.13.4 → openrewrite_remote-0.13.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openrewrite-remote
3
- Version: 0.13.4
3
+ Version: 0.13.5
4
4
  Summary: Remoting functionality for the OpenRewrite library.
5
5
  Author-email: "Moderne Inc." <support@moderne.io>
6
6
  License: Moderne, Inc. Commercial License
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openrewrite-remote
3
- Version: 0.13.4
3
+ Version: 0.13.5
4
4
  Summary: Remoting functionality for the OpenRewrite library.
5
5
  Author-email: "Moderne Inc." <support@moderne.io>
6
6
  License: Moderne, Inc. Commercial License
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "openrewrite-remote"
7
7
  description = "Remoting functionality for the OpenRewrite library."
8
- version = "0.13.4" # Updated dynamically during release
8
+ version = "0.13.5" # Updated dynamically during release
9
9
  authors = [{ name = "Moderne Inc.", email = "support@moderne.io" }]
10
10
  license = { text = "Moderne, Inc. Commercial License" }
11
11
  dependencies = [
@@ -24,11 +24,12 @@ exclude = []
24
24
  [dependency-groups]
25
25
  dev = [
26
26
  "pytest==8.3.4",
27
- "pytest-asyncio==0.24.0",
28
- "mypy==1.13.0",
27
+ "pytest-asyncio==0.25.0",
28
+ "mypy==1.14.0",
29
29
  "poethepoet==0.31.1",
30
- "black==24.10.0",
31
30
  "pylint==3.3.2",
31
+ "ruff>=0.8.4",
32
+ "types-toml>=0.10.8.20240310",
32
33
  ]
33
34
 
34
35
  [project.scripts]
@@ -36,6 +37,8 @@ start_python_remoting = "rewrite_remote.server:main"
36
37
 
37
38
  [tool.poe.tasks]
38
39
  check-types = "mypy ./rewrite_remote"
39
- format = "black ./rewrite_remote ./tests"
40
+ format = "ruff format ./rewrite_remote ./tests"
40
41
  test = "pytest"
41
- lint = "pylint ./rewrite_remote/**/*.py ./tests/**/*.py"
42
+ lint-pylint = "pylint ./rewrite_remote/**/*.py ./tests/**/*.py"
43
+ lint-ruff = "ruff check ./rewrite_remote ./tests"
44
+ lint-ruff-fix = "ruff check --fix ./rewrite_remote ./tests"
@@ -6,7 +6,5 @@ from .sender import *
6
6
  from .remoting import *
7
7
 
8
8
  __all__ = [
9
- name
10
- for name in dir()
11
- if not name.startswith("_") and not isinstance(globals()[name], TypeVar)
9
+ name for name in dir() if not name.startswith("_") and not isinstance(globals()[name], TypeVar)
12
10
  ]
@@ -3,7 +3,7 @@ import socket
3
3
  import cbor2
4
4
 
5
5
  from rewrite_remote.remote_utils import COMMAND_END
6
- from rewrite_remote import RemotingMessageType, OK, ERROR
6
+ from rewrite_remote import RemotingMessageType, ERROR
7
7
 
8
8
 
9
9
  def respond_with_error(message: str, sock: socket.socket) -> None:
@@ -54,9 +54,7 @@ def is_uv_project(tomlData: dict[str, Any]) -> bool:
54
54
  return "tool" in tomlData and "uv" in tomlData["tool"]
55
55
 
56
56
 
57
- def find_sub_projects_in_poetry(
58
- tomlData: dict[str, Any], toml_path: str
59
- ) -> list[Project]:
57
+ def find_sub_projects_in_poetry(tomlData: dict[str, Any], toml_path: str) -> list[Project]:
60
58
  """
61
59
  Finds sub projects in a poetry project by looking for dependencies with a "path" key:
62
60
  [tool.poetry.dependencies]
@@ -78,9 +76,7 @@ def find_sub_projects_in_poetry(
78
76
  return subProjects
79
77
 
80
78
 
81
- def find_sub_projects_in_hatch(
82
- tomlData: dict[str, Any], toml_path: str
83
- ) -> list[Project]:
79
+ def find_sub_projects_in_hatch(tomlData: dict[str, Any], toml_path: str) -> list[Project]:
84
80
  """
85
81
  Finds sub projects in a hatch project by looking for dependencies with a "path" key:
86
82
  [tool.hatch.envs.default.dependencies]
@@ -98,18 +94,14 @@ def find_sub_projects_in_hatch(
98
94
  subProjects.append(
99
95
  Project(
100
96
  project_name=dep_name,
101
- project_root=get_absolute_path(
102
- toml_path, dep_value["path"]
103
- ),
97
+ project_root=get_absolute_path(toml_path, dep_value["path"]),
104
98
  project_tool=f"hatch:{env_name}",
105
99
  )
106
100
  )
107
101
  return subProjects
108
102
 
109
103
 
110
- def find_sub_projects_in_uv_sources(
111
- tomlData: dict[str, Any], toml_path: str
112
- ) -> list[Project]:
104
+ def find_sub_projects_in_uv_sources(tomlData: dict[str, Any], toml_path: str) -> list[Project]:
113
105
  """
114
106
  Finds sub projects in a uv project by looking at sources and workspace:
115
107
  [tool.uv.sources]
@@ -146,7 +138,8 @@ def find_sub_projects_in_uv_sources(
146
138
  for glob_pattern in uv_workspace["members"]:
147
139
  # Every directory included by the members globs (and not excluded by the exclude globs) must contain a pyproject.toml file
148
140
  directories = glob.glob(
149
- os.path.join(os.path.dirname(toml_path), glob_pattern), recursive=True
141
+ os.path.join(os.path.dirname(toml_path), glob_pattern),
142
+ recursive=True,
150
143
  )
151
144
 
152
145
  for directory in directories:
@@ -4,6 +4,8 @@ import subprocess
4
4
  import importlib
5
5
  import inspect
6
6
  import pkgutil
7
+ import site
8
+
7
9
  from dataclasses import dataclass
8
10
 
9
11
  from pypi_simple import PyPISimple
@@ -51,7 +53,11 @@ class InstalledRecipe:
51
53
 
52
54
  class InstalledPackage:
53
55
  def __init__(
54
- self, name: str, version: str, source: str, recipes: List[InstalledRecipe]
56
+ self,
57
+ name: str,
58
+ version: str,
59
+ source: str,
60
+ recipes: List[InstalledRecipe],
55
61
  ):
56
62
  self.name = name
57
63
  self.version = version
@@ -87,14 +93,10 @@ class PyPiManager:
87
93
  requestedVersion,
88
94
  )
89
95
  if result:
90
- print(
91
- f"Package {package_identifier} found in source: {source.source}"
92
- )
96
+ print(f"Package {package_identifier} found in source: {source.source}")
93
97
  return source
94
98
  else:
95
- print(
96
- f"Package {package_identifier} not found in source: {source.source}"
97
- )
99
+ print(f"Package {package_identifier} not found in source: {source.source}")
98
100
  except Exception as e:
99
101
  print(f"Error checking source {source.source}: {e}")
100
102
 
@@ -161,9 +163,7 @@ class PyPiManager:
161
163
  raise RuntimeError(f"Failed to uninstall package {package_name}: {e}")
162
164
 
163
165
  @staticmethod
164
- def load_recipe(
165
- recipe_name: str, module_name: str, recipe_options: List[Option]
166
- ) -> Recipe:
166
+ def load_recipe(recipe_name: str, module_name: str, recipe_options: List[Option]) -> Recipe:
167
167
  """
168
168
  Loads a recipe from the specified source.
169
169
  """
@@ -191,9 +191,7 @@ class PyPiManager:
191
191
  raise RuntimeError(f"Package {package_name} is not installed.")
192
192
  return metadata
193
193
  except Exception as e:
194
- raise RuntimeError(
195
- f"Failed to load package details for {package_name}: {e}"
196
- )
194
+ raise RuntimeError(f"Failed to load package details for {package_name}: {e}")
197
195
 
198
196
  @staticmethod
199
197
  def _get_package_metadata(package_name: str) -> Dict[str, Any]:
@@ -210,9 +208,7 @@ class PyPiManager:
210
208
  metadata_dict = {key.lower(): value for key, value in dist.metadata.items()}
211
209
  return metadata_dict
212
210
  except importlib.metadata.PackageNotFoundError:
213
- print(
214
- f"Package {package_name} not found in {DEFAULT_RECIPE_INSTALL_LOCATION}"
215
- )
211
+ print(f"Package {package_name} not found in {DEFAULT_RECIPE_INSTALL_LOCATION}")
216
212
  return {}
217
213
 
218
214
  @staticmethod
@@ -225,6 +221,7 @@ class PyPiManager:
225
221
  module_name = module_name.replace("-", "_")
226
222
 
227
223
  try:
224
+ site.main(); # We want the recently installed module to be available to introspection
228
225
  module = importlib.import_module(module_name)
229
226
  submodules = [name for _, name, _ in pkgutil.iter_modules(module.__path__)]
230
227
 
@@ -111,9 +111,7 @@ def recipe_install_handler(
111
111
 
112
112
  # 4. Install the recipe
113
113
  try:
114
- installable_recipes = PyPiManager.install_package(
115
- package_id, package_version, valid_source
116
- )
114
+ installable_recipes = PyPiManager.install_package(package_id, package_version, valid_source)
117
115
  except Exception as e: # pylint: disable=broad-except
118
116
  respond_with_error(f"Failed to install package: {e}", sock)
119
117
  return
@@ -13,7 +13,7 @@ from rewrite_remote.remoting import (
13
13
  )
14
14
 
15
15
  from rewrite_remote.remote_utils import COMMAND_END
16
- from rewrite_remote.remoting import OK, RemotingContext, RemotingMessageType
16
+ from rewrite_remote.remoting import RemotingContext
17
17
  from rewrite_remote.handlers.handler_helpers import respond_with_error
18
18
 
19
19
  from rewrite import InMemoryExecutionContext
@@ -98,9 +98,7 @@ def run_recipe_load_and_visitor_handler(
98
98
  RemotingExecutionContextView.view(ctx).remoting_context = remoting_ctx
99
99
 
100
100
  try:
101
- recipe_instance = PyPiManager.load_recipe(
102
- recipe_name, recipe_source, recipe_options
103
- )
101
+ recipe_instance = PyPiManager.load_recipe(recipe_name, recipe_source, recipe_options)
104
102
  except Exception as e:
105
103
  respond_with_error(f"Failed to load recipe: {e}", sock)
106
104
  return
@@ -122,9 +120,7 @@ def run_recipe_load_and_visitor_handler(
122
120
 
123
121
  # 5. Write the response
124
122
  response_encoder = BytesIO()
125
- RemotingMessenger.send_tree(
126
- remoting_ctx, response_encoder, RemotingMessenger._state, received
127
- )
123
+ RemotingMessenger.send_tree(remoting_ctx, response_encoder, RemotingMessenger._state, received)
128
124
 
129
125
  encoded_response = b""
130
126
  encoded_response += dumps(RemotingMessageType.Response)
@@ -86,7 +86,10 @@ class ReceiverFactory(Protocol):
86
86
 
87
87
  class DetailsReceiver(Protocol[T]):
88
88
  def receive_details(
89
- self, before: Optional[T], type: Optional[Type[T]], ctx: "ReceiverContext"
89
+ self,
90
+ before: Optional[T],
91
+ type: Optional[Type[T]],
92
+ ctx: "ReceiverContext",
90
93
  ) -> T:
91
94
  pass
92
95
 
@@ -111,7 +114,10 @@ class ReceiverContext:
111
114
  return cast(Optional[T], OmniReceiver().receive(before, self))
112
115
 
113
116
  def receive_tree(
114
- self, before: Optional[Tree], tree_type: Optional[str], ctx: "ReceiverContext"
117
+ self,
118
+ before: Optional[Tree],
119
+ tree_type: Optional[str],
120
+ ctx: "ReceiverContext",
115
121
  ) -> Tree:
116
122
  if before:
117
123
  return before.accept(self.visitor, ctx)
@@ -123,9 +129,7 @@ class ReceiverContext:
123
129
  def polymorphic_receive_tree(self, before: Optional[Tree]) -> Optional[Tree]:
124
130
  diff_event = self.receiver.receive_node()
125
131
  if diff_event.event_type in (EventType.Add, EventType.Update):
126
- tree_receiver = self.new_receiver(
127
- diff_event.concrete_type or type(before).__name__
128
- )
132
+ tree_receiver = self.new_receiver(diff_event.concrete_type or type(before).__name__)
129
133
  forked = tree_receiver.fork(self)
130
134
  return forked.receive_tree(
131
135
  None if diff_event.event_type == EventType.Add else before,
@@ -159,7 +163,10 @@ class ReceiverContext:
159
163
  return before
160
164
 
161
165
  def receive_markers(
162
- self, before: Optional[Markers], type: Optional[str], ctx: "ReceiverContext"
166
+ self,
167
+ before: Optional[Markers],
168
+ type: Optional[str],
169
+ ctx: "ReceiverContext",
163
170
  ) -> Markers:
164
171
  id_ = self.receive_value(getattr(before, "id", None), UUID)
165
172
  after_markers: Optional[List[Marker]] = self.receive_values(
@@ -177,9 +184,7 @@ class ReceiverContext:
177
184
  ) -> Optional[List[A]]:
178
185
  return remote_utils.receive_nodes(before, details, self)
179
186
 
180
- def receive_values(
181
- self, before: Optional[List[V]], type: Type[Any]
182
- ) -> Optional[List[V]]:
187
+ def receive_values(self, before: Optional[List[V]], type: Type[Any]) -> Optional[List[V]]:
183
188
  return remote_utils.receive_values(before, type, self)
184
189
 
185
190
  def receive_value(self, before: Optional[V], type: Type[Any]) -> Optional[V]:
@@ -198,7 +203,7 @@ class ReceiverContext:
198
203
  ReceiverContext.Registry[type_] = receiver_factory
199
204
 
200
205
 
201
- ValueDeserializer = Callable[[Type[Any], CBORDecoder, "DeserializationContext"], Optional[Any]]
206
+ ValueDeserializer = Callable[[str, CBORDecoder, "DeserializationContext"], Optional[Any]]
202
207
 
203
208
 
204
209
  class DefaultValueDeserializer(ValueDeserializer):
@@ -256,7 +261,7 @@ class DeserializationContext:
256
261
  initial_byte = decoder.read(1)[0]
257
262
  major_type = initial_byte >> 5
258
263
  subtype = initial_byte & 31
259
- concrete_type = None
264
+ concrete_type: Optional[str] = None
260
265
 
261
266
  # Object ID for Marker, JavaType, etc.
262
267
  if major_type == 0:
@@ -275,7 +280,9 @@ class DeserializationContext:
275
280
  for _ in range(subtype):
276
281
  array.append(self.deserialize(expected_elem_type, decoder))
277
282
  else:
278
- while not (value := self.deserialize(expected_elem_type, decoder)) == break_marker:
283
+ while (
284
+ not (value := self.deserialize(expected_elem_type, decoder)) == break_marker
285
+ ):
279
286
  array.append(value)
280
287
  return array
281
288
  else:
@@ -301,7 +308,7 @@ class DeserializationContext:
301
308
  id_ = UUID(bytes=decoder.decode())
302
309
  return SearchResult(id_, desc)
303
310
 
304
- if (deser := self.value_deserializers.get(concrete_type)):
311
+ if deser := self.value_deserializers.get(concrete_type):
305
312
  return deser(concrete_type, decoder, self)
306
313
 
307
314
  for type_, value_deserializer in self.value_deserializers.items():
@@ -378,9 +385,7 @@ class DeserializationContext:
378
385
  if concrete_type == "java.math.BigDecimal":
379
386
  return decoder.decode()
380
387
 
381
- raise NotImplementedError(
382
- f"No deserialization implemented for: {concrete_type}"
383
- )
388
+ raise NotImplementedError(f"No deserialization implemented for: {concrete_type}")
384
389
 
385
390
  if state == cbor2.CborReaderState.ARRAY:
386
391
  decoder.read_array_start()
@@ -425,9 +430,7 @@ class DeserializationContext:
425
430
  for type_, deserializer in self.value_deserializers.items():
426
431
  if issubclass(actual_type, type_):
427
432
  return deserializer.deserialize(actual_type, decoder, self)
428
- raise NotImplementedError(
429
- f"No deserialization implemented for: {expected_type}"
430
- )
433
+ raise NotImplementedError(f"No deserialization implemented for: {expected_type}")
431
434
 
432
435
 
433
436
  class JsonReceiver(TreeReceiver):
@@ -448,11 +451,7 @@ class JsonReceiver(TreeReceiver):
448
451
  concrete_type = None
449
452
 
450
453
  if event_type in {EventType.Add, EventType.Update}:
451
- if (
452
- event_type == EventType.Add
453
- and len(array) > 1
454
- and isinstance(array[1], str)
455
- ):
454
+ if event_type == EventType.Add and len(array) > 1 and isinstance(array[1], str):
456
455
  concrete_type = array[1]
457
456
 
458
457
  elif event_type not in {
@@ -522,21 +521,15 @@ class ParseErrorReceiver(Receiver):
522
521
  parse_error = parse_error.with_markers(
523
522
  ctx.receive_node(parse_error.markers, ctx.receive_markers)
524
523
  )
525
- parse_error = parse_error.with_source_path(
526
- ctx.receive_value(parse_error.source_path)
527
- )
524
+ parse_error = parse_error.with_source_path(ctx.receive_value(parse_error.source_path))
528
525
  parse_error = parse_error.with_file_attributes(
529
526
  ctx.receive_value(parse_error.file_attributes)
530
527
  )
531
- parse_error = parse_error.with_charset_name(
532
- ctx.receive_value(parse_error.charset_name)
533
- )
528
+ parse_error = parse_error.with_charset_name(ctx.receive_value(parse_error.charset_name))
534
529
  parse_error = parse_error.with_charset_bom_marked(
535
530
  ctx.receive_value(parse_error.charset_bom_marked)
536
531
  )
537
- parse_error = parse_error.with_checksum(
538
- ctx.receive_value(parse_error.checksum)
539
- )
532
+ parse_error = parse_error.with_checksum(ctx.receive_value(parse_error.checksum))
540
533
  parse_error = parse_error.with_text(ctx.receive_value(parse_error.text))
541
534
  # parse_error = parse_error.with_erroneous(ctx.receive_tree(parse_error.erroneous))
542
535
  return parse_error
@@ -57,9 +57,7 @@ def receive_nodes(
57
57
  elif diff_event.event_type == EventType.NoChange:
58
58
  after[i] = None # Or some default value
59
59
  else:
60
- raise NotImplementedError(
61
- f"Unexpected operation: {diff_event.event_type}"
62
- )
60
+ raise NotImplementedError(f"Unexpected operation: {diff_event.event_type}")
63
61
  return after # type: ignore
64
62
  elif list_event.event_type == EventType.Update:
65
63
  return _receive_updated_nodes(before, list_event.msg, details, ctx) # type: ignore
@@ -85,7 +83,11 @@ def _receive_updated_nodes(
85
83
  if evt.event_type in (EventType.NoChange, EventType.EndList):
86
84
  break
87
85
 
88
- if evt.event_type in (EventType.Delete, EventType.Update, EventType.Add):
86
+ if evt.event_type in (
87
+ EventType.Delete,
88
+ EventType.Update,
89
+ EventType.Add,
90
+ ):
89
91
  if not modified:
90
92
  after_list = _copy_range(before, before_idx)
91
93
  modified = True
@@ -97,9 +99,7 @@ def _receive_updated_nodes(
97
99
  elif evt.event_type == EventType.Delete:
98
100
  before_idx += 1
99
101
  elif evt.event_type == EventType.Update:
100
- after_list.append(
101
- details.receive_details(before[before_idx], evt.concrete_type, ctx)
102
- )
102
+ after_list.append(details.receive_details(before[before_idx], evt.concrete_type, ctx))
103
103
  before_idx += 1
104
104
  elif evt.event_type == EventType.Add:
105
105
  after_list.append(details.receive_details(None, evt.concrete_type, ctx))
@@ -130,9 +130,7 @@ def receive_values(
130
130
  elif diff_event.event_type == EventType.NoChange:
131
131
  after[i] = None # Or some default value
132
132
  else:
133
- raise NotImplementedError(
134
- f"Unexpected operation: {diff_event.event_type}"
135
- )
133
+ raise NotImplementedError(f"Unexpected operation: {diff_event.event_type}")
136
134
  return after # type: ignore
137
135
  elif list_event.event_type == EventType.Update:
138
136
  return _receive_updated_values(before, list_event.msg, type, ctx) # type: ignore
@@ -155,7 +153,11 @@ def _receive_updated_values(
155
153
  if evt.event_type in (EventType.NoChange, EventType.EndList):
156
154
  break
157
155
 
158
- if evt.event_type in (EventType.Delete, EventType.Update, EventType.Add):
156
+ if evt.event_type in (
157
+ EventType.Delete,
158
+ EventType.Update,
159
+ EventType.Add,
160
+ ):
159
161
  if not modified:
160
162
  after_list = _copy_range(before, before_idx)
161
163
  modified = True
@@ -239,16 +241,20 @@ def calculate_list_diff(
239
241
 
240
242
  # If elements at current indices are not equal, figure out the operation
241
243
  if before_id not in after_map:
242
- consumer(Operation.Delete, before_idx, -1, before[before_idx], None)
244
+ consumer(
245
+ Operation.Delete,
246
+ before_idx,
247
+ -1,
248
+ before[before_idx],
249
+ None,
250
+ )
243
251
  before_idx += 1
244
252
  else:
245
253
  consumer(Operation.Add, -1, after_idx, None, after[after_idx])
246
254
  after_idx += 1
247
255
 
248
256
 
249
- def create_index_map(
250
- lst: List[T], from_index: int, id_function: Callable[[T], I]
251
- ) -> Dict[I, int]:
257
+ def create_index_map(lst: List[T], from_index: int, id_function: Callable[[T], I]) -> Dict[I, int]:
252
258
  result = {}
253
259
  for i in range(from_index, len(lst)):
254
260
  result[id_function(lst[i])] = i
@@ -12,8 +12,6 @@ from typing import (
12
12
  Dict,
13
13
  Optional,
14
14
  Type,
15
- List,
16
- Tuple,
17
15
  Callable,
18
16
  cast,
19
17
  Union,
@@ -108,14 +106,16 @@ class RemotingContext:
108
106
  def new_sender_context(self, output_stream: Any) -> "SenderContext":
109
107
  return SenderContext(
110
108
  JsonSender(
111
- output_stream, SerializationContext(self, self._value_serializers)
109
+ output_stream,
110
+ SerializationContext(self, self._value_serializers),
112
111
  )
113
112
  )
114
113
 
115
114
  def new_receiver_context(self, input_stream: Any) -> "ReceiverContext":
116
115
  return ReceiverContext(
117
116
  JsonReceiver(
118
- input_stream, DeserializationContext(self, self._value_deserializers)
117
+ input_stream,
118
+ DeserializationContext(self, self._value_deserializers),
119
119
  )
120
120
  )
121
121
 
@@ -160,7 +160,6 @@ ERROR = 1
160
160
 
161
161
 
162
162
  class RemotingMessenger:
163
-
164
163
  def __init__(
165
164
  self,
166
165
  context: RemotingContext,
@@ -249,9 +248,7 @@ class RemotingMessenger:
249
248
  root_cursor = Cursor(None, Cursor.ROOT_VALUE)
250
249
  ctx = InMemoryExecutionContext()
251
250
  RemotingExecutionContextView.view(ctx).remoting_context = self._context
252
- print_output = received.print(
253
- Cursor(root_cursor, received), PrintOutputCapture(0)
254
- )
251
+ print_output = received.print(Cursor(root_cursor, received), PrintOutputCapture(0))
255
252
 
256
253
  response_stream = BytesIO()
257
254
  cbor2.dump(RemotingMessageType.Response, response_stream)
@@ -280,7 +277,9 @@ class RemotingMessenger:
280
277
 
281
278
  def send_print_request(self, sock: socket.socket, cursor: Cursor):
282
279
  self.__send_request_stream(
283
- sock, "print", lambda s: self.send_tree(s, cast(Tree, cursor.value))
280
+ sock,
281
+ "print",
282
+ lambda s: self.send_tree(s, cast(Tree, cursor.value)),
284
283
  )
285
284
  if self.recv_byte(sock) != RemotingMessageType.Response:
286
285
  raise ValueError("Unexpected message type.")
@@ -302,7 +301,9 @@ class RemotingMessenger:
302
301
  sock.sendall(dumps(b.getvalue()))
303
302
 
304
303
  def receive_tree(
305
- self, data: Union[BinaryIO, socket.socket], before: Optional[Tree] = None
304
+ self,
305
+ data: Union[BinaryIO, socket.socket],
306
+ before: Optional[Tree] = None,
306
307
  ):
307
308
  receiver_context = self._context.new_receiver_context(BytesIO(cbor2.load(data)))
308
309
  return receiver_context.receive_any_tree(before)
@@ -52,9 +52,7 @@ class OmniSender(Sender):
52
52
 
53
53
 
54
54
  class TreeSender(Protocol):
55
- def send_node(
56
- self, diff_event: DiffEvent, visitor: Callable[["TreeSender"], None]
57
- ) -> None: ...
55
+ def send_node(self, diff_event: DiffEvent, visitor: Callable[["TreeSender"], None]) -> None: ...
58
56
 
59
57
  def send_value(self, diff_event: DiffEvent) -> None: ...
60
58
 
@@ -69,10 +67,10 @@ class SenderContext(Generic[T]):
69
67
  Registry: Dict[Type[Any], Callable[[], Sender]] = {}
70
68
 
71
69
  def __init__(
72
- self,
73
- sender: "TreeSender",
74
- visitor: TreeVisitor = None,
75
- before: Optional[Any] = None,
70
+ self,
71
+ sender: "TreeSender",
72
+ visitor: TreeVisitor = None,
73
+ before: Optional[Any] = None,
76
74
  ):
77
75
  self.sender = sender
78
76
  self.visitor = visitor
@@ -82,24 +80,20 @@ class SenderContext(Generic[T]):
82
80
  for entry_type, factory in self.Registry.items():
83
81
  # FIXME find better solution
84
82
  try:
85
- if type_.__bases__.__contains__(entry_type) or issubclass(
86
- type_, entry_type
87
- ):
83
+ if type_.__bases__.__contains__(entry_type) or issubclass(type_, entry_type):
88
84
  return factory()
89
85
  except:
90
86
  pass
91
87
  raise ValueError(f"Unsupported sender type: {type_}")
92
88
 
93
- def fork(
94
- self, visitor: TreeVisitor, before: Optional[Any] = None
95
- ) -> "SenderContext[T]":
89
+ def fork(self, visitor: TreeVisitor, before: Optional[Any] = None) -> "SenderContext[T]":
96
90
  return SenderContext(self.sender, visitor, before)
97
91
 
98
92
  def visit(
99
- self,
100
- consumer: Callable[[V, "SenderContext"], None],
101
- after: V,
102
- before: Optional[V] = None,
93
+ self,
94
+ consumer: Callable[[V, "SenderContext"], None],
95
+ after: V,
96
+ before: Optional[V] = None,
103
97
  ) -> None:
104
98
  save_before = self.before
105
99
  self.before = before
@@ -113,10 +107,10 @@ class SenderContext(Generic[T]):
113
107
  OmniSender().send(after, before, self)
114
108
 
115
109
  def send_node(
116
- self,
117
- owner: A,
118
- extractor: Callable[[A], Optional[V]],
119
- details: Callable[[V, "SenderContext[T]"], None],
110
+ self,
111
+ owner: A,
112
+ extractor: Callable[[A], Optional[V]],
113
+ details: Callable[[V, "SenderContext[T]"], None],
120
114
  ) -> None:
121
115
  self.send_node_internal(
122
116
  extractor(owner),
@@ -124,9 +118,7 @@ class SenderContext(Generic[T]):
124
118
  details,
125
119
  )
126
120
 
127
- def send_value(
128
- self, owner: Any, value_extractor: Callable[[T], Optional[V]]
129
- ) -> None:
121
+ def send_value(self, owner: Any, value_extractor: Callable[[T], Optional[V]]) -> None:
130
122
  after_value = value_extractor(owner)
131
123
  before_value = value_extractor(self.before) if self.before is not None else None
132
124
  self.send_value_internal(after_value, before_value)
@@ -136,9 +128,7 @@ class SenderContext(Generic[T]):
136
128
  before_value = value_extractor(self.before) if self.before is not None else None
137
129
  self.send_typed_value_internal(after_value, before_value)
138
130
 
139
- def send_list_event(
140
- self, after: Optional[List[V]], before: Optional[List[V]]
141
- ) -> bool:
131
+ def send_list_event(self, after: Optional[List[V]], before: Optional[List[V]]) -> bool:
142
132
  if after == before:
143
133
  evt = DiffEvent(EventType.NoChange, None, None)
144
134
  elif before is None:
@@ -149,21 +139,17 @@ class SenderContext(Generic[T]):
149
139
  evt = DiffEvent(EventType.Update, None, len(after))
150
140
 
151
141
  self.sender.send_value(evt)
152
- return (
153
- evt.event_type != EventType.NoChange and evt.event_type != EventType.Delete
154
- )
142
+ return evt.event_type != EventType.NoChange and evt.event_type != EventType.Delete
155
143
 
156
144
  def send_nodes(
157
- self,
158
- owner: A,
159
- element_extractor: Callable[[A], List[V]],
160
- details: Callable[[V, "SenderContext"], None],
161
- id_function: Callable[[V], I],
145
+ self,
146
+ owner: A,
147
+ element_extractor: Callable[[A], List[V]],
148
+ details: Callable[[V, "SenderContext"], None],
149
+ id_function: Callable[[V], I],
162
150
  ) -> None:
163
151
  after_list = element_extractor(owner)
164
- before_list = (
165
- element_extractor(self.before) if self.before is not None else None
166
- )
152
+ before_list = element_extractor(self.before) if self.before is not None else None
167
153
 
168
154
  if self.send_list_event(after_list, before_list):
169
155
  if before_list is not None:
@@ -175,14 +161,10 @@ class SenderContext(Generic[T]):
175
161
  id_function,
176
162
  lambda op, _1, _2, bv, av: {
177
163
  Operation.Delete: lambda: self.send_node_internal(av, bv, details),
178
- Operation.NoChange: lambda: self.send_node_internal(
179
- av, bv, details
180
- ),
164
+ Operation.NoChange: lambda: self.send_node_internal(av, bv, details),
181
165
  Operation.Add: lambda: self.send_node_internal(av, bv, details),
182
166
  Operation.Update: lambda: self.send_node_internal(av, bv, details),
183
- Operation.Move: lambda: NotImplementedError(
184
- "Unexpected operation: " + str(op)
185
- ),
167
+ Operation.Move: lambda: NotImplementedError("Unexpected operation: " + str(op)),
186
168
  }[op](),
187
169
  )
188
170
 
@@ -190,10 +172,10 @@ class SenderContext(Generic[T]):
190
172
  self.sender.send_value(DiffEvent(EventType.EndList, None, None))
191
173
 
192
174
  def send_values(
193
- self,
194
- owner: T,
195
- value_extractor: Callable[[T], List[V]],
196
- id_function: Callable[[V], I],
175
+ self,
176
+ owner: T,
177
+ value_extractor: Callable[[T], List[V]],
178
+ id_function: Callable[[V], I],
197
179
  ) -> None:
198
180
  after_list = value_extractor(owner)
199
181
  before_list = value_extractor(self.before) if self.before is not None else None
@@ -211,9 +193,7 @@ class SenderContext(Generic[T]):
211
193
  Operation.NoChange: lambda: self.send_value_internal(av, bv),
212
194
  Operation.Add: lambda: self.send_value_internal(av, bv),
213
195
  Operation.Update: lambda: self.send_value_internal(av, bv),
214
- Operation.Move: lambda: NotImplementedError(
215
- "Unexpected operation: " + str(op)
216
- ),
196
+ Operation.Move: lambda: NotImplementedError("Unexpected operation: " + str(op)),
217
197
  }[op](),
218
198
  )
219
199
 
@@ -221,10 +201,10 @@ class SenderContext(Generic[T]):
221
201
  self.sender.send_value(DiffEvent(EventType.EndList, None, None))
222
202
 
223
203
  def send_typed_values(
224
- self,
225
- owner: T,
226
- value_extractor: Callable[[T], List[V]],
227
- id_function: Callable[[V], I],
204
+ self,
205
+ owner: T,
206
+ value_extractor: Callable[[T], List[V]],
207
+ id_function: Callable[[V], I],
228
208
  ) -> None:
229
209
  after_list = value_extractor(owner)
230
210
  before_list = value_extractor(self.before) if self.before is not None else None
@@ -242,9 +222,7 @@ class SenderContext(Generic[T]):
242
222
  Operation.NoChange: lambda: self.send_typed_value_internal(av, bv),
243
223
  Operation.Add: lambda: self.send_typed_value_internal(av, bv),
244
224
  Operation.Update: lambda: self.send_typed_value_internal(av, bv),
245
- Operation.Move: lambda: NotImplementedError(
246
- "Unexpected operation: " + str(op)
247
- ),
225
+ Operation.Move: lambda: NotImplementedError("Unexpected operation: " + str(op)),
248
226
  }[op](),
249
227
  )
250
228
 
@@ -270,17 +248,15 @@ class SenderContext(Generic[T]):
270
248
  return isinstance(after, (Tree, Markers)) or isinstance(before, (Tree, Markers))
271
249
 
272
250
  def send_node_internal(
273
- self,
274
- after: Optional[V],
275
- before: Optional[V],
276
- details: Callable[[V, "SenderContext"], None],
251
+ self,
252
+ after: Optional[V],
253
+ before: Optional[V],
254
+ details: Callable[[V, "SenderContext"], None],
277
255
  ) -> None:
278
256
  if self.are_equal(after, before):
279
257
  evt = DiffEvent(EventType.NoChange, None, None)
280
258
  elif before is None:
281
- concrete_type = (
282
- to_java_type_name(type(after)) if after is not None else None
283
- )
259
+ concrete_type = to_java_type_name(type(after)) if after is not None else None
284
260
  evt = DiffEvent(EventType.Add, concrete_type, None)
285
261
  elif after is None:
286
262
  evt = DiffEvent(EventType.Delete, None, None)
@@ -293,9 +269,7 @@ class SenderContext(Generic[T]):
293
269
  if self.before is not None and self.are_equal(after, before):
294
270
  evt = DiffEvent(EventType.NoChange, None, None)
295
271
  elif self.before is None or before is None:
296
- concrete_type = (
297
- to_java_type_name(type(after)) if isinstance(after, Marker) else None
298
- )
272
+ concrete_type = to_java_type_name(type(after)) if isinstance(after, Marker) else None
299
273
  evt = DiffEvent(EventType.Add, concrete_type, after)
300
274
  elif after is None:
301
275
  evt = DiffEvent(EventType.Delete, None, None)
@@ -308,9 +282,7 @@ class SenderContext(Generic[T]):
308
282
  if self.before is not None and self.are_equal(after, before):
309
283
  evt = DiffEvent(EventType.NoChange, None, None)
310
284
  elif self.before is None or before is None:
311
- concrete_type = (
312
- to_java_type_name_from_value(after) if after is not None else None
313
- )
285
+ concrete_type = to_java_type_name_from_value(after) if after is not None else None
314
286
  evt = DiffEvent(EventType.Add, concrete_type, after)
315
287
  elif after is None:
316
288
  evt = DiffEvent(EventType.Delete, None, None)
@@ -322,23 +294,21 @@ class SenderContext(Generic[T]):
322
294
 
323
295
  class SerializationContext:
324
296
  def __init__(
325
- self,
326
- remoting_context: "RemotingContext",
327
- value_serializers: Optional[Dict[Type[Any], "ValueSerializer"]] = None,
297
+ self,
298
+ remoting_context: "RemotingContext",
299
+ value_serializers: Optional[Dict[Type[Any], "ValueSerializer"]] = None,
328
300
  ):
329
301
  self.remoting_context = remoting_context
330
302
  self.value_serializers = value_serializers or {}
331
303
 
332
- def serialize(
333
- self, value: Any, type_name: Optional[str], encoder: CBOREncoder
334
- ) -> None:
304
+ def serialize(self, value: Any, type_name: Optional[str], encoder: CBOREncoder) -> None:
335
305
  if value is None:
336
306
  encoder.encode_none(None)
337
307
  return
338
308
 
339
309
  for type_cls, serializer in self.value_serializers.items():
340
310
  if isinstance(value, type_cls):
341
- serializer.serialize(value, type_name, encoder, self)
311
+ serializer(value, type_name, encoder, self)
342
312
  return
343
313
 
344
314
  DefaultValueSerializer().serialize(value, type_name, encoder, self)
@@ -353,7 +323,6 @@ class JsonSender(TreeSender):
353
323
  self._encoder = cbor2.CBOREncoder(self._stream)
354
324
 
355
325
  def send_node(self, diff_event, visitor) -> None:
356
-
357
326
  if diff_event.event_type in (EventType.Add, EventType.Update):
358
327
  self._encoder.encode(
359
328
  [diff_event.event_type.value]
@@ -375,20 +344,16 @@ class JsonSender(TreeSender):
375
344
 
376
345
  def send_value(self, diff_event):
377
346
  if diff_event.event_type in (EventType.Add, EventType.Update):
378
- self._encoder.encode_length(
379
- 4, 3 if diff_event.concrete_type is not None else 2
380
- )
347
+ self._encoder.encode_length(4, 3 if diff_event.concrete_type is not None else 2)
381
348
  self._encoder.encode_int(diff_event.event_type.value)
382
349
  if diff_event.concrete_type is not None:
383
350
  self._encoder.encode(diff_event.concrete_type)
384
- self._context.serialize(
385
- diff_event.msg, diff_event.concrete_type, self._encoder
386
- )
351
+ self._context.serialize(diff_event.msg, diff_event.concrete_type, self._encoder)
387
352
  elif diff_event.event_type in (
388
- EventType.Delete,
389
- EventType.NoChange,
390
- EventType.StartList,
391
- EventType.EndList,
353
+ EventType.Delete,
354
+ EventType.NoChange,
355
+ EventType.StartList,
356
+ EventType.EndList,
392
357
  ):
393
358
  self._encoder.encode([diff_event.event_type.value])
394
359
  else:
@@ -409,11 +374,11 @@ ValueSerializer = Callable[[Any, Optional[str], CBOREncoder, SerializationContex
409
374
 
410
375
 
411
376
  def write_object_using_reflection(
412
- value: Any,
413
- type_name: Optional[str],
414
- with_id: bool,
415
- encoder: CBOREncoder,
416
- context: SerializationContext,
377
+ value: Any,
378
+ type_name: Optional[str],
379
+ with_id: bool,
380
+ encoder: CBOREncoder,
381
+ context: SerializationContext,
417
382
  ) -> None:
418
383
  if with_id and (id := context.remoting_context.try_get_id(value)):
419
384
  encoder.encode_int(id)
@@ -429,8 +394,7 @@ def write_object_using_reflection(
429
394
 
430
395
  for field in fields(value):
431
396
  if field.name[0] == "_" and (
432
- not hasattr(field.type, "__origin__")
433
- or field.type.__origin__ is not ClassVar
397
+ not hasattr(field.type, "__origin__") or field.type.__origin__ is not ClassVar
434
398
  ):
435
399
  encoder.encode_string(to_java_field_name(field))
436
400
  context.serialize(getattr(value, field.name), None, encoder)
@@ -442,11 +406,11 @@ class DefaultValueSerializer(ValueSerializer):
442
406
  return self.serialize(*args, **kwargs)
443
407
 
444
408
  def serialize(
445
- self,
446
- value: Any,
447
- type_name: Optional[str],
448
- encoder: CBOREncoder,
449
- context: SerializationContext,
409
+ self,
410
+ value: Any,
411
+ type_name: Optional[str],
412
+ encoder: CBOREncoder,
413
+ context: SerializationContext,
450
414
  ) -> None:
451
415
  if isinstance(value, (int, float, str, bool, decimal.Decimal)):
452
416
  encoder.encode(value)
@@ -457,7 +421,12 @@ class DefaultValueSerializer(ValueSerializer):
457
421
  elif isinstance(value, Enum):
458
422
  if isinstance(value, JavaType.Primitive):
459
423
  # FIXME implement type attribution support
460
- encoder.encode(["org.openrewrite.java.tree.JavaType$Primitive", value.value])
424
+ encoder.encode(
425
+ [
426
+ "org.openrewrite.java.tree.JavaType$Primitive",
427
+ value.value,
428
+ ]
429
+ )
461
430
  else:
462
431
  encoder.encode(value.value)
463
432
  elif isinstance(value, Path):
@@ -492,8 +461,8 @@ class DefaultValueSerializer(ValueSerializer):
492
461
  encoder.encode_int(id)
493
462
  for field in fields(value):
494
463
  if field.name[0] == "_" and (
495
- not hasattr(field.type, "__origin__")
496
- or field.type.__origin__ is not ClassVar
464
+ not hasattr(field.type, "__origin__")
465
+ or field.type.__origin__ is not ClassVar
497
466
  ):
498
467
  encoder.encode_string(to_java_field_name(field))
499
468
  context.serialize(getattr(value, field.name), None, encoder)
@@ -504,21 +473,19 @@ class DefaultValueSerializer(ValueSerializer):
504
473
  elif isinstance(value, complex):
505
474
  encoder.encode(str(value))
506
475
  else:
507
- write_object_using_reflection(
508
- value, type_name, False, encoder, context
509
- )
476
+ write_object_using_reflection(value, type_name, False, encoder, context)
510
477
 
511
478
 
512
479
  def delegate_based_serializer(
513
- delegate: Callable[[Any, Optional[str], CBOREncoder, SerializationContext], None]
480
+ delegate: Callable[[Any, Optional[str], CBOREncoder, SerializationContext], None],
514
481
  ) -> Type[ValueSerializer]:
515
482
  class DelegateBasedSerializer(ValueSerializer):
516
483
  def serialize(
517
- self,
518
- value: Any,
519
- type_name: Optional[str],
520
- encoder: CBOREncoder,
521
- context: SerializationContext,
484
+ self,
485
+ value: Any,
486
+ type_name: Optional[str],
487
+ encoder: CBOREncoder,
488
+ context: SerializationContext,
522
489
  ) -> None:
523
490
  delegate(value, type_name, encoder, context)
524
491
 
@@ -30,7 +30,9 @@ from rewrite.python.remote.receiver import PythonReceiver
30
30
  from rewrite.python.remote.sender import PythonSender
31
31
 
32
32
  from rewrite_remote.handlers.hello_world_handler import hello_world_handler
33
- from rewrite_remote.handlers.recipe_install_handler import recipe_install_handler
33
+ from rewrite_remote.handlers.recipe_install_handler import (
34
+ recipe_install_handler,
35
+ )
34
36
  from rewrite_remote.handlers.run_recipe_load_and_visitor_handler import (
35
37
  run_recipe_load_and_visitor_handler,
36
38
  )
@@ -86,9 +88,7 @@ class Server:
86
88
  self._path = path
87
89
  self.timeout = timeout
88
90
  self._remoting_context = RemotingContext()
89
- self._remoting_context._recipe_factories["test"] = (
90
- lambda recipe_options: Recipe()
91
- )
91
+ self._remoting_context._recipe_factories["test"] = lambda recipe_options: Recipe()
92
92
  self._messenger = RemotingMessenger(
93
93
  self._remoting_context,
94
94
  {
@@ -132,9 +132,7 @@ class Server:
132
132
  except socket.timeout:
133
133
  current_time = time.time()
134
134
  if current_time - last_activity_time >= self.timeout:
135
- print(
136
- "No new connections for 5 minutes, shutting down server."
137
- )
135
+ print("No new connections for 5 minutes, shutting down server.")
138
136
  break
139
137
 
140
138
  def handle_client(self, sock: socket.socket) -> None:
@@ -175,7 +173,10 @@ class Server:
175
173
  sock.close()
176
174
 
177
175
  def parse_python_source(
178
- self, stream: BytesIO, sock: socket.socket, remoting_ctx: RemotingContext
176
+ self,
177
+ stream: BytesIO,
178
+ sock: socket.socket,
179
+ remoting_ctx: RemotingContext,
179
180
  ) -> None:
180
181
  remoting_ctx.reset()
181
182
  source = cbor2.load(stream)
@@ -199,7 +200,10 @@ class Server:
199
200
  sock.sendall(response_stream.getvalue())
200
201
 
201
202
  def parse_python_file(
202
- self, stream: BytesIO, sock: socket.socket, remoting_ctx: RemotingContext
203
+ self,
204
+ stream: BytesIO,
205
+ sock: socket.socket,
206
+ remoting_ctx: RemotingContext,
203
207
  ) -> None:
204
208
  remoting_ctx.reset()
205
209
  path = cbor2.load(stream)
@@ -209,7 +213,14 @@ class Server:
209
213
  PythonParserBuilder()
210
214
  .build()
211
215
  .parse_inputs(
212
- [ParserInput(Path(path), None, True, lambda: read_file_contents(path))],
216
+ [
217
+ ParserInput(
218
+ Path(path),
219
+ None,
220
+ True,
221
+ lambda: read_file_contents(path),
222
+ )
223
+ ],
213
224
  None,
214
225
  ctx,
215
226
  )