Beispiel #1
0
def annotationoftype(t, bookkeeper=False):
    from pypy.rpython import extregistry

    """The most precise SomeValue instance that contains all
    objects of type t."""
    assert isinstance(t, (type, types.ClassType))
    if t is bool:
        return SomeBool()
    elif t is int:
        return SomeInteger()
    elif t is float:
        return SomeFloat()
    elif issubclass(t, str): # py.lib uses annotated str subclasses
        return SomeString()
    elif t is unicode:
        return SomeUnicodeString()
    elif t is list:
        return SomeList(MOST_GENERAL_LISTDEF)
    elif t is dict:
        return SomeDict(MOST_GENERAL_DICTDEF)
    # can't do tuple
    elif t is types.NoneType:
        return s_None
    elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy):
        entry = extregistry.lookup_type(t, bookkeeper.policy)
        return entry.compute_annotation_bk(bookkeeper)
    elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes:
        classdef = bookkeeper.getuniqueclassdef(t)
        return SomeInstance(classdef)
    else:
        o = SomeObject()
        if t != object:
            o.knowntype = t
        return o
Beispiel #2
0
def annotationoftype(t, bookkeeper=False):
    from pypy.rpython import extregistry
    """The most precise SomeValue instance that contains all
    objects of type t."""
    assert isinstance(t, (type, types.ClassType))
    if t is bool:
        return SomeBool()
    elif t is int:
        return SomeInteger()
    elif t is float:
        return SomeFloat()
    elif issubclass(t, str):  # py.lib uses annotated str subclasses
        return SomeString()
    elif t is unicode:
        return SomeUnicodeString()
    elif t is list:
        return SomeList(MOST_GENERAL_LISTDEF)
    elif t is dict:
        return SomeDict(MOST_GENERAL_DICTDEF)
    # can't do tuple
    elif t is types.NoneType:
        return s_None
    elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy):
        entry = extregistry.lookup_type(t, bookkeeper.policy)
        return entry.compute_annotation_bk(bookkeeper)
    elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes:
        classdef = bookkeeper.getuniqueclassdef(t)
        return SomeInstance(classdef)
    else:
        o = SomeObject()
        if t != object:
            o.knowntype = t
        return o
Beispiel #3
0
 def newtuple(self, items_s):
     if items_s == [Ellipsis]:
         res = SomeObject()   # hack to get a SomeObject as the *arg
         res.from_ellipsis = True
         return res
     else:
         return SomeTuple(items_s)
Beispiel #4
0
 def newtuple(self, items_s):
     if len(items_s) == 1 and items_s[0] is Ellipsis:
         res = SomeObject()  # hack to get a SomeObject as the *arg
         res.from_ellipsis = True
         return res
     else:
         return SomeTuple(items_s)
Beispiel #5
0
 def union((obj1, obj2)):
     if obj1 == obj2:
         return obj1
     else:
         result = SomeObject()
         if obj1.knowntype == obj2.knowntype and obj1.knowntype != object:
             result.knowntype = obj1.knowntype
         is_type_of1 = getattr(obj1, 'is_type_of', None)
         is_type_of2 = getattr(obj2, 'is_type_of', None)
         if obj1.is_immutable_constant() and obj2.is_immutable_constant() and obj1.const == obj2.const:
             result.const = obj1.const
             is_type_of = {}
             if is_type_of1:
                 for v in is_type_of1:
                     is_type_of[v] = True
             if is_type_of2:
                 for v in is_type_of2:
                     is_type_of[v] = True
             if is_type_of:
                 result.is_type_of = is_type_of.keys()
         else:
             if is_type_of1 and is_type_of1 == is_type_of2:
                 result.is_type_of = is_type_of1
         # try to preserve the origin of SomeObjects
         if obj1 == result:
             result = obj1
         elif obj2 == result:
             result = obj2
         unioncheck(result)
         return result
Beispiel #6
0
 def newtuple(self, items_s):
     if items_s == [Ellipsis]:
         res = SomeObject()  # hack to get a SomeObject as the *arg
         res.from_ellipsis = True
         return res
     else:
         return SomeTuple(items_s)
Beispiel #7
0
 def newtuple(self, items_s):
     if len(items_s) == 1 and items_s[0] is Ellipsis:
         res = SomeObject()   # hack to get a SomeObject as the *arg
         res.from_ellipsis = True
         return res
     else:
         return SomeTuple(items_s)
Beispiel #8
0
 def getattr(ins, s_attr):
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         attr = s_attr.const
         if attr == '__class__':
             return ins.classdef.read_attr__class__()
         attrdef = ins.classdef.find_attribute(attr)
         position = getbookkeeper().position_key
         attrdef.read_locations[position] = True
         s_result = attrdef.getvalue()
         # hack: if s_result is a set of methods, discard the ones
         #       that can't possibly apply to an instance of ins.classdef.
         # XXX do it more nicely
         if isinstance(s_result, SomePBC):
             s_result = ins.classdef.lookup_filter(s_result, attr,
                                                   ins.flags)
         elif isinstance(s_result, SomeImpossibleValue):
             ins.classdef.check_missing_attribute_update(attr)
             # blocking is harmless if the attribute is explicitly listed
             # in the class or a parent class.
             for basedef in ins.classdef.getmro():
                 if basedef.classdesc.all_enforced_attrs is not None:
                     if attr in basedef.classdesc.all_enforced_attrs:
                         raise HarmlesslyBlocked("get enforced attr")
         elif isinstance(s_result, SomeList):
             s_result = ins.classdef.classdesc.maybe_return_immutable_list(
                 attr, s_result)
         return s_result
     return SomeObject()
Beispiel #9
0
 def len(pbc):
     if pbc.isNone():
         # this None could later be generalized into an empty list,
         # whose length is the constant 0; so let's tentatively answer 0.
         return immutablevalue(0)
     else:
         return SomeObject()  # len() on a pbc? no chance
Beispiel #10
0
 def len(dct):
     s_key = dct.dictdef.read_key()
     s_value = dct.dictdef.read_value()
     if isinstance(s_key, SomeImpossibleValue) or isinstance(
             s_value, SomeImpossibleValue):
         return immutablevalue(0)
     return SomeObject.len(dct)
Beispiel #11
0
 def find_method(obj, name):
     "Look for a special-case implementation for the named method."
     type_analyser = builtin.EXTERNAL_TYPE_ANALYZERS[obj.knowntype]
     if name in type_analyser:
         analyser = type_analyser[name]
         return SomeBuiltin(analyser, obj, name)
     return SomeObject.find_method(obj, name)
Beispiel #12
0
 def getattr(p, s_attr):
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         attr = s_attr.const
         entry = extregistry.lookup_type(p.knowntype)
         s_value = entry.get_field_annotation(p.knowntype, attr)
         return s_value
     else:
         return SomeObject()
Beispiel #13
0
 def simple_call(self, *s_args):
     from pypy.translator.cli.query import get_cli_class
     DELEGATE = get_cli_class('System.Delegate')._INSTANCE
     if ootype.isSubclass(self.ootype, DELEGATE):
         s_invoke = self.getattr(immutablevalue('Invoke'))
         return s_invoke.simple_call(*s_args)
     else:
         # cannot call a non-delegate
         return SomeObject.simple_call(self, *s_args)
Beispiel #14
0
 def simple_call(self, *s_args):
     from pypy.translator.cli.query import get_cli_class
     DELEGATE = get_cli_class('System.Delegate')._INSTANCE
     if ootype.isSubclass(self.ootype, DELEGATE):
         s_invoke = self.getattr(immutablevalue('Invoke'))
         return s_invoke.simple_call(*s_args)
     else:
         # cannot call a non-delegate
         return SomeObject.simple_call(self, *s_args)
Beispiel #15
0
 def compute_result_annotation(self, s_obj):
     if s_None.contains(s_obj):
         return s_obj
     assert isinstance(s_obj, (SomeString, SomeUnicodeString))
     if s_obj.no_nul:
         return s_obj
     new_s_obj = SomeObject.__new__(s_obj.__class__)
     new_s_obj.__dict__ = s_obj.__dict__.copy()
     new_s_obj.no_nul = True
     return new_s_obj
Beispiel #16
0
 def union((s_wrf1, s_wrf2)):
     if s_wrf1.classdef is None:
         basedef = s_wrf2.classdef  # s_wrf1 is known to be dead
     elif s_wrf2.classdef is None:
         basedef = s_wrf1.classdef  # s_wrf2 is known to be dead
     else:
         basedef = s_wrf1.classdef.commonbase(s_wrf2.classdef)
         if basedef is None:  # no common base class! complain...
             return SomeObject()
     return SomeWeakRef(basedef)
Beispiel #17
0
 def compute_result_annotation(self, s_obj):
     if s_None.contains(s_obj):
         return s_obj
     assert isinstance(s_obj, (SomeString, SomeUnicodeString))
     if s_obj.no_nul:
         return s_obj
     new_s_obj = SomeObject.__new__(s_obj.__class__)
     new_s_obj.__dict__ = s_obj.__dict__.copy()
     new_s_obj.no_nul = True
     return new_s_obj
Beispiel #18
0
 def getattr(p, s_attr):
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         # XXX kill with extfunctable.py
         if p.knowntype in builtin.EXTERNAL_TYPE_ANALYZERS:
             return SomeObject.getattr(p, s_attr)
         
         attr = s_attr.const
         entry = extregistry.lookup_type(p.knowntype)
         s_value = entry.get_field_annotation(p.knowntype, attr)
         return s_value
     else:
         return SomeObject()
Beispiel #19
0
 def union((ext1, ext2)):
     def commonsuperclass(cls1, cls2):
         cls = cls2
         while not issubclass(cls1, cls):
             cls = cls.__bases__[0]
         return cls
     
     from pypy.rpython.ootypesystem.bltregistry import BasicExternal
     cls = commonsuperclass(ext1.knowntype, ext2.knowntype)
     if cls is BasicExternal:
         return SomeObject()
     return SomeExternalInstance(cls)
Beispiel #20
0
 def union((obj1, obj2)):
     if obj1 == obj2:
         return obj1
     else:
         result = SomeObject()
         if obj1.knowntype == obj2.knowntype and obj1.knowntype != object:
             result.knowntype = obj1.knowntype
         is_type_of1 = getattr(obj1, 'is_type_of', None)
         is_type_of2 = getattr(obj2, 'is_type_of', None)
         if obj1.is_immutable_constant() and obj2.is_immutable_constant(
         ) and obj1.const == obj2.const:
             result.const = obj1.const
             is_type_of = {}
             if is_type_of1:
                 for v in is_type_of1:
                     is_type_of[v] = True
             if is_type_of2:
                 for v in is_type_of2:
                     is_type_of[v] = True
             if is_type_of:
                 result.is_type_of = is_type_of.keys()
         else:
             if is_type_of1 and is_type_of1 == is_type_of2:
                 result.is_type_of = is_type_of1
         # try to preserve the origin of SomeObjects
         if obj1 == result:
             result = obj1
         elif obj2 == result:
             result = obj2
         unioncheck(result)
         return result
Beispiel #21
0
 def getattr(s_array, s_attr):
     s = None
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         attr = s_attr.const
         if attr == 'shape':
             s = SomeTuple([SomeInteger()]*s_array.ndim)
         elif attr == 'ndim':
             s = SomeInteger()
         elif attr == 'dtype':
             s = SomeChar()
     if s is None:
         return SomeObject.getattr(s_array, s_attr)
     return s
Beispiel #22
0
 def getattr(s_array, s_attr):
     s = None
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         attr = s_attr.const
         if attr == 'shape':
             s = SomeTuple([SomeInteger()] * s_array.ndim)
         elif attr == 'ndim':
             s = SomeInteger()
         elif attr == 'dtype':
             s = SomeChar()
     if s is None:
         return SomeObject.getattr(s_array, s_attr)
     return s
Beispiel #23
0
 def getattr(obj, s_attr):
     # get a SomeBuiltin if the SomeObject has
     # a corresponding method to handle it
     if s_attr.is_constant() and isinstance(s_attr.const, str):
         attr = s_attr.const
         s_method = obj.find_method(attr)
         if s_method is not None:
             return s_method
         # if the SomeObject is itself a constant, allow reading its attrs
         if obj.is_immutable_constant() and hasattr(obj.const, attr):
             return immutablevalue(getattr(obj.const, attr))
     else:
         getbookkeeper().warning('getattr(%r, %r) is not RPythonic enough' %
                                 (obj, s_attr))
     return SomeObject()
Beispiel #24
0
 def union((ins1, ins2)):
     if ins1.classdef is None or ins2.classdef is None:
         # special case only
         basedef = None
     else:
         basedef = ins1.classdef.commonbase(ins2.classdef)
         if basedef is None:
             # print warning?
             return SomeObject()
     flags = ins1.flags
     if flags:
         flags = flags.copy()
         for key, value in flags.items():
             if key not in ins2.flags or ins2.flags[key] != value:
                 del flags[key]
     return SomeInstance(basedef,
                         can_be_None=ins1.can_be_None or ins2.can_be_None,
                         flags=flags)
Beispiel #25
0
 def type(obj, *moreargs):
     if moreargs:
         raise Exception, 'type() called with more than one argument'
     if obj.is_constant():
         if isinstance(obj, SomeInstance):
             r = SomePBC([obj.classdef.classdesc])
         else:
             r = immutablevalue(obj.knowntype)
     else:
         r = SomeObject()
         r.knowntype = type
     bk = getbookkeeper()
     fn, block, i = bk.position_key
     annotator = bk.annotator
     op = block.operations[i]
     assert op.opname == "type"
     assert len(op.args) == 1
     assert annotator.binding(op.args[0]) == obj
     r.is_type_of = [op.args[0]]
     return r
Beispiel #26
0
 def len(lst):
     s_item = lst.listdef.read_item()
     if isinstance(s_item, SomeImpossibleValue):
         return immutablevalue(0)
     return SomeObject.len(lst)
Beispiel #27
0
 def immutablevalue(self, x, need_const=True):
     """The most precise SomeValue instance that contains the
     immutable value x."""
     # convert unbound methods to the underlying function
     if hasattr(x, 'im_self') and x.im_self is None:
         x = x.im_func
         assert not hasattr(x, 'im_self')
     if x is sys:  # special case constant sys to someobject
         return SomeObject()
     tp = type(x)
     if issubclass(tp, Symbolic):  # symbolic constants support
         result = x.annotation()
         result.const_box = Constant(x)
         return result
     if tp is bool:
         result = SomeBool()
     elif tp is int:
         result = SomeInteger(nonneg=x >= 0)
     elif tp is long:
         if -sys.maxint - 1 <= x <= sys.maxint:
             x = int(x)
             result = SomeInteger(nonneg=x >= 0)
         else:
             raise Exception("seeing a prebuilt long (value %s)" % hex(x))
     elif issubclass(tp, str):  # py.lib uses annotated str subclasses
         if len(x) == 1:
             result = SomeChar()
         else:
             result = SomeString()
     elif tp is unicode:
         if len(x) == 1:
             result = SomeUnicodeCodePoint()
         else:
             result = SomeUnicodeString()
     elif tp is tuple:
         result = SomeTuple(
             items=[self.immutablevalue(e, need_const) for e in x])
     elif tp is float:
         result = SomeFloat()
     elif tp is list:
         if need_const:
             key = Constant(x)
             try:
                 return self.immutable_cache[key]
             except KeyError:
                 result = SomeList(ListDef(self, s_ImpossibleValue))
                 self.immutable_cache[key] = result
                 for e in x:
                     result.listdef.generalize(self.immutablevalue(e))
                 result.const_box = key
                 return result
         else:
             listdef = ListDef(self, s_ImpossibleValue)
             for e in x:
                 listdef.generalize(self.immutablevalue(e, False))
             result = SomeList(listdef)
     elif tp is dict or tp is r_dict:
         if need_const:
             key = Constant(x)
             try:
                 return self.immutable_cache[key]
             except KeyError:
                 result = SomeDict(
                     DictDef(self,
                             s_ImpossibleValue,
                             s_ImpossibleValue,
                             is_r_dict=tp is r_dict))
                 self.immutable_cache[key] = result
                 if tp is r_dict:
                     s_eqfn = self.immutablevalue(x.key_eq)
                     s_hashfn = self.immutablevalue(x.key_hash)
                     result.dictdef.dictkey.update_rdict_annotations(
                         s_eqfn, s_hashfn)
                 seen_elements = 0
                 while seen_elements != len(x):
                     items = x.items()
                     for ek, ev in items:
                         result.dictdef.generalize_key(
                             self.immutablevalue(ek))
                         result.dictdef.generalize_value(
                             self.immutablevalue(ev))
                         result.dictdef.seen_prebuilt_key(ek)
                     seen_elements = len(items)
                     # if the dictionary grew during the iteration,
                     # start over again
                 result.const_box = key
                 return result
         else:
             dictdef = DictDef(self,
                               s_ImpossibleValue,
                               s_ImpossibleValue,
                               is_r_dict=tp is r_dict)
             if tp is r_dict:
                 s_eqfn = self.immutablevalue(x.key_eq)
                 s_hashfn = self.immutablevalue(x.key_hash)
                 dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
             for ek, ev in x.iteritems():
                 dictdef.generalize_key(self.immutablevalue(ek, False))
                 dictdef.generalize_value(self.immutablevalue(ev, False))
                 dictdef.seen_prebuilt_key(ek)
             result = SomeDict(dictdef)
     elif tp is weakref.ReferenceType:
         x1 = x()
         if x1 is None:
             result = SomeWeakRef(None)  # dead weakref
         else:
             s1 = self.immutablevalue(x1)
             assert isinstance(s1, SomeInstance)
             result = SomeWeakRef(s1.classdef)
     elif ishashable(x) and x in BUILTIN_ANALYZERS:
         _module = getattr(x, "__module__", "unknown")
         result = SomeBuiltin(BUILTIN_ANALYZERS[x],
                              methodname="%s.%s" % (_module, x.__name__))
     elif extregistry.is_registered(x, self.policy):
         entry = extregistry.lookup(x, self.policy)
         result = entry.compute_annotation_bk(self)
     elif isinstance(x, lltype._ptr):
         result = SomePtr(lltype.typeOf(x))
     elif isinstance(x, llmemory.fakeaddress):
         result = SomeAddress()
     elif isinstance(x, ootype._static_meth):
         result = SomeOOStaticMeth(ootype.typeOf(x))
     elif isinstance(x, ootype._class):
         result = SomeOOClass(x._INSTANCE)  # NB. can be None
     elif isinstance(x, ootype.instance_impl):  # XXX
         result = SomeOOInstance(ootype.typeOf(x))
     elif isinstance(x, (ootype._record, ootype._string)):
         result = SomeOOInstance(ootype.typeOf(x))
     elif isinstance(x, (ootype._object)):
         result = SomeOOObject()
     elif callable(x):
         if hasattr(x, 'im_self') and hasattr(x, 'im_func'):
             # on top of PyPy, for cases like 'l.append' where 'l' is a
             # global constant list, the find_method() returns non-None
             s_self = self.immutablevalue(x.im_self, need_const)
             result = s_self.find_method(x.im_func.__name__)
         elif hasattr(x, '__self__') and x.__self__ is not None:
             # for cases like 'l.append' where 'l' is a global constant list
             s_self = self.immutablevalue(x.__self__, need_const)
             result = s_self.find_method(x.__name__)
             if result is None:
                 result = SomeObject()
         else:
             result = None
         if result is None:
             if (self.annotator.policy.allow_someobjects
                     and getattr(x, '__module__', None) == '__builtin__'
                     # XXX note that the print support functions are __builtin__
                     and tp not in (types.FunctionType, types.MethodType)):
                 result = SomeObject()
                 result.knowntype = tp  # at least for types this needs to be correct
             else:
                 result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '_freeze_') and x._freeze_():
         # user-defined classes can define a method _freeze_(), which
         # is called when a prebuilt instance is found.  If the method
         # returns True, the instance is considered immutable and becomes
         # a SomePBC().  Otherwise it's just SomeInstance().
         result = SomePBC([self.getdesc(x)])
     elif hasattr(x, '__class__') \
              and x.__class__.__module__ != '__builtin__':
         self.see_mutable(x)
         result = SomeInstance(self.getuniqueclassdef(x.__class__))
     elif x is None:
         return s_None
     else:
         result = SomeObject()
     if need_const:
         result.const = x
     return result
Beispiel #28
0
def import_func(*args):
    return SomeObject()
Beispiel #29
0
def builtin_tuple(s_iterable):
    if isinstance(s_iterable, SomeTuple):
        return s_iterable
    return SomeObject()
Beispiel #30
0
 def long(obj):
     return SomeObject()  # XXX
Beispiel #31
0
 def union((ext1, ext2)):
     if ext1.knowntype == ext2.knowntype:
         return SomeExternalObject(ext1.knowntype)
     return SomeObject()
Beispiel #32
0
 def len(p):
     length = p.ll_ptrtype._example()._fixedlength()
     if length is None:
         return SomeObject.len(p)
     else:
         return immutablevalue(length)
Beispiel #33
0
 def len(p):
     length = p.ll_ptrtype._example()._fixedlength()
     if length is None:
         return SomeObject.len(p)
     else:
         return immutablevalue(length)
Beispiel #34
0
 def call(obj, args, implicit_init=False):
     #raise Exception, "cannot follow call_args%r" % ((obj, args),)
     getbookkeeper().warning("cannot follow call(%r, %r)" % (obj, args))
     return SomeObject()
Beispiel #35
0
 def len(dct):
     s_key = dct.dictdef.read_key()
     s_value = dct.dictdef.read_value()
     if isinstance(s_key, SomeImpossibleValue) or isinstance(s_value, SomeImpossibleValue):
         return immutablevalue(0)
     return SomeObject.len(dct)
Beispiel #36
0
 def len(lst):
     s_item = lst.listdef.read_item()
     if isinstance(s_item, SomeImpossibleValue):
         return immutablevalue(0)
     return SomeObject.len(lst)
Beispiel #37
0
def builtin_apply(*stuff):
    getbookkeeper().warning("ignoring apply%r" % (stuff,))
    return SomeObject()
Beispiel #38
0
 def len(dct):
     if dct._is_empty():
         return immutablevalue(0)
     return SomeObject.len(dct)
Beispiel #39
0
                position_key = getbookkeeper().position_key
            else:
                position_key = self.bookkeeper.position_key
        self.dictvalue.read_locations[position_key] = True
        return self.dictvalue.s_value

    def same_as(self, other):
        return (self.dictkey is other.dictkey
                and self.dictvalue is other.dictvalue)

    def union(self, other):
        if (self.same_as(MOST_GENERAL_DICTDEF)
                or other.same_as(MOST_GENERAL_DICTDEF)):
            return MOST_GENERAL_DICTDEF  # without merging
        else:
            self.dictkey.merge(other.dictkey)
            self.dictvalue.merge(other.dictvalue)
            return self

    def generalize_key(self, s_key):
        self.dictkey.generalize(s_key)

    def generalize_value(self, s_value):
        self.dictvalue.generalize(s_value)

    def __repr__(self):
        return '<{%r: %r}>' % (self.dictkey.s_value, self.dictvalue.s_value)


MOST_GENERAL_DICTDEF = DictDef(None, SomeObject(), SomeObject())
Beispiel #40
0
 def union((tup1, tup2)):
     if len(tup1.items) != len(tup2.items):
         return SomeObject()
     else:
         unions = [unioncheck(x, y) for x, y in zip(tup1.items, tup2.items)]
         return SomeTuple(items=unions)
Beispiel #41
0
 def len(dct):
     if dct._is_empty():
         return immutablevalue(0)
     return SomeObject.len(dct)
Beispiel #42
0
                               self.listitem.immutable and 'I' or '',
                               self.listitem.must_not_resize and '!R' or '')

    def mutate(self):
        self.listitem.mutate()

    def resize(self):
        self.listitem.mutate()
        self.listitem.resize()

    def never_resize(self):
        if self.listitem.resized:
            raise ListChangeUnallowed("list already resized")
        self.listitem.must_not_resize = True

    def mark_as_immutable(self):
        # Sets the 'immutable' flag.  Note that unlike "never resized",
        # the immutable flag is only a hint.  It is cleared again e.g.
        # when we merge with a "normal" list that doesn't have it.  It
        # is thus expected to live only shortly, mostly for the case
        # of writing 'x.list[n]'.
        self.never_resize()
        if not self.listitem.mutated:
            self.listitem.immutable = True
        #else: it's fine, don't set immutable=True at all (see
        #      test_can_merge_immutable_list_with_regular_list)

MOST_GENERAL_LISTDEF = ListDef(None, SomeObject())

s_list_of_strings = SomeList(ListDef(None, SomeString(), resized = True))