[Python-Dev] Re: [Python-checkins] python/dist/src/Lib types.py,1.26,1.27

Skip Montanaro skip@pobox.com
Thu, 23 May 2002 16:21:00 -0500


--aH8BSLKya8
Content-Type: text/plain; charset=us-ascii
Content-Description: message body text
Content-Transfer-Encoding: 7bit


    Guido> It's good that we're arguing about this now -- we should offer
    Guido> something to replace all features of the the types module in 2.3.

Attached is the start of a PEP (regarding which I welcome all inputs, even
cranky ones by people suffering without air conditioning).  I will be going
out of town tomorrow morning for the Memorial Day weekend, so if you send me
feedback be prepared to wait a few days for a reply.

Skip


--aH8BSLKya8
Content-Type: text/plain
Content-Description: skeletal types module deprecation PEP
Content-Transfer-Encoding: 7bit

PEP: NNN
Title: Deprecating the types module
Version: $Revision:$
Last-Modified: $Date:$
Author: skip@pobox.com (Skip Montanaro)
Status: Draft
Type: Standards Track
Created: 23-May-2002
Post-History: 
Python-Version: 2.3


Abstract

    This PEP describes the steps necessary to deprecate the types
    module and eventually remove it from the distribution.


Introduction

    The types module has long been available as a convenient source of
    type objects for those situations where programmers need to
    perform type-specific operations.  It has never truly been
    necessary, since whatever it does could be done by calling the
    type() builtin function with object of the desired type as an
    argument.  For many types it is certainly a convenience though.
    Some objects can only be generated from Python code by indirect
    means.  For example, traceback objects are generated as a side
    effect of raising exceptions.

    As type/class unification progresses, the justification for the
    presence of the types becomes a bit less clear.  Since many C
    types can now be subclassed, the relationship between an object
    and its type is no longer one-to-one, as this simple example
    demonstrates:

    >>> class myint(int):
    ...   pass
    ... 
    >>> myint(1)
    1
    >>> type(myint(1))
    <class '__main__.myint'>
    >>> type(myint(1)) == int
    False
    >>> isinstance(myint(1), int)
    True

    Still, the types module has been around for a long time.
    Replacing it will not be easy.  This PEP considers each of the
    objects the types module exports.


Easy Types

    The most commonly used objects exported by the types module are
    already present in builtins as constructor objects.  They are:

        Symbol in types module                 Symbol in builtins
        ----------------------                 ------------------
        ComplexType                            complex
        DictType, DictionaryType               dictionary
        FileType                               file, open
        FloatType                              float
        IntType                                int
        ListType                               list
        LongType                               long
        ObjectType                             object
        StringType                             str
        TupleType                              tuple
        TypeType                               type
        UnicodeType                            unicode

    When comparisons against those types are required, programmers can
    simply use the name present in builtins, e.g.:

        if type(o) is int:
            ...

    or

        if isinstance(o, int):
            ...

    instead of

        if type(o) is IntType:
            ...

    Testing for inclusion in a set of types is a little less
    straightforward if you are concerned about possible subclassing.
    Currently, to see if an object is a number you would write

        if type(o) in (IntType, FloatType, ComplexType):
            ...

    That would be converted to 

        if type(o) in (int, float, complex):
            ...

    or

        if (isinstance(o, int) or isinstance(o, float) or
            isinstance(o, complex)):
            ...

    The last case is decidedly cumbersome.

    In short, converting code to use the easy types would be fairly
    trivial.

Harder Types

    The types that programmers manipulate most often are the "easy"
    types -- those they create and manipulate directly.  The types
    module exposes a number of less commonly used types as well.  Some
    of them are created by calling a builtin function, while others
    are generated by the Python runtime as a side effect of another
    operation (e.g., an exception handler has access to a traceback
    object generated by the runtime).  The table below suggests how
    these symbols in the types module might be replaced:

        Symbol in types module          Suggested replacement
        ----------------------          ---------------------
        BufferType                      replace buffer builtin
                                        function with a callable type
                                        object
        BuiltinFunctionType             ???
        BuiltinMethodType               ???
        ClassType                       ???
        CodeType                        ???
        DictProxyType                   ???
        EllipsisType                    call type(Ellipsis)
        FrameType                       ???
        FunctionType, LambdaType        ???                           
        GeneratorType                   ???
        InstanceType                    ???
        MethodType, UnboundMethodType   ???
        ModuleType                      ???
        NoneType                        call type(None)
        SliceType                       replace slice builtin
                                        function with a callable type
                                        object
        TracebackType                   ???
        XRangeType                      replace xrange builtin
                                        function with a callable type
                                        object

    Most of these types are only used in fairly introspective code.
    For the most part, programmers using them can just call type()
    with an object of the desired type.  On the other hand, generating
    some of them is cumbersome.  For example, to get an object to
    assign to TracebackType, in the types module an exception is
    raised and then calls type(sys.get_exc_info()).  Similar
    machinations are necessary to get a frame object.

    Since these types reflect implementation details to a certain
    degree (are all of these available in Jython?), one possible
    destination for those marked with "???" is the sys module.
    Placing them in the builtins module seems like it would just add
    bloat to that module (the same could probably be said for placing
    them in sys though).

Miscellaneous

    With the arrival of Unicode objects, it became necessary to see if
    objects were plain strings or Unicode objects.  To make it a
    little easier to perform this check the StringTypes tuple was
    added to the types module.  Code can thus check for either string
    type using

        if type(o) in StringTypes:
            ...

    A common (abstract) base class for strings is needed.  If
    implemented, it would replace this functionality.

    Perhaps a similar approach (create an abstract number type) would
    improve the numeric test shown earlier.

    There are currently no symbols in the types module which represent
    the type of boolean or iterator objects.

References

    PEP 254 - "Making Classes Look More Like Types"

    PEP 260 - "Simplify xrange()"

    PEP 285 - "Adding a bool type"

Implementation

    xrange type in builtins - http://www.python.org/sf/559833

    others tbd.

Copyright

    This document has been placed in the public domain.



Local Variables:
mode: indented-text
indent-tabs-mode: nil
fill-column: 70
End:

--aH8BSLKya8--