Skip to content

Commit 92d7fb1

Browse files
committed
Split pretty-print functions to own subpackage
* scyjava.fields -> scyjava.inspect.fields * scyjava.methods -> scyjava.inspect.methods * scyjava.src -> scyjava.inspect.src And add new `constructors` and `members` convenience functions.
1 parent 2713b6c commit 92d7fb1

File tree

4 files changed

+157
-127
lines changed

4 files changed

+157
-127
lines changed

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,6 @@ FUNCTIONS
441441

442442
:raise RuntimeError: if this method is called while in Jep mode.
443443

444-
src(data)
445-
Print the source code URL for a Java class, object, or class name.
446-
447-
:param data: The Java class, object, or fully qualified class name as string
448-
449444
start_jvm(options=None) -> None
450445
Explicitly connect to the Java virtual machine (JVM). Only one JVM can
451446
be active; does nothing if the JVM has already been started. Calling

src/scyjava/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,8 @@
9292
to_python,
9393
)
9494
from ._introspect import (
95-
attrs,
96-
fields,
9795
jreflect,
9896
jsource,
99-
methods,
100-
src,
10197
)
10298
from ._jvm import ( # noqa: F401
10399
available_processors,

src/scyjava/_introspect.py

Lines changed: 2 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
class methods, fields, and source code URL.
44
"""
55

6-
from functools import partial
7-
from typing import Any, Dict, List, Optional
6+
from typing import Any, Dict, List
87

98
from scyjava._jvm import jimport
109
from scyjava._types import isjava, jinstance, jclass
@@ -64,7 +63,7 @@ def jreflect(data, aspect: str = "all") -> List[Dict[str, Any]]:
6463
returns = (
6564
member.getReturnType().getName()
6665
if hasattr(member, "getReturnType")
67-
else (member.getType().getName() if hasattr(member, "getType") else None)
66+
else (member.getType().getName() if hasattr(member, "getType") else name)
6867
)
6968
table.append(
7069
{
@@ -79,58 +78,6 @@ def jreflect(data, aspect: str = "all") -> List[Dict[str, Any]]:
7978
return table
8079

8180

82-
def _map_syntax(base_type):
83-
"""
84-
Map a Java BaseType annotation (see link below) in an Java array
85-
to a specific type with an Python interpretable syntax.
86-
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3
87-
"""
88-
basetype_mapping = {
89-
"[B": "byte[]",
90-
"[C": "char[]",
91-
"[D": "double[]",
92-
"[F": "float[]",
93-
"[I": "int[]",
94-
"[J": "long[]",
95-
"[L": "[]", # array
96-
"[S": "short[]",
97-
"[Z": "boolean[]",
98-
}
99-
100-
if base_type in basetype_mapping:
101-
return basetype_mapping[base_type]
102-
# Handle the case of a returned array of an object
103-
elif base_type.__str__().startswith("[L"):
104-
return base_type.__str__()[2:-1] + "[]"
105-
else:
106-
return base_type
107-
108-
109-
def _make_pretty_string(entry, offset):
110-
"""
111-
Print the entry with a specific formatting and aligned style.
112-
:param entry: Dictionary of class names, modifiers, arguments, and return values.
113-
:param offset: Offset between the return value and the method.
114-
"""
115-
116-
# A star implies that the method is a static method
117-
return_val = f"{entry['returns'].__str__():<{offset}}"
118-
# Handle whether to print static/instance modifiers
119-
obj_name = f"{entry['name']}"
120-
modifier = f"{'*':>4}" if "static" in entry["mods"] else f"{'':>4}"
121-
122-
# Handle fields
123-
if entry["arguments"] is None:
124-
return f"{return_val} {modifier} = {obj_name}\n"
125-
126-
# Handle methods with no arguments
127-
if len(entry["arguments"]) == 0:
128-
return f"{return_val} {modifier} = {obj_name}()\n"
129-
else:
130-
arg_string = ", ".join([r.__str__() for r in entry["arguments"]])
131-
return f"{return_val} {modifier} = {obj_name}({arg_string})\n"
132-
133-
13481
def jsource(data):
13582
"""
13683
Try to find the source code using SciJava's SourceFinder.
@@ -162,66 +109,3 @@ def jsource(data):
162109
return f"Not a Java class {str(type(data))}"
163110
except Exception as err:
164111
return f"Unexpected {err=}, {type(err)=}"
165-
166-
167-
def _print_data(data, aspect, static: Optional[bool] = None, source: bool = True):
168-
"""
169-
Write data to a printed string of class methods with inputs, static modifier,
170-
arguments, and return values.
171-
172-
:param data: The object or class to inspect or fully qualified class name.
173-
:param aspect: Whether to print class "fields" or "methods".
174-
:param static:
175-
Boolean filter on Static or Instance methods.
176-
Optional, default is None (prints all).
177-
:param source: Whether to print any available source code. Default True.
178-
"""
179-
table = jreflect(data, aspect)
180-
if len(table) == 0:
181-
print(f"No {aspect} found")
182-
return
183-
184-
# Print source code
185-
offset = max(list(map(lambda entry: len(entry["returns"]), table)))
186-
all_methods = ""
187-
if source:
188-
urlstring = jsource(data)
189-
print(f"Source code URL: {urlstring}")
190-
191-
# Print methods
192-
for entry in table:
193-
entry["returns"] = _map_syntax(entry["returns"])
194-
if entry["arguments"]:
195-
entry["arguments"] = [_map_syntax(e) for e in entry["arguments"]]
196-
if static is None:
197-
entry_string = _make_pretty_string(entry, offset)
198-
all_methods += entry_string
199-
200-
elif static and entry["static"]:
201-
entry_string = _make_pretty_string(entry, offset)
202-
all_methods += entry_string
203-
elif not static and not entry["static"]:
204-
entry_string = _make_pretty_string(entry, offset)
205-
all_methods += entry_string
206-
else:
207-
continue
208-
209-
# 4 added to align the asterisk with output.
210-
print(f"{'':<{offset + 4}}* indicates static modifier")
211-
print(all_methods)
212-
213-
214-
# The functions with short names for quick usage.
215-
methods = partial(_print_data, aspect="methods")
216-
fields = partial(_print_data, aspect="fields")
217-
attrs = partial(_print_data, aspect="fields")
218-
219-
220-
def src(data):
221-
"""
222-
Print the source code URL for a Java class, object, or class name.
223-
224-
:param data: The Java class, object, or fully qualified class name as string
225-
"""
226-
source_url = jsource(data)
227-
print(f"Source code URL: {source_url}")

src/scyjava/inspect.py

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
"""
2+
High-level convenience functions for inspecting Java objects.
3+
"""
4+
5+
from typing import Optional
6+
7+
from scyjava._introspect import jreflect, jsource
8+
9+
10+
def members(data):
11+
"""
12+
Print all the members (constructors, fields, and methods)
13+
for a Java class, object, or class name.
14+
15+
:param data: The Java class, object, or fully qualified class name as string.
16+
"""
17+
_print_data(data, aspect="all")
18+
19+
20+
def constructors(data):
21+
"""
22+
Print the constructors for a Java class, object, or class name.
23+
24+
:param data: The Java class, object, or fully qualified class name as string.
25+
"""
26+
_print_data(data, aspect="constructors")
27+
28+
29+
def fields(data):
30+
"""
31+
Print the fields for a Java class, object, or class name.
32+
33+
:param data: The Java class, object, or fully qualified class name as string.
34+
"""
35+
_print_data(data, aspect="fields")
36+
37+
38+
def methods(data):
39+
"""
40+
Print the methods for a Java class, object, or class name.
41+
42+
:param data: The Java class, object, or fully qualified class name as string.
43+
"""
44+
_print_data(data, aspect="methods")
45+
46+
47+
def src(data):
48+
"""
49+
Print the source code URL for a Java class, object, or class name.
50+
51+
:param data: The Java class, object, or fully qualified class name as string.
52+
"""
53+
source_url = jsource(data)
54+
print(f"Source code URL: {source_url}")
55+
56+
57+
def _map_syntax(base_type):
58+
"""
59+
Map a Java BaseType annotation (see link below) in an Java array
60+
to a specific type with an Python interpretable syntax.
61+
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3
62+
"""
63+
basetype_mapping = {
64+
"[B": "byte[]",
65+
"[C": "char[]",
66+
"[D": "double[]",
67+
"[F": "float[]",
68+
"[I": "int[]",
69+
"[J": "long[]",
70+
"[L": "[]", # array
71+
"[S": "short[]",
72+
"[Z": "boolean[]",
73+
}
74+
75+
if base_type in basetype_mapping:
76+
return basetype_mapping[base_type]
77+
# Handle the case of a returned array of an object
78+
elif base_type.__str__().startswith("[L"):
79+
return base_type.__str__()[2:-1] + "[]"
80+
else:
81+
return base_type
82+
83+
84+
def _pretty_string(entry, offset):
85+
"""
86+
Print the entry with a specific formatting and aligned style.
87+
88+
:param entry: Dictionary of class names, modifiers, arguments, and return values.
89+
:param offset: Offset between the return value and the method.
90+
"""
91+
92+
# A star implies that the method is a static method
93+
return_type = entry["returns"] or "void"
94+
return_val = f"{return_type.__str__():<{offset}}"
95+
# Handle whether to print static/instance modifiers
96+
obj_name = f"{entry['name']}"
97+
modifier = f"{'*':>4}" if "static" in entry["mods"] else f"{'':>4}"
98+
99+
# Handle fields
100+
if entry["arguments"] is None:
101+
return f"{return_val} {modifier} = {obj_name}\n"
102+
103+
# Handle methods with no arguments
104+
if len(entry["arguments"]) == 0:
105+
return f"{return_val} {modifier} = {obj_name}()\n"
106+
else:
107+
arg_string = ", ".join([r.__str__() for r in entry["arguments"]])
108+
return f"{return_val} {modifier} = {obj_name}({arg_string})\n"
109+
110+
111+
def _print_data(data, aspect, static: Optional[bool] = None, source: bool = True):
112+
"""
113+
Write data to a printed table with inputs, static modifier,
114+
arguments, and return values.
115+
116+
:param data: The object or class to inspect or fully qualified class name.
117+
:param static:
118+
Boolean filter on Static or Instance methods.
119+
Optional, default is None (prints all).
120+
:param source: Whether to print any available source code. Default True.
121+
"""
122+
table = jreflect(data, aspect)
123+
if len(table) == 0:
124+
print(f"No {aspect} found")
125+
return
126+
127+
# Print source code
128+
offset = max(list(map(lambda entry: len(entry["returns"] or "void"), table)))
129+
all_methods = ""
130+
if source:
131+
urlstring = jsource(data)
132+
print(f"Source code URL: {urlstring}")
133+
134+
# Print methods
135+
for entry in table:
136+
if entry["returns"]:
137+
entry["returns"] = _map_syntax(entry["returns"])
138+
if entry["arguments"]:
139+
entry["arguments"] = [_map_syntax(e) for e in entry["arguments"]]
140+
if static is None:
141+
entry_string = _pretty_string(entry, offset)
142+
all_methods += entry_string
143+
144+
elif static and "static" in entry["mods"]:
145+
entry_string = _pretty_string(entry, offset)
146+
all_methods += entry_string
147+
elif not static and "static" not in entry["mods"]:
148+
entry_string = _pretty_string(entry, offset)
149+
all_methods += entry_string
150+
else:
151+
continue
152+
153+
# 4 added to align the asterisk with output.
154+
print(f"{'':<{offset + 4}}* indicates static modifier")
155+
print(all_methods)

0 commit comments

Comments
 (0)