Class PyType

All Implemented Interfaces:
Serializable, Traverseproc
Direct Known Subclasses:
PyJavaType, PyTypeDerived

public class PyType extends PyObject implements Serializable, Traverseproc
This class implements the Python type object and the static methods and data structures that support the Python type system in Jython (the type registry).

The class PyType contains static data that describes Python types, that are consulted and modified through its static API (notably fromClass(Class)). The data structures are guarded against modification by concurrent threads (or consultation while being modified). They support construction of type objects that are visible to Python.

Bootstrapping of the type system: The first attempt to construct or get a PyObject (or instance of a subclass of PyObject), to use the Py class utilities, or to call fromClass(Class), causes the Jython type system to be initialised. By the time that call returns, the type system will be in working order: any PyTypes the application sees will be fully valid. Also, provided that the static initialisation of the PyObject subclass in question is not obstructed for any other reason, the instance returned will also be fully functional. Note that it is possible to refer to C.class, and (if it is not an exposed type) to produce a PyType for it, without causing the static initialisation of C.

This may be no less than the reader expected, but we mention it because, for classes encountered during the bootstrapping of the type system, this guarantee is not offered. The (static) initialisation of the type system is highly reentrant. Classes that are used by the type system itself, and their instances, do encounter defective PyType objects. Instances of these classes, which include mundane classes like PyNone and PyString, may exist before their class is statically initialised in the JVM sense. The type system has been implemented with this fact constantly in mind. The PyType encountered is always the "right" one — the unique instance representing the Python type of that class — but it may not be completely filled in. Debugging that enters these classes during bootstrapping will take surprising turns. Changes to these classes should also take this into account.

See Also:
  • Field Details

    • TYPE

      public static final PyType TYPE
      The PyType of PyType (or type(type)).
  • Method Details

    • newType

      public static PyObject newType(PyNewWrapper new_, PyType metatype, String name, PyTuple bases, PyObject dict)
    • ensureDoc

      public static void ensureDoc(PyObject dict)
      Ensure dict contains a __doc__.
      Parameters:
      dict - a PyObject mapping
    • ensureModule

      public static void ensureModule(PyObject dict)
      Ensure dict contains a __module__, retrieving it from the current frame if it doesn't exist.
      Parameters:
      dict - a PyObject mapping
    • getStatic

      public PyObject getStatic()
    • needsFinalizer

      public final boolean needsFinalizer()
      Offers public read-only access to the protected field needs_finalizer.
      Returns:
      a boolean indicating whether the type implements __del__
    • compatibleForAssignment

      public void compatibleForAssignment(PyType other, String attribute)
      Ensures that the physical layout between this type and other are compatible. Raises a TypeError if not.
    • type___eq__

      public PyObject type___eq__(PyObject other)
    • type___ne__

      public PyObject type___ne__(PyObject other)
    • type___le__

      public PyObject type___le__(PyObject other)
    • type___lt__

      public PyObject type___lt__(PyObject other)
    • type___ge__

      public PyObject type___ge__(PyObject other)
    • type___gt__

      public PyObject type___gt__(PyObject other)
    • getBase

      public PyObject getBase()
    • getBases

      public PyObject getBases()
    • delBases

      public void delBases()
    • setBases

      public void setBases(PyObject newBasesTuple)
    • instDict

      public PyObject instDict()
    • getMro

      public PyTuple getMro()
    • getFlags

      public PyLong getFlags()
    • type___subclasses__

      public final PyObject type___subclasses__()
    • type___subclasscheck__

      public final boolean type___subclasscheck__(PyObject inst)
    • type___instancecheck__

      public final boolean type___instancecheck__(PyObject inst)
    • getProxyType

      public Class<?> getProxyType()
      Returns the Java Class that this type inherits from, or null if this type is Python-only.
    • isSubType

      public boolean isSubType(PyType supertype)
    • lookup

      public PyObject lookup(String name)
      Attribute lookup for name through mro objects' dicts. Lookups are cached.
      Parameters:
      name - attribute name (must be interned)
      Returns:
      found object or null
    • lookup_where

      public PyObject lookup_where(String name, PyObject[] where)
      Attribute lookup for name through mro objects' dicts. Lookups are cached. Returns where in the mro the attribute was found at where[0].
      Parameters:
      name - attribute name (must be interned)
      where - Where in the mro the attribute was found is written to index 0
      Returns:
      found object or null
    • super_lookup

      public PyObject super_lookup(PyType ref, String name)
    • addBuilder

      public static void addBuilder(Class<?> c, org.python.expose.TypeBuilder builder)
      Register the TypeBuilder for the given class. This only really makes sense for a PyObject. Initialising a properly-formed PyObject will usually result in a call to addBuilder, thanks to code inserted by the Jython type-exposer.
      Parameters:
      c - class for which this is the builder
      builder - to register
    • ensureBootstrapped

      public static boolean ensureBootstrapped()
      Attempt to ensure that the that the type system has fully constructed the types necessary to build a fully-working, exposed, PyObject (the "bootstrap types"). Produce a warning message if it does not seem to have worked. This is called at the end of the static initialisation of PyObject.
      Returns:
      whether bootstrapping was successful
    • fromClass

      public static PyType fromClass(Class<?> c, boolean hardRef)
      Equivalent to fromClass(Class), which is to be preferred.

      The boolean argument is ignored. Previously it controlled whether the returned PyType remained strongly-reachable through a reference the type registry would keep. The returned object is now reachable as long as the class c remains loaded.

      Parameters:
      c - for which the corresponding PyType is to be found
      hardRef - ignored
      Returns:
      the PyType found or created
    • fromClass

      public static PyType fromClass(Class<?> c)
      Look up (create if necessary) the PyType for the given target Java class. If the target's PyType already exists, this is returned quickly. When a PyType must be created, the method updates the registry of type information internal to Jython, caching the answer for next time.

      Creating the PyType also looks up or creates any PyTypes that the target depends upon, which results in re-entrant calls to fromClass for these classes and (if PyTypes are created for PyObjects) calls to addBuilder(Class, TypeBuilder).

      Look-up of existing types is non-blocking in the majority of cases.

      Parameters:
      c - for which the corresponding PyType is to be found
      Returns:
      the PyType found or created
    • __findattr_ex__

      public PyObject __findattr_ex__(String name)
      Description copied from class: PyObject
      Attribute lookup hook. If the attribute is not found, null may be returned or a Py.AttributeError can be thrown, whatever is more correct, efficient and/or convenient for the implementing class. Client code should use PyObject.__getattr__(String) or PyObject.__findattr__(String). Both methods have a clear policy for failed lookups.
      Overrides:
      __findattr_ex__ in class PyObject
      Returns:
      The looked up value. May return null if the attribute is not found
    • __setattr__

      public void __setattr__(String name, PyObject value)
      Description copied from class: PyObject
      A variant of the __setattr__ method which accepts a String as the key. This String must be interned.
      Overrides:
      __setattr__ in class PyObject
      Parameters:
      name - the name whose value will be set - must be an interned string .
      value - the value to set this name to
      See Also:
    • addMethod

      public void addMethod(PyBuiltinMethod meth)
      Adds the given method to this type's dict under its name in its descriptor. If there's an existing item in the dict, it's replaced.
    • removeMethod

      public void removeMethod(PyBuiltinMethod meth)
      Removes the given method from this type's dict or raises a KeyError.
    • __delattr__

      public void __delattr__(String name)
      Description copied from class: PyObject
      A variant of the __delattr__ method which accepts a String as the key. This String must be interned. By default, this will call __delattr__(PyString name) with the appropriate args. The only reason to override this method is for performance.
      Overrides:
      __delattr__ in class PyObject
      Parameters:
      name - the name which will be removed - must be an interned string .
      See Also:
    • __call__

      public PyObject __call__(PyObject[] args, String[] keywords)
      Description copied from class: PyObject
      The basic method to override when implementing a callable object. The first len(args)-len(keywords) members of args[] are plain arguments. The last len(keywords) arguments are the values of the keyword arguments.
      Overrides:
      __call__ in class PyObject
      Parameters:
      args - all arguments to the function (including keyword arguments).
      keywords - the keywords used for all keyword arguments.
    • fastGetName

      public String fastGetName()
    • pyGetName

      public PyObject pyGetName()
    • getName

      public String getName()
    • pySetName

      public void pySetName(PyObject name)
    • setName

      public void setName(String name)
    • pyDelName

      public void pyDelName()
    • fastGetDict

      public PyObject fastGetDict()
      Returns the actual dict underlying this type instance. Changes to Java types should go through addMethod(org.python.core.PyBuiltinMethod) and removeMethod(org.python.core.PyBuiltinMethod), or unexpected mro errors can occur.
      Overrides:
      fastGetDict in class PyObject
      Returns:
      internal object per instance dict or null
    • getDict

      public PyObject getDict()
      Description copied from class: PyObject
      xxx implements where meaningful
      Overrides:
      getDict in class PyObject
      Returns:
      internal object __dict__ or null
    • setDict

      public void setDict(PyObject newDict)
      Overrides:
      setDict in class PyObject
    • delDict

      public void delDict()
      Overrides:
      delDict in class PyObject
    • getDoc

      public PyObject getDoc()
      Equivalent of CPython's typeobject.c::type_get_doc; handles __doc__ descriptors.
    • __tojava__

      public Object __tojava__(Class<?> c)
      Description copied from class: PyObject
      Equivalent to the Jython __tojava__ method. Tries to coerce this object to an instance of the requested Java class. Returns the special object Py.NoConversion if this PyObject can not be converted to the desired Java class.
      Overrides:
      __tojava__ in class PyObject
      Parameters:
      c - the Class to convert this PyObject to.
    • getModule

      public PyObject getModule()
    • delModule

      public void delModule()
    • getAbstractmethods

      public PyObject getAbstractmethods()
    • setAbstractmethods

      public void setAbstractmethods(PyObject value)
    • getNumSlots

      public int getNumSlots()
    • toString

      public String toString()
      Overrides:
      toString in class PyObject
    • noAttributeError

      public void noAttributeError(String name)
      Raises AttributeError on type objects. The message differs from PyObject#noAttributeError, to mimic CPython behaviour.
      Overrides:
      noAttributeError in class PyObject
    • traverse

      public int traverse(Visitproc visit, Object arg)
      Description copied from interface: Traverseproc
      Traverses all directly contained PyObjects. Like in CPython, arg must be passed unmodified to visit as its second parameter. If Visitproc.visit(PyObject, Object) returns nonzero, this return value must be returned immediately by traverse. Visitproc.visit(PyObject, Object) must not be called with a null PyObject-argument.
      Specified by:
      traverse in interface Traverseproc
    • refersDirectlyTo

      public boolean refersDirectlyTo(PyObject ob) throws UnsupportedOperationException
      Description copied from interface: Traverseproc
      Optional operation. Should only be implemented if it is more efficient than calling Traverseproc.traverse(Visitproc, Object) with a visitproc that just watches out for ob. Must return false if ob is null.
      Specified by:
      refersDirectlyTo in interface Traverseproc
      Throws:
      UnsupportedOperationException