Skip to content

Commit fcb9d9d

Browse files
committed
Merged PR posit-dev/positron-python#86: Add some additional documentation to positron python
Merge pull request #86 from posit-dev/positron-docs Add some additional documentation to positron python -------------------- Commit message for posit-dev/positron-python@4b19d94: Add some additional documentation to positron python Authored-by: Pete Farland <[email protected]> Signed-off-by: Pete Farland <[email protected]>
1 parent 8531217 commit fcb9d9d

File tree

3 files changed

+126
-52
lines changed

3 files changed

+126
-52
lines changed

extensions/positron-python/pythonFiles/positron/environment.py

+75-21
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,15 @@ def on_comm_open(self, comm, open_msg) -> None:
182182

183183
def receive_message(self, msg) -> None:
184184
"""
185-
Handle messages sent by the client to the positron.environment comm.
185+
Handle messages received from the client via the positron.environment comm.
186+
187+
Message Types:
188+
"inspect" - Inspect the user variable at the requested path
189+
"refresh" - Refresh the list of user variables in the environment
190+
"view" - Format the variable at the requested path for the data viewer
191+
"clipboard_format" - Format the variable at the requested path for the client clipboard
192+
"clear" - Clear all user variables in the environment
193+
"delete" - Delete user variables in the environment by name
186194
"""
187195
data = msg["content"]["data"]
188196

@@ -214,6 +222,10 @@ def receive_message(self, msg) -> None:
214222
self._send_error(f"Unknown message type '{msgType}'")
215223

216224
def send_update(self, assigned: dict, removed: set) -> None:
225+
"""
226+
Sends the list of variables that have changed in the current user session through the
227+
environment comm to the client.
228+
"""
217229
# Ensure the number of changes does not exceed our maximum items
218230
if len(assigned) < MAX_ITEMS and len(removed) < MAX_ITEMS:
219231
self._send_update(assigned, removed)
@@ -264,7 +276,7 @@ def _send_message(self, msg: EnvironmentMessage) -> None:
264276

265277
self.env_comm.send(msg)
266278

267-
def _send_error(self, message: str) -> None:
279+
def _send_error(self, error_message: str) -> None:
268280
"""
269281
Send an error message through the envirvonment comm to the client.
270282
@@ -277,7 +289,7 @@ def _send_error(self, message: str) -> None:
277289
...
278290
}
279291
"""
280-
msg = EnvironmentMessageError(message)
292+
msg = EnvironmentMessageError(error_message)
281293
self._send_message(msg)
282294

283295
def _send_update(self, assigned: Mapping, removed: Iterable) -> None:
@@ -312,12 +324,24 @@ def _send_update(self, assigned: Mapping, removed: Iterable) -> None:
312324
def _delete_all_vars(self, parent) -> None:
313325
"""
314326
Deletes all of the variables in the current user session.
327+
328+
Args:
329+
parent:
330+
A dict providing the parent context for the response,
331+
e.g. the client message requesting the clear operation
315332
"""
316333
self.kernel.delete_all_vars(parent)
317334

318335
def _delete_vars(self, names: Iterable, parent) -> None:
319336
"""
320337
Deletes the requested variables by name from the current user session.
338+
339+
Args:
340+
names:
341+
A list of variable names to delete
342+
parent:
343+
A dict providing the parent context for the response,
344+
e.g. the client message requesting the delete operation
321345
"""
322346
if names is None:
323347
return
@@ -328,12 +352,15 @@ def _delete_vars(self, names: Iterable, parent) -> None:
328352
def _inspect_var(self, path: Sequence) -> None:
329353
"""
330354
Describes the variable at the requested path in the current user session.
355+
356+
Args:
357+
path:
358+
A list of names describing the path to the variable.
331359
"""
332360
if path is None:
333361
return
334362

335363
is_known, value = self.kernel.find_var(path)
336-
337364
if is_known:
338365
self._send_details(path, value)
339366
else:
@@ -357,8 +384,14 @@ def _send_formatted_var(
357384
Formats the variable at the requested path in the current user session
358385
using the requested clipboard format and sends the result through the
359386
environment comm to the client.
360-
"""
361387
388+
Args:
389+
path:
390+
A list of names describing the path to the variable.
391+
clipboard_format:
392+
The format to use for the clipboard copy, described as a mime type.
393+
Defaults to "text/plain".
394+
"""
362395
if path is None:
363396
return
364397

@@ -372,7 +405,7 @@ def _send_formatted_var(
372405
message = f"Cannot find variable at '{path}' to format"
373406
self._send_error(message)
374407

375-
def _send_details(self, path: Sequence, context: Any = None):
408+
def _send_details(self, path: Sequence, value: Any = None):
376409
"""
377410
Sends a detailed list of children of the value (or just the value
378411
itself, if is a leaf node on the path) as a message through the
@@ -397,15 +430,21 @@ def _send_details(self, path: Sequence, context: Any = None):
397430
}
398431
...
399432
}
433+
434+
Args:
435+
path:
436+
A list of names describing the path to the variable.
437+
value:
438+
The variable's value to summarize.
400439
"""
401440

402441
children = []
403-
inspector = get_inspector(context)
404-
if inspector is not None and inspector.has_children(context):
405-
children = inspector.summarize_children(context, self._summarize_variable)
442+
inspector = get_inspector(value)
443+
if inspector.has_children(value):
444+
children = inspector.summarize_children(value, self._summarize_variable)
406445
else:
407446
# Otherwise, treat as a simple value at given path
408-
summary = self._summarize_variable("", context)
447+
summary = self._summarize_variable("", value)
409448
if summary is not None:
410449
children.append(summary)
411450
# TODO: Handle scalar objects with a specific message type
@@ -414,11 +453,19 @@ def _send_details(self, path: Sequence, context: Any = None):
414453
self._send_message(msg)
415454

416455
def _summarize_variables(self, variables: Mapping, max_items: int = MAX_ITEMS) -> list:
456+
"""
457+
Summarizes the given variables into a list of EnvironmentVariable objects.
458+
459+
Args:
460+
variables:
461+
A mapping of variable names to values.
462+
max_items:
463+
The maximum number of items to summarize.
464+
"""
417465
summaries = []
418466

419467
for key, value in variables.items():
420-
# Ensure the number of items summarized is within our
421-
# max limit
468+
# Ensure the number of items summarized is within our max limit
422469
if len(summaries) >= max_items:
423470
break
424471

@@ -428,22 +475,28 @@ def _summarize_variables(self, variables: Mapping, max_items: int = MAX_ITEMS) -
428475

429476
return summaries
430477

431-
def _summarize_variable(self, key, value) -> Optional[EnvironmentVariable]:
478+
def _summarize_variable(self, key: Any, value: Any) -> Optional[EnvironmentVariable]:
479+
"""
480+
Summarizes the given variable into an EnvironmentVariable object.
481+
482+
Returns:
483+
An EnvironmentVariable summary, or None if the variable should be skipped.
484+
"""
432485
# Hide module types for now
433486
if isinstance(value, types.ModuleType):
434487
return None
435488

436-
display_name = str(key)
437-
438489
try:
439490
# Use an inspector to summarize the value
440491
ins = get_inspector(value)
441492

493+
display_name = ins.get_display_name(key)
442494
kind_str = ins.get_kind(value)
443495
kind = getattr(EnvironmentVariableKind, kind_str.upper())
444496
display_value, is_truncated = ins.get_display_value(value)
445497
display_type = ins.get_display_type(value)
446498
type_info = ins.get_type_info(value)
499+
access_key = ins.get_access_key(key)
447500
length = ins.get_length(value)
448501
size = ins.get_size(value)
449502
has_children = ins.has_children(value)
@@ -455,7 +508,7 @@ def _summarize_variable(self, key, value) -> Optional[EnvironmentVariable]:
455508
display_type=display_type,
456509
kind=kind,
457510
type_info=type_info,
458-
access_key=display_name,
511+
access_key=access_key,
459512
length=length,
460513
size=size,
461514
has_children=has_children,
@@ -466,17 +519,18 @@ def _summarize_variable(self, key, value) -> Optional[EnvironmentVariable]:
466519
except Exception as err:
467520
logging.warning(err, exc_info=True)
468521
return EnvironmentVariable(
469-
display_name=display_name,
522+
display_name=str(key),
470523
display_value=get_qualname(value),
471524
kind=EnvironmentVariableKind.OTHER,
472525
)
473526

474-
def _format_value(self, value, clipboard_format: ClipboardFormat) -> str:
527+
def _format_value(self, value: Any, clipboard_format: ClipboardFormat) -> str:
528+
"""
529+
Formats the given value using the requested clipboard format.
530+
"""
475531
inspector = get_inspector(value)
476532

477533
if clipboard_format == ClipboardFormat.HTML:
478534
return inspector.to_html(value)
479-
elif clipboard_format == ClipboardFormat.PLAIN:
480-
return inspector.to_tsv(value)
481535
else:
482-
return str(value)
536+
return inspector.to_plaintext(value)

extensions/positron-python/pythonFiles/positron/inspectors.py

+24-8
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@
2323
# conditional property lookup
2424
__POSITRON_DEFAULT__ = object()
2525

26-
# Base inspector for any type
26+
#
27+
# Base inspector
28+
#
2729

2830

2931
class PositronInspector:
3032
"""
3133
Base inspector for any type
3234
"""
3335

36+
def get_display_name(self, key: Any) -> str:
37+
return str(key)
38+
3439
def get_display_value(
3540
self,
3641
value: Any,
@@ -75,6 +80,9 @@ def get_kind(self, value: Any) -> str:
7580
def get_type_info(self, value: Any) -> str:
7681
return get_qualname(value)
7782

83+
def get_access_key(self, name: Any) -> str:
84+
return self.get_display_name(name)
85+
7886
def get_length(self, value: Any) -> int:
7987
return get_value_length(value)
8088

@@ -113,11 +121,13 @@ def to_dataset(self, value: Any, title: str) -> Optional[DataSet]:
113121
def to_html(self, value: Any) -> str:
114122
return repr(value)
115123

116-
def to_tsv(self, value: Any) -> str:
124+
def to_plaintext(self, value: Any) -> str:
117125
return repr(value)
118126

119127

128+
#
120129
# Inspectors by kind
130+
#
121131

122132

123133
class BooleanInspector(PositronInspector):
@@ -318,7 +328,9 @@ def is_snapshottable(self, value: Any) -> bool:
318328
return True
319329

320330

331+
#
321332
# Custom inspectors for specific types
333+
#
322334

323335

324336
class PandasDataFrameInspector(TableInspector):
@@ -406,7 +418,7 @@ def to_dataset(self, value: Any, title: str) -> Optional[DataSet]:
406418
def to_html(self, value: Any) -> str:
407419
return value.to_html()
408420

409-
def to_tsv(self, value: Any) -> str:
421+
def to_plaintext(self, value: Any) -> str:
410422
return value.to_csv(path_or_buf=None, sep="\t")
411423

412424

@@ -481,9 +493,9 @@ def copy(self, value: Any) -> Any:
481493

482494
def to_html(self, value: Any) -> str:
483495
# TODO: Support HTML
484-
return self.to_tsv(value)
496+
return self.to_plaintext(value)
485497

486-
def to_tsv(self, value: Any) -> str:
498+
def to_plaintext(self, value: Any) -> str:
487499
return value.to_csv(path_or_buf=None, sep="\t")
488500

489501

@@ -570,7 +582,7 @@ def to_dataset(self, value: Any, title: str) -> Optional[DataSet]:
570582
def to_html(self, value: Any) -> str:
571583
return value._repr_html_()
572584

573-
def to_tsv(self, value: Any) -> str:
585+
def to_plaintext(self, value: Any) -> str:
574586
return value.write_csv(file=None, separator="\t")
575587

576588

@@ -695,8 +707,12 @@ def copy(self, value: Any) -> Any:
695707
"table": TableInspector(),
696708
}
697709

710+
#
711+
# Helper functions
712+
#
713+
698714

699-
def get_inspector(value) -> PositronInspector:
715+
def get_inspector(value: Any) -> PositronInspector:
700716
# Look for a specific inspector by qualified classname
701717
qualname = get_qualname(value)
702718
inspector = INSPECTORS.get(qualname, None)
@@ -713,7 +729,7 @@ def get_inspector(value) -> PositronInspector:
713729
return inspector
714730

715731

716-
def _get_kind(value) -> str:
732+
def _get_kind(value: Any) -> str:
717733
if isinstance(value, str):
718734
return "string"
719735
elif isinstance(value, bool):

0 commit comments

Comments
 (0)