public class gc extends Object
Modifier and Type | Class and Description |
---|---|
static class |
gc.CycleMarkAttr |
Modifier and Type | Field and Description |
---|---|
static String |
__doc__ |
static PyString |
__doc__collect |
static PyString |
__doc__disable |
static PyString |
__doc__enable |
static PyString |
__doc__get_count |
static PyString |
__doc__get_debug |
static PyString |
__doc__get_objects |
static PyString |
__doc__get_referents |
static PyString |
__doc__get_referrers |
static PyString |
__doc__get_thresh |
static PyString |
__doc__is_tracked |
static PyString |
__doc__isenabled |
static PyString |
__doc__set_debug |
static PyString |
__doc__set_thresh |
static String |
__name__ |
static int |
DEBUG_COLLECTABLE
print collectable objects
(in Jython scoped on monitored objects)
|
static int |
DEBUG_INSTANCES
print instances
(in Jython scoped on monitored objects)
|
static int |
DEBUG_LEAK
Bit-combination of the flags
DEBUG_COLLECTABLE ,
DEBUG_UNCOLLECTABLE , DEBUG_INSTANCES ,
DEBUG_OBJECTS , DEBUG_SAVEALL . |
static int |
DEBUG_OBJECTS
print other objects
(in Jython scoped on monitored objects)
|
static int |
DEBUG_SAVEALL
save all garbage in gc.garbage
(in Jython scoped on monitored objects)
|
static int |
DEBUG_STATS
print collection statistics
(in Jython scoped on monitored objects)
|
static int |
DEBUG_UNCOLLECTABLE
print uncollectable objects
(in Jython scoped on monitored objects)
|
static short |
DONT_FINALIZE_CYCLIC_GARBAGE
CPython prior to 3.4 does not finalize cyclic garbage
PyObjects, while Jython does this by default.
|
static short |
DONT_FINALIZE_RESURRECTED_OBJECTS
If in CPython an object is resurrected via its finalizer
and contained strong references to other objects, these
are also resurrected and not finalized in CPython (as
their reference count never drops to zero).
|
static short |
DONT_TRAVERSE_BY_REFLECTION
Reflection-based traversion is currently an experimental feature and
is deactivated by default for now.
|
static PyList |
garbage
list of uncollectable objects
|
static long |
gcRecallTime |
static short |
MONITOR_GLOBAL
This flag tells every newly created PyObject to register for
gc-monitoring.
|
static short |
PRESERVE_WEAKREFS_ON_RESURRECTION
If a PyObject is resurrected during its finalization
process and was weakly referenced, Jython breaks the
weak references to the resurrected PyObject by default.
|
static short |
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
If this flag is not set, gc warns whenever an object would be subject to
reflection-based traversion.
|
static int |
UNKNOWN_COUNT
A constant that can occur as result of
collect() and
indicates an unknown number of collected cyclic trash. |
static short |
USE_PY_WRITE_DEBUG
In Jython one usually uses
Py.writeDebug for debugging output. |
static short |
VERBOSE
|
static short |
VERBOSE_COLLECT
Enables collection-related verbose-output.
|
static short |
VERBOSE_DELAYED
Enables delayed finalization related verbose-output.
|
static short |
VERBOSE_FINALIZE
Enables finalization-related verbose-output.
|
static short |
VERBOSE_WEAKREF
Enables weakref-related verbose-output.
|
Constructor and Description |
---|
gc() |
Modifier and Type | Method and Description |
---|---|
static void |
addJythonGCFlags(short flags)
This is a convenience method to add flags via bitwise or.
|
static boolean |
canLinkToPyObject(Class<?> cls,
boolean actual)
This method checks via type-checking-only, whether an object
of the given class can in principle hold a ref to a
PyObject . |
static int |
collect()
If no objects are monitored, this just delegates to
System.gc() and returns UNKNOWN_COUNT as a
non-erroneous default value. |
static int |
collect(int generation)
The generation parameter is only for compatibility with
CPython
gc.collect() and is ignored. |
static boolean |
delayedFinalizationEnabled() |
static void |
disable()
Not supported by Jython.
|
static void |
enable()
Does nothing in Jython as Java-gc is always enabled.
|
static Set<PyObject> |
findCyclicObjects(PyObject start)
Return objects that are reachable from start AND can reach start,
thus participate in a cycle with start.
|
static PyObject |
get_count()
Not supported by Jython.
|
static int |
get_debug()
Copied from CPython-doc:
Get the garbage collection debugging flags. |
static PyObject |
get_objects()
Not supported by Jython.
|
static PyObject |
get_referents(PyObject[] args,
String[] kwargs)
Only works reliably if all objects in args properly
implement the Traverseproc mechanism (unless reflection-based traversion
is activated and works stable).
|
static PyObject |
get_referrers(PyObject[] args,
String[] kwargs)
Only works reliably if
monitorGlobal is active, as it depends on
monitored objects to search for referrers. |
static PyObject |
get_threshold()
Not supported by Jython.
|
static short |
getJythonGCFlags()
Gets the current Jython-specific gc-flags.
|
static boolean |
getMonitorGlobal() |
static org.python.modules.gc.WeakReferenceGC |
getMonitorReference(PyObject ob)
Avoid to use this method.
|
static int |
indexOfPostFinalizationProcess(Runnable process) |
static int |
indexOfPreFinalizationProcess(Runnable process) |
static PyObject |
is_tracked(PyObject[] args,
String[] kwargs)
is_tracked is - in Jython case - interpreted in the sense that
gc.collect will be able to count the object as collected if it
participates in a cycle. |
static boolean |
isenabled()
Always returns
true in Jython. |
static boolean |
isMonitored(PyObject ob) |
static boolean |
isMonitoring() |
static boolean |
isTraversable(PyObject ob) |
static void |
markCyclicObjects(PyObject start,
boolean uncollectable)
Mark all objects that are reachable from start AND can reach start,
thus participate in a cycle with start.
|
static void |
monitorObject(PyObject ob) |
static void |
monitorObject(PyObject ob,
boolean initString) |
static void |
notifyFinalize(PyObject finalized)
Do not call this method manually.
|
static void |
notifyPostFinalization() |
static void |
notifyPreFinalization() |
static void |
registerForDelayedFinalization(PyObject ob) |
static void |
registerPostFinalizationProcess(Runnable process)
Registers a process that will be called after all finalization during gc-run
is done ("finalization" refers to Jython-style finalizers ran by
FinalizeTrigger s;
to care for other finalizers these must call
gc.notifyPreFinalization() before anything else is done and
gc.notifyPostFinalization() afterwards; between these calls the finalizer
must not terminate by throwing an exception). |
static void |
registerPostFinalizationProcess(Runnable process,
int index)
See doc of
registerPostFinalizationProcess(Runnable process) . |
static void |
registerPreFinalizationProcess(Runnable process)
Registers a process that will be called before any finalization during gc-run
takes place ("finalization" refers to Jython-style finalizers ran by
FinalizeTrigger s;
to care for other finalizers these must call
gc.notifyPreFinalization() before anything else is done and
gc.notifyPostFinalization() afterwards; between these calls the finalizer
must not terminate by throwing an exception). |
static void |
registerPreFinalizationProcess(Runnable process,
int index)
See doc of .
|
static void |
removeJythonGCFlags(short flags)
This is a convenience method to remove flags via bitwise and-not.
|
static void |
set_debug(int flags)
Copied from CPython-doc:
Set the garbage collection debugging flags. |
static void |
set_threshold(PyObject[] args,
String[] kwargs)
Not supported by Jython.
|
static void |
setJythonGCFlags(short flags)
Sets the current Jython-specific gc-flags.
|
static void |
setMonitorGlobal(boolean flag) |
static void |
stopMonitoring() |
static int |
traverse(PyObject ob,
Visitproc visit,
Object arg)
Does its best to traverse the given
PyObject
ob . |
static int |
traverseByReflection(Object ob,
Visitproc visit,
Object arg)
This method recursively traverses fields of
ob . |
static void |
unmonitorAll() |
static boolean |
unmonitorObject(PyObject ob) |
static boolean |
unregisterPostFinalizationProcess(Runnable process) |
static void |
unregisterPostFinalizationProcessAfterNextRun(Runnable process)
Useful if a process wants to remove another one or itself during its execution.
|
static boolean |
unregisterPreFinalizationProcess(Runnable process) |
static void |
unregisterPreFinalizationProcessAfterNextRun(Runnable process)
Useful if a process wants to remove another one or itself during its execution.
|
static void |
writeDebug(String type,
String msg)
Works like
Py.writeDebug(String, String) ,
but prints to Py.writeDebug(String, String)
(i.e. subject to Jython's verbose level)
or directly to System.err , according to
USE_PY_WRITE_DEBUG . |
public static final int UNKNOWN_COUNT
collect()
and
indicates an unknown number of collected cyclic trash.
It is intentionally not valued -1 as that value is
reserved to indicate an error.public static final short MONITOR_GLOBAL
collect()
to report the
number of collected objects.public static final short DONT_FINALIZE_CYCLIC_GARBAGE
gc.garbage
list instead).public static final short PRESERVE_WEAKREFS_ON_RESURRECTION
Traverseproc
).
Note that this feature comes with some cost as it can
delay garbage collection of some weak referenced objects
for several gc cycles if activated. So we recommend to
use it only for debugging.public static final short DONT_FINALIZE_RESURRECTED_OBJECTS
public static final short DONT_TRAVERSE_BY_REFLECTION
DONT_TRAVERSE_BY_REFLECTION
is set by default.
Once it is stable, reflection-based traversion will be active by default.public static final short SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
If this flag is not set, gc warns whenever an object would be subject to
reflection-based traversion.
Note that if this flag is not set, the warning will occur even if
reflection-based traversion is not active. The purpose of this behavior is
to identify objects that don't properly support the traverseproc-mechanism,
i.e. instances of PyObject-subclasses that neither implement
Traverseproc
,
nor are annotated with the Untraversable
-annotation.
A SUPPRESS-flag was chosen rather than a WARN-flag, so that warning is the default behavior - the user must actively set this flag in order to not to be warned. This is because in an ideal implementation reflection-based traversion never occurs; it is only an inefficient fallback.
public static final short USE_PY_WRITE_DEBUG
Py.writeDebug
for debugging output.
However that method is only verbose if an appropriate verbose-level
was set. In CPython it is enough to set gc-DEBUG
flags to get
gc-messages, no matter what overall verbose level is selected.
This flag tells Jython to use Py.writeDebug
for debugging output.
If it is not set (default-case), gc-debugging output (if gc-VERBOSE
or -DEBUG
flags are set) is directly written to System.err
.public static final short VERBOSE_COLLECT
public static final short VERBOSE_WEAKREF
public static final short VERBOSE_DELAYED
public static final short VERBOSE_FINALIZE
public static final short VERBOSE
public static final int DEBUG_STATS
set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static final int DEBUG_COLLECTABLE
set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static final int DEBUG_UNCOLLECTABLE
set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static final int DEBUG_INSTANCES
set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static final int DEBUG_OBJECTS
set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static final int DEBUG_SAVEALL
set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static final int DEBUG_LEAK
DEBUG_COLLECTABLE
,
DEBUG_UNCOLLECTABLE
, DEBUG_INSTANCES
,
DEBUG_OBJECTS
, DEBUG_SAVEALL
.set_debug(int)
,
get_debug()
,
Constant Field Valuespublic static long gcRecallTime
public static PyList garbage
public static final String __doc__
public static final String __name__
public static final PyString __doc__enable
public static final PyString __doc__disable
public static final PyString __doc__isenabled
public static final PyString __doc__collect
public static final PyString __doc__get_count
public static final PyString __doc__set_debug
public static final PyString __doc__get_debug
public static final PyString __doc__set_thresh
public static final PyString __doc__get_thresh
public static final PyString __doc__get_objects
public static final PyString __doc__is_tracked
public static final PyString __doc__get_referrers
public static final PyString __doc__get_referents
public static void writeDebug(String type, String msg)
Py.writeDebug(String, String)
,
but prints to Py.writeDebug(String, String)
(i.e. subject to Jython's verbose level)
or directly to System.err
, according to
USE_PY_WRITE_DEBUG
.public static boolean delayedFinalizationEnabled()
public static void registerForDelayedFinalization(PyObject ob)
public static void registerPreFinalizationProcess(Runnable process)
Registers a process that will be called before any finalization during gc-run
takes place ("finalization" refers to Jython-style finalizers ran by
FinalizeTrigger
s;
to care for other finalizers these must call
gc.notifyPreFinalization()
before anything else is done and
gc.notifyPostFinalization()
afterwards; between these calls the finalizer
must not terminate by throwing an exception). (Note: Using this for extern
finalizers is currently experimental and needs more testing.)
This works independently from monitoring, which is mainly needed to allow
counting of cyclic garbage in gc.collect
.
This feature compensates that Java's gc does not provide any guarantees about finalization order. Java not even guarantees that when a weak reference is added to a reference queue, its finalizer already ran or not yet ran, if any.
The only guarantee is that PhantomReference
s are enqueued
after finalization of their referents, but this happens in another gc-cycle then.
Actually there are still situations that can cause pre-finalization process to
run again during finalization phase. This can happen if external frameworks use
their own finalizers. This can be cured by letting these finalizers call
gc.notifyPreFinalization()
before anything else is done and
gc.notifyPostFinalization()
right before the finalization method returns.
Between these calls the finalizer must not terminate by throwing an exception.
(Note: Using this for extern finalizers is currently experimental and needs more testing.)
We recommend to use this feature in a way such that false-positive runs are not critically harmful, e.g. use it to enhance performance, but don't let it cause a crash if preprocess is rerun unexpectedly.
public static void registerPreFinalizationProcess(Runnable process, int index)
public static int indexOfPreFinalizationProcess(Runnable process)
public static boolean unregisterPreFinalizationProcess(Runnable process)
public static void unregisterPreFinalizationProcessAfterNextRun(Runnable process)
public static void registerPostFinalizationProcess(Runnable process)
Registers a process that will be called after all finalization during gc-run
is done ("finalization" refers to Jython-style finalizers ran by
FinalizeTrigger
s;
to care for other finalizers these must call
gc.notifyPreFinalization()
before anything else is done and
gc.notifyPostFinalization()
afterwards; between these calls the finalizer
must not terminate by throwing an exception). (Note: Using this for extern
finalizers is currently experimental and needs more testing.)
This works independently from monitoring (which is mainly needed to allow
garbage counting in gc.collect
).
This feature compensates that Java's gc does not provide any guarantees about finalization order. Java not even guarantees that when a weak reference is added to a reference queue, its finalizer already ran or not yet ran, if any.
The only guarantee is that PhantomReference
s are
enqueued after finalization of the referents, but this
happens - however - in another gc-cycle then.
There are situations that can cause post finalization process to run
already during finalization phase. This can happen if external frameworks use
their own finalizers. This can be cured by letting these finalizers call
gc.notifyPreFinalization()
before anything else is done and
notifyPostFinalization()
right before the finalization method returns.
Between these calls the finalizer must not terminate by throwing an exception.
(Note: Using this for extern finalizers is currently experimental and needs more testing.)
If it runs too early, we can at least guarantee that it will run again after finalization was really done. So we recommend to use this feature in a way such that false-positive runs are not critically harmful.
public static void registerPostFinalizationProcess(Runnable process, int index)
registerPostFinalizationProcess(Runnable process)
.public static int indexOfPostFinalizationProcess(Runnable process)
public static boolean unregisterPostFinalizationProcess(Runnable process)
public static void unregisterPostFinalizationProcessAfterNextRun(Runnable process)
public static void notifyPreFinalization()
public static void notifyPostFinalization()
public static void monitorObject(PyObject ob)
public static void monitorObject(PyObject ob, boolean initString)
public static org.python.modules.gc.WeakReferenceGC getMonitorReference(PyObject ob)
public static boolean isMonitoring()
public static boolean isMonitored(PyObject ob)
public static boolean unmonitorObject(PyObject ob)
public static void unmonitorAll()
public static void stopMonitoring()
public static boolean getMonitorGlobal()
public static void setMonitorGlobal(boolean flag)
public static short getJythonGCFlags()
MONITOR_GLOBAL
,
DONT_FINALIZE_CYCLIC_GARBAGE
,
PRESERVE_WEAKREFS_ON_RESURRECTION
,
DONT_FINALIZE_RESURRECTED_OBJECTS
,
DONT_TRAVERSE_BY_REFLECTION
,
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
,
USE_PY_WRITE_DEBUG
,
VERBOSE_COLLECT
,
VERBOSE_WEAKREF
,
VERBOSE_DELAYED
,
VERBOSE_FINALIZE
,
VERBOSE
,
setJythonGCFlags(short)
,
addJythonGCFlags(short)
,
removeJythonGCFlags(short)
public static void setJythonGCFlags(short flags)
flags
is a short
and can have the following bits turned on:MONITOR_GLOBAL
- Automatically monitors all PyObjects created from now on.DONT_FINALIZE_CYCLIC_GARBAGE
- Adds cyclic finalizable PyObjects to garbage
.PRESERVE_WEAKREFS_ON_RESURRECTION
- Keeps weak references alive if the referent is resurrected.DONT_FINALIZE_RESURRECTED_OBJECTS
-
Emulates CPython behavior regarding resurrected objects and finalization.DONT_TRAVERSE_BY_REFLECTION
- Inhibits reflection-based traversion.SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
-
Suppress warnings for PyObjects that neither implement Traverseproc
nor
are marked as Untraversable
.USE_PY_WRITE_DEBUG
- uses Py.writeDebug(String, String)
for
debugging output instead of directly writing to System.err
.VERBOSE_COLLECT
- Enable collection-related verbose output.VERBOSE_WEAKREF
- Enable weakref-related verbose output.VERBOSE_DELAYED
- Enable delayed finalization-related verbose output.VERBOSE_FINALIZE
- Enable finalization-related verbose output.VERBOSE
- All previous verbose-flags combined.MONITOR_GLOBAL
,
DONT_FINALIZE_CYCLIC_GARBAGE
,
PRESERVE_WEAKREFS_ON_RESURRECTION
,
DONT_FINALIZE_RESURRECTED_OBJECTS
,
DONT_TRAVERSE_BY_REFLECTION
,
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
,
USE_PY_WRITE_DEBUG
,
VERBOSE_COLLECT
,
VERBOSE_WEAKREF
,
VERBOSE_DELAYED
,
VERBOSE_FINALIZE
,
VERBOSE
,
getJythonGCFlags()
,
addJythonGCFlags(short)
,
removeJythonGCFlags(short)
public static void addJythonGCFlags(short flags)
MONITOR_GLOBAL
,
DONT_FINALIZE_CYCLIC_GARBAGE
,
PRESERVE_WEAKREFS_ON_RESURRECTION
,
DONT_FINALIZE_RESURRECTED_OBJECTS
,
DONT_TRAVERSE_BY_REFLECTION
,
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
,
USE_PY_WRITE_DEBUG
,
VERBOSE_COLLECT
,
VERBOSE_WEAKREF
,
VERBOSE_DELAYED
,
VERBOSE_FINALIZE
,
VERBOSE
,
getJythonGCFlags()
,
setJythonGCFlags(short)
,
removeJythonGCFlags(short)
public static void removeJythonGCFlags(short flags)
MONITOR_GLOBAL
,
DONT_FINALIZE_CYCLIC_GARBAGE
,
PRESERVE_WEAKREFS_ON_RESURRECTION
,
DONT_FINALIZE_RESURRECTED_OBJECTS
,
DONT_TRAVERSE_BY_REFLECTION
,
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
,
USE_PY_WRITE_DEBUG
,
VERBOSE_COLLECT
,
VERBOSE_WEAKREF
,
VERBOSE_DELAYED
,
VERBOSE_FINALIZE
,
VERBOSE
,
getJythonGCFlags()
,
setJythonGCFlags(short)
,
addJythonGCFlags(short)
public static void notifyFinalize(PyObject finalized)
FinalizeTrigger
.public static void enable()
public static void disable()
Py.NotImplementedError
.org.python.core.Py#NotImplementedError
public static boolean isenabled()
true
in Jython.public static int collect(int generation)
gc.collect()
and is ignored.generation
- (ignored)gc.UNKNOWN_COUNT
if nothing is monitored or -1 if
an error occurred and collection did not complete.collect()
public static int collect()
System.gc()
and returns UNKNOWN_COUNT
as a
non-erroneous default value. If objects are monitored,
it emulates a synchronous gc-run in the sense that it waits
until all collected monitored objects were finalized.UNKNOWN_COUNT
if nothing is monitored or -1
if an error occurred and collection did not complete.UNKNOWN_COUNT
,
collect(int)
public static PyObject get_count()
Py.NotImplementedError
.org.python.core.Py#NotImplementedError
public static void set_debug(int flags)
System.err
.int
eger and can have the following bits turned on:DEBUG_STATS
- Print statistics during collection.DEBUG_COLLECTABLE
- Print collectable objects found.DEBUG_UNCOLLECTABLE
- Print unreachable but uncollectable objects found.DEBUG_INSTANCES
- Print instance objects.DEBUG_OBJECTS
- Print objects other than instances.DEBUG_SAVEALL
- Save objects to gc.garbage rather than freeing them.DEBUG_LEAK
- Debug leaking programs (everything but STATS).public static int get_debug()
public static void set_threshold(PyObject[] args, String[] kwargs)
Py.NotImplementedError
.org.python.core.Py#NotImplementedError
public static PyObject get_threshold()
Py.NotImplementedError
.org.python.core.Py#NotImplementedError
public static PyObject get_objects()
Py.NotImplementedError
.org.python.core.Py#NotImplementedError
public static PyObject get_referrers(PyObject[] args, String[] kwargs)
monitorGlobal
is active, as it depends on
monitored objects to search for referrers. It only finds referrers that
properly implement the traverseproc mechanism (unless reflection-based
traversion is activated and works stable).
Further note that the resulting list will contain referrers in no specific
order and may even include duplicates.public static PyObject get_referents(PyObject[] args, String[] kwargs)
public static PyObject is_tracked(PyObject[] args, String[] kwargs)
is_tracked
is - in Jython case - interpreted in the sense that
gc.collect
will be able to count the object as collected if it
participates in a cycle. This mimics CPython behavior and passes
the corresponding unit test in test_gc.py
.public static void markCyclicObjects(PyObject start, boolean uncollectable)
public static Set<PyObject> findCyclicObjects(PyObject start)
null
if start does not participate in any cycle.public static int traverse(PyObject ob, Visitproc visit, Object arg)
PyObject
ob
. It exploits both
Traverseproc.traverse(Visitproc, Object)
and
TraverseprocDerived.traverseDerived(Visitproc, Object)
.
If ob
neither implements Traverseproc
nor
Traverseproc
and is not annotated with
Untraversable
, reflection-based traversion via
traverseByReflection(Object, Visitproc, Object)
may be attempted
according to DONT_TRAVERSE_BY_REFLECTION
.public static int traverseByReflection(Object ob, Visitproc visit, Object arg)
This method recursively traverses fields of ob
.
If a field is a PyObject, it is passed to visit
.
and recursion ends in that branch.
If a field is an array, the elements are checked whether
they are PyObjects. PyObject
-elements are passed to
visit
. Elements that are arrays themselves are again
processed elementwise and so on.
Through the whole search this method fails fast if
visit
returns non-zero.
Note that we intentionally don't traverse iterables by iterating them. Since we perform recursion, this should reach all contained references anyway - in Java every object can only contain references as fields or arrays. On the one hand, exploiting iterables would ease the access to private fields, but on the other hand during iteration they might change inner state, create new (Py)Objects or obtain objects from native methods. Additionally we might run into concurrent modification issues. So all in all the traversal is cleaner and safer if just fields and arrays are traversed.
public static boolean canLinkToPyObject(Class<?> cls, boolean actual)
This method checks via type-checking-only, whether an object
of the given class can in principle hold a ref to a PyObject
.
Especially if arrays are involved, this can safe a lot performance.
For now, no generic-type info is exploited.
If actual
is true, the answer will hold for an object
that is an instance of the given class.
Otherwise it is assumed that cls is the type of a field holding an
object, so cls is considered as upper bound for an objects actual
type.
One should call with actual == true
, if cls was obtained
by ob.getClass()
and with actual == false
, if cls
was obtained as a field-type or component-type of an array.
public static boolean isTraversable(PyObject ob)