baseobjspace.py 74.9 KB
Newer Older
1
2
import sys

3
4
5
6
7
from rpython.rlib.cache import Cache
from rpython.tool.uid import HUGEVAL_BYTES
from rpython.rlib import jit, types
from rpython.rlib.debug import make_sure_not_resized
from rpython.rlib.objectmodel import (we_are_translated, newlist_hint,
8
     compute_unique_id, specialize)
9
from rpython.rlib.signature import signature
10
from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \
11
    INT_MIN, INT_MAX, UINT_MAX, USHRT_MAX
12

13
from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag,
Armin Rigo's avatar
Armin Rigo committed
14
    make_finalizer_queue)
15
from pypy.interpreter.error import OperationError, new_exception_class, oefmt
16
from pypy.interpreter.argument import Arguments
17
from pypy.interpreter.miscutils import ThreadLocals, make_weak_value_dictionary
18

19

20
__all__ = ['ObjSpace', 'OperationError', 'W_Root']
21

22
23
24
25
unpackiterable_driver = jit.JitDriver(name='unpackiterable',
                                      greens=['tp'],
                                      reds=['items', 'w_iterator'])

26

27
class W_Root(object):
28
29
    """This is the abstract root class of all wrapped objects that live
    in a 'normal' object space like StdObjSpace."""
30
    __slots__ = ('__weakref__',)
Armin Rigo's avatar
Armin Rigo committed
31
    _must_be_light_finalizer_ = True
32
    user_overridden_class = False
33

34
    def getdict(self, space):
35
        return None
36

37
    def getdictvalue(self, space, attr):
38
        w_dict = self.getdict(space)
39
        if w_dict is not None:
40
            return space.finditem_str(w_dict, attr)
41
        return None
42

Armin Rigo's avatar
Armin Rigo committed
43
    def setdictvalue(self, space, attr, w_value):
44
        w_dict = self.getdict(space)
Samuele Pedroni's avatar
Samuele Pedroni committed
45
        if w_dict is not None:
Armin Rigo's avatar
Armin Rigo committed
46
            space.setitem_str(w_dict, attr, w_value)
Samuele Pedroni's avatar
Samuele Pedroni committed
47
48
            return True
        return False
Justas Sadzevicius's avatar
Justas Sadzevicius committed
49

50
    def deldictvalue(self, space, attr):
51
        w_dict = self.getdict(space)
Samuele Pedroni's avatar
Samuele Pedroni committed
52
53
        if w_dict is not None:
            try:
54
                space.delitem(w_dict, space.wrap(attr))
Samuele Pedroni's avatar
Samuele Pedroni committed
55
                return True
56
            except OperationError as ex:
Samuele Pedroni's avatar
Samuele Pedroni committed
57
58
59
60
                if not ex.match(space, space.w_KeyError):
                    raise
        return False

61
    def setdict(self, space, w_dict):
62
63
64
        raise oefmt(space.w_TypeError,
                     "attribute '__dict__' of %T objects is not writable",
                     self)
65

66
    # to be used directly only by space.type implementations
67
68
69
    def getclass(self, space):
        return space.gettypeobject(self.typedef)

70
    def setclass(self, space, w_subtype):
Philip Jenvey's avatar
Philip Jenvey committed
71
72
        raise oefmt(space.w_TypeError,
                    "__class__ assignment: only for heap types")
73

74
    def user_setup(self, space, w_subtype):
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
75
76
        raise NotImplementedError("only for interp-level user subclasses "
                                  "from typedef.py")
77

78
    def getname(self, space):
79
80
        try:
            return space.str_w(space.getattr(self, space.wrap('__name__')))
81
        except OperationError as e:
82
            if e.match(space, space.w_TypeError) or e.match(space, space.w_AttributeError):
83
                return '?'
84
            raise
85

86
    def getaddrstring(self, space):
87
        # slowish
88
89
90
91
92
93
        w_id = space.id(self)
        w_4 = space.wrap(4)
        w_0x0F = space.wrap(0x0F)
        i = 2 * HUGEVAL_BYTES
        addrstring = [' '] * i
        while True:
94
            n = space.int_w(space.and_(w_id, w_0x0F), allow_conversion=False)
95
96
97
98
99
100
101
102
            n += ord('0')
            if n > ord('9'):
                n += (ord('a') - ord('9') - 1)
            i -= 1
            addrstring[i] = chr(n)
            if i == 0:
                break
            w_id = space.rshift(w_id, w_4)
103
104
105
106
107
        return ''.join(addrstring)

    def getrepr(self, space, info, moreinfo=''):
        addrstring = self.getaddrstring(space)
        return space.wrap("<%s at 0x%s%s>" % (info, addrstring,
108
                                              moreinfo))
109

110
111
112
113
114
115
    def getslotvalue(self, index):
        raise NotImplementedError

    def setslotvalue(self, index, w_val):
        raise NotImplementedError

116
117
118
    def delslotvalue(self, index):
        raise NotImplementedError

Samuele Pedroni's avatar
Samuele Pedroni committed
119
    def descr_call_mismatch(self, space, opname, RequiredClass, args):
Armin Rigo's avatar
Armin Rigo committed
120
121
122
123
        if RequiredClass is None:
            classname = '?'
        else:
            classname = wrappable_class_name(RequiredClass)
124
125
        raise oefmt(space.w_TypeError,
                    "'%s' object expected, got '%T' instead", classname, self)
Samuele Pedroni's avatar
Samuele Pedroni committed
126

127
128
129
130
131
132
    # used by _weakref implemenation

    def getweakref(self):
        return None

    def setweakref(self, space, weakreflifeline):
133
134
        raise oefmt(space.w_TypeError,
                    "cannot create weak reference to '%T' object", self)
135

136
137
138
    def delweakref(self):
        pass

139
    def clear_all_weakrefs(self):
Armin Rigo's avatar
Armin Rigo committed
140
141
        """Ensures that weakrefs (if any) are cleared now.  This is
        called by UserDelAction before the object is finalized further.
142
143
144
145
146
147
148
149
150
        """
        lifeline = self.getweakref()
        if lifeline is not None:
            # Clear all weakrefs to this object before we proceed with
            # the destruction of the object.  We detach the lifeline
            # first: if the code following before_del() calls the
            # app-level, e.g. a user-defined __del__(), and this code
            # tries to use weakrefs again, it won't reuse the broken
            # (already-cleared) weakrefs from this lifeline.
151
            self.delweakref()
152
153
            lifeline.clear_all_weakrefs()

Armin Rigo's avatar
Armin Rigo committed
154
    def _finalize_(self):
Armin Rigo's avatar
Armin Rigo committed
155
        """The RPython-level finalizer.
156

Armin Rigo's avatar
Armin Rigo committed
157
158
        By default, it is *not called*.  See self.register_finalizer().
        Be ready to handle the case where the object is only half
Armin Rigo's avatar
Careful    
Armin Rigo committed
159
160
161
        initialized.  Also, in some cases the object might still be
        visible to app-level after _finalize_() is called (e.g. if
        there is a __del__ that resurrects).
Armin Rigo's avatar
Armin Rigo committed
162
        """
163

Armin Rigo's avatar
Armin Rigo committed
164
165
166
167
168
169
170
171
172
173
174
    def register_finalizer(self, space):
        """Register a finalizer for this object, so that
        self._finalize_() will be called.  You must call this method at
        most once.  Be ready to handle in _finalize_() the case where
        the object is half-initialized, even if you only call
        self.register_finalizer() at the end of the initialization.
        This is because there are cases where the finalizer is already
        registered before: if the user makes an app-level subclass with
        a __del__.  (In that case only, self.register_finalizer() does
        nothing, because the finalizer is already registered in
        allocate_instance().)
175
        """
Armin Rigo's avatar
Armin Rigo committed
176
177
178
179
180
181
182
183
184
        if self.user_overridden_class and self.getclass(space).hasuserdel:
            # already registered by space.allocate_instance()
            if not we_are_translated():
                assert space.finalizer_queue._already_registered(self)
        else:
            if not we_are_translated():
                # does not make sense if _finalize_ is not overridden
                assert self._finalize_.im_func is not W_Root._finalize_.im_func
            space.finalizer_queue.register_finalizer(self)
185

186
187
188
189
190
191
192
193
194
195
196
197
198
199
    # hooks that the mapdict implementations needs:
    def _get_mapdict_map(self):
        return None
    def _set_mapdict_map(self, map):
        raise NotImplementedError
    def _mapdict_read_storage(self, index):
        raise NotImplementedError
    def _mapdict_write_storage(self, index, value):
        raise NotImplementedError
    def _mapdict_storage_length(self):
        raise NotImplementedError
    def _set_mapdict_storage_and_map(self, storage, map):
        raise NotImplementedError

200
201
    # -------------------------------------------------------------------

Armin Rigo's avatar
Armin Rigo committed
202
203
204
    def is_w(self, space, w_other):
        return self is w_other

Armin Rigo's avatar
Armin Rigo committed
205
206
    def immutable_unique_id(self, space):
        return None
Armin Rigo's avatar
Armin Rigo committed
207

208
    def buffer_w(self, space, flags):
209
210
        w_impl = space.lookup(self, '__buffer__')
        if w_impl is not None:
Matti Picus's avatar
Matti Picus committed
211
212
            w_result = space.get_and_call_function(w_impl, self, 
                                        space.newint(flags))
213
            if space.isinstance_w(w_result, space.w_buffer):
214
                return w_result.buffer_w(space, flags)
Armin Rigo's avatar
Armin Rigo committed
215
        raise BufferInterfaceNotFound
216
217
218
219

    def readbuf_w(self, space):
        w_impl = space.lookup(self, '__buffer__')
        if w_impl is not None:
220
            w_result = space.get_and_call_function(w_impl, self,
Matti Picus's avatar
Matti Picus committed
221
                                        space.newint(space.BUF_FULL_RO))
222
223
            if space.isinstance_w(w_result, space.w_buffer):
                return w_result.readbuf_w(space)
Armin Rigo's avatar
Armin Rigo committed
224
        raise BufferInterfaceNotFound
225
226
227
228

    def writebuf_w(self, space):
        w_impl = space.lookup(self, '__buffer__')
        if w_impl is not None:
229
            w_result = space.get_and_call_function(w_impl, self,
Matti Picus's avatar
Matti Picus committed
230
                                        space.newint(space.BUF_FULL))
231
232
            if space.isinstance_w(w_result, space.w_buffer):
                return w_result.writebuf_w(space)
Armin Rigo's avatar
Armin Rigo committed
233
        raise BufferInterfaceNotFound
234
235
236
237

    def charbuf_w(self, space):
        w_impl = space.lookup(self, '__buffer__')
        if w_impl is not None:
238
            w_result = space.get_and_call_function(w_impl, self,
Matti Picus's avatar
Matti Picus committed
239
                                        space.newint(space.BUF_FULL_RO))
240
241
            if space.isinstance_w(w_result, space.w_buffer):
                return w_result.charbuf_w(space)
Armin Rigo's avatar
Armin Rigo committed
242
        raise BufferInterfaceNotFound
243

244
    def str_w(self, space):
Philip Jenvey's avatar
cleanup    
Philip Jenvey committed
245
        self._typed_unwrap_error(space, "string")
246

Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
247
    def unicode_w(self, space):
Philip Jenvey's avatar
cleanup    
Philip Jenvey committed
248
        self._typed_unwrap_error(space, "unicode")
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
249

Armin Rigo's avatar
Armin Rigo committed
250
251
252
    def bytearray_list_of_chars_w(self, space):
        self._typed_unwrap_error(space, "bytearray")

253
254
    def int_w(self, space, allow_conversion=True):
        # note that W_IntObject.int_w has a fast path and W_FloatObject.int_w
255
        # raises w_TypeError
256
257
258
259
260
261
        w_obj = self
        if allow_conversion:
            w_obj = space.int(self)
        return w_obj._int_w(space)

    def _int_w(self, space):
Philip Jenvey's avatar
cleanup    
Philip Jenvey committed
262
        self._typed_unwrap_error(space, "integer")
263

264
265
266
267
268
269
270
    def float_w(self, space, allow_conversion=True):
        w_obj = self
        if allow_conversion:
            w_obj = space.float(self)
        return w_obj._float_w(space)

    def _float_w(self, space):
Philip Jenvey's avatar
cleanup    
Philip Jenvey committed
271
        self._typed_unwrap_error(space, "float")
272

273
    def uint_w(self, space):
Philip Jenvey's avatar
cleanup    
Philip Jenvey committed
274
        self._typed_unwrap_error(space, "integer")
275

276
277
278
279
280
281
282
283
284
    def bigint_w(self, space, allow_conversion=True):
        # note that W_IntObject and W_LongObject have fast paths,
        # W_FloatObject.rbigint_w raises w_TypeError raises
        w_obj = self
        if allow_conversion:
            w_obj = space.long(self)
        return w_obj._bigint_w(space)

    def _bigint_w(self, space):
Philip Jenvey's avatar
cleanup    
Philip Jenvey committed
285
286
287
        self._typed_unwrap_error(space, "integer")

    def _typed_unwrap_error(self, space, expected):
288
289
        raise oefmt(space.w_TypeError,
                    "expected %s, got %T object", expected, self)
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
290

291
292
293
    def int(self, space):
        w_impl = space.lookup(self, '__int__')
        if w_impl is None:
294
            self._typed_unwrap_error(space, "integer")
295
296
297
298
299
        w_result = space.get_and_call_function(w_impl, self)

        if (space.isinstance_w(w_result, space.w_int) or
            space.isinstance_w(w_result, space.w_long)):
            return w_result
300
301
        raise oefmt(space.w_TypeError,
                    "__int__ returned non-int (type '%T')", w_result)
302

303
    def ord(self, space):
304
305
        raise oefmt(space.w_TypeError,
                    "ord() expected string of length 1, but %T found", self)
306

307
308
309
    def __spacebind__(self, space):
        return self

310
311
312
313
314
    def unwrap(self, space):
        """NOT_RPYTHON"""
        # _____ this code is here to support testing only _____
        return self

315
316
317
318
319
320
321
322
323
324
325
326
    def unpackiterable_int(self, space):
        lst = space.listview_int(self)
        if lst:
            return lst[:]
        return None

    def unpackiterable_float(self, space):
        lst = space.listview_float(self)
        if lst:
            return lst[:]
        return None

Armin Rigo's avatar
Armin Rigo committed
327

328
class InterpIterable(object):
329
330
331
332
333
334
335
336
337
338
339
    def __init__(self, space, w_iterable):
        self.w_iter = space.iter(w_iterable)
        self.space = space

    def __iter__(self):
        return self

    def next(self):
        space = self.space
        try:
            return space.next(self.w_iter)
340
        except OperationError as e:
341
342
343
344
            if not e.match(space, space.w_StopIteration):
                raise
            raise StopIteration

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
class InternalSpaceCache(Cache):
    """A generic cache for an object space.  Arbitrary information can
    be attached to the space by defining a function or class 'f' which
    can be called as 'f(space)'.  Its result is stored in this
    ObjSpaceCache.
    """
    def __init__(self, space):
        Cache.__init__(self)
        self.space = space
    def _build(self, callable):
        return callable(self.space)

class SpaceCache(Cache):
    """A base class for all our concrete caches."""
    def __init__(self, space):
        Cache.__init__(self)
        self.space = space
362

363
    def _build(self, key):
364
365
        return self.build(key)

Michael Hudson's avatar
Michael Hudson committed
366
    def _ready(self, result):
367
368
        return self.ready(result)

Michael Hudson's avatar
Michael Hudson committed
369
370
    def ready(self, result):
        pass
Justas Sadzevicius's avatar
Justas Sadzevicius committed
371

Samuele Pedroni's avatar
Samuele Pedroni committed
372
373
374
class DescrMismatch(Exception):
    pass

Armin Rigo's avatar
Armin Rigo committed
375
376
377
class BufferInterfaceNotFound(Exception):
    pass

Armin Rigo's avatar
Armin Rigo committed
378
379
380
381
382
383
384
def wrappable_class_name(Class):
    try:
        return Class.typedef.name
    except AttributeError:
        return 'internal subclass of %s' % (Class.__name__,)
wrappable_class_name._annspecialcase_ = 'specialize:memo'

385
386
387
class CannotHaveLock(Exception):
    """Raised by space.allocate_lock() if we're translating."""

Armin Rigo's avatar
Armin Rigo committed
388
389
# ____________________________________________________________

390
391
class ObjSpace(object):
    """Base class for the interpreter-level implementations of object spaces.
392
    http://pypy.readthedocs.org/en/latest/objspace.html"""
Justas Sadzevicius's avatar
Justas Sadzevicius committed
393

394
    def __init__(self, config=None):
395
        "NOT_RPYTHON: Basic initialization of objects."
396
        self.fromcache = InternalSpaceCache(self).getorbuild
397
        self.threadlocals = ThreadLocals()
Samuele Pedroni's avatar
Samuele Pedroni committed
398
        # set recursion limit
399
        # sets all the internal descriptors
400
        if config is None:
401
402
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=False)
403
        self.config = config
404

405
406
407
        self.builtin_modules = {}
        self.reloading_modules = {}

408
        self.interned_strings = make_weak_value_dictionary(self, str, W_Root)
409
        self.actionflag = ActionFlag()    # changed by the signal module
410
        self.check_signal_action = None   # changed by the signal module
Armin Rigo's avatar
Armin Rigo committed
411
        make_finalizer_queue(W_Root, self)
412
        self._code_of_sys_exc_info = None
Armin Rigo's avatar
Armin Rigo committed
413

Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
414
        # can be overridden to a subclass
415
        self.initialize()
416

Anders Chrigstrom's avatar
Anders Chrigstrom committed
417
418
    def startup(self):
        # To be called before using the space
Armin Rigo's avatar
Armin Rigo committed
419
        self.threadlocals.enter_thread(self)
420

421
        # Initialize already imported builtin modules
422
        from pypy.interpreter.module import Module
423
        w_modules = self.sys.get('modules')
424
425
        for w_modname in self.unpackiterable(
                                self.sys.get('builtin_module_names')):
426
427
            try:
                w_mod = self.getitem(w_modules, w_modname)
428
            except OperationError as e:
429
430
431
                if e.match(self, self.w_KeyError):
                    continue
                raise
Armin Rigo's avatar
Armin Rigo committed
432
433
            if isinstance(w_mod, Module) and not w_mod.startup_called:
                w_mod.init(self)
Anders Chrigstrom's avatar
Anders Chrigstrom committed
434
435

    def finish(self):
436
        self.wait_for_thread_shutdown()
437
        w_exitfunc = self.sys.getdictvalue(self, 'exitfunc')
Anders Chrigstrom's avatar
Anders Chrigstrom committed
438
        if w_exitfunc is not None:
Armin Rigo's avatar
Armin Rigo committed
439
440
441
442
            try:
                self.call_function(w_exitfunc)
            except OperationError as e:
                e.write_unraisable(self, 'sys.exitfunc == ', w_exitfunc)
443
        from pypy.interpreter.module import Module
444
        for w_mod in self.builtin_modules.values():
Armin Rigo's avatar
Armin Rigo committed
445
446
            if isinstance(w_mod, Module) and w_mod.startup_called:
                w_mod.shutdown(self)
Justas Sadzevicius's avatar
Justas Sadzevicius committed
447

448
449
450
451
452
453
454
455
456
457
458
459
460
461
    def wait_for_thread_shutdown(self):
        """Wait until threading._shutdown() completes, provided the threading
        module was imported in the first place.  The shutdown routine will
        wait until all non-daemon 'threading' threads have completed."""
        if not self.config.translation.thread:
            return

        w_modules = self.sys.get('modules')
        w_mod = self.finditem_str(w_modules, 'threading')
        if w_mod is None:
            return

        try:
            self.call_method(w_mod, "_shutdown")
462
        except OperationError as e:
463
464
            e.write_unraisable(self, "threading._shutdown()")

465
    def __repr__(self):
466
467
468
469
        try:
            return self._this_space_repr_
        except AttributeError:
            return self.__class__.__name__
470

471
    def setbuiltinmodule(self, importname):
Samuele Pedroni's avatar
Samuele Pedroni committed
472
        """NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules"""
473
474
475
476
477
        if '.' in importname:
            fullname = importname
            importname = fullname.rsplit('.', 1)[1]
        else:
            fullname = "pypy.module.%s" % importname
478

Justas Sadzevicius's avatar
Justas Sadzevicius committed
479
        Module = __import__(fullname,
480
                            None, None, ["Module"]).Module
481
482
483
484
485
        if Module.applevel_name is not None:
            name = Module.applevel_name
        else:
            name = importname

486
487
488
        mod = Module(self, self.wrap(name))
        mod.install()

489
        return name
490

491
    def getbuiltinmodule(self, name, force_init=False, reuse=True):
Christian Tismer-Sperling's avatar
Christian Tismer-Sperling committed
492
493
        w_name = self.wrap(name)
        w_modules = self.sys.get('modules')
494
        if not force_init:
495
            assert reuse
496
497
            try:
                return self.getitem(w_modules, w_name)
498
            except OperationError as e:
499
500
                if not e.match(self, self.w_KeyError):
                    raise
501
502
503
504
505
506

        # If the module is a builtin but not yet imported,
        # retrieve it and initialize it
        try:
            w_mod = self.builtin_modules[name]
        except KeyError:
507
508
509
            raise oefmt(self.w_SystemError,
                        "getbuiltinmodule() called with non-builtin module %s",
                        name)
510

511
512
513
514
515
516
517
518
519
520
521
522
523
        # Add the module to sys.modules and initialize the module. The
        # order is important to avoid recursions.
        from pypy.interpreter.module import Module
        if isinstance(w_mod, Module):
            if not reuse and w_mod.startup_called:
                # create a copy of the module.  (see issue1514) eventlet
                # patcher relies on this behaviour.
                w_mod2 = self.wrap(Module(self, w_name))
                self.setitem(w_modules, w_name, w_mod2)
                w_mod.getdict(self)  # unlazy w_initialdict
                self.call_method(w_mod2.getdict(self), 'update',
                                 w_mod.w_initialdict)
                return w_mod2
524
            self.setitem(w_modules, w_name, w_mod)
525
            w_mod.init(self)
526
527
        else:
            self.setitem(w_modules, w_name, w_mod)
528
        return w_mod
Christian Tismer-Sperling's avatar
Christian Tismer-Sperling committed
529

530
    def get_builtinmodule_to_install(self):
531
532
533
534
        """NOT_RPYTHON"""
        try:
            return self._builtinmodule_list
        except AttributeError:
Holger Krekel's avatar
Holger Krekel committed
535
536
            pass

537
        modules = []
538

539
        # You can enable more modules by specifying --usemodules=xxx,yyy
540
541
        for name, value in self.config.objspace.usemodules:
            if value and name not in modules:
542
                modules.append(name)
543

544
545
546
547
548
        if self.config.objspace.extmodules:
            for name in self.config.objspace.extmodules.split(','):
                if name not in modules:
                    modules.append(name)

549
        self._builtinmodule_list = modules
Holger Krekel's avatar
Holger Krekel committed
550
        return self._builtinmodule_list
551

552
553
554
555
556
557
558
559
    ALL_BUILTIN_MODULES = [
        'posix', 'nt', 'os2', 'mac', 'ce', 'riscos',
        'math', 'array', 'select',
        '_random', '_sre', 'time', '_socket', 'errno',
        'unicodedata',
        'parser', 'fcntl', '_codecs', 'binascii'
    ]

560
561
562
563
564
565
566
567
568
569
    # These modules are treated like CPython treats built-in modules,
    # i.e. they always shadow any xx.py.  The other modules are treated
    # like CPython treats extension modules, and are loaded in sys.path
    # order by the fake entry '.../lib_pypy/__extensions__'.
    MODULES_THAT_ALWAYS_SHADOW = dict.fromkeys([
        '__builtin__', '__pypy__', '_ast', '_codecs', '_sre', '_warnings',
        '_weakref', 'errno', 'exceptions', 'gc', 'imp', 'marshal',
        'posix', 'nt', 'pwd', 'signal', 'sys', 'thread', 'zipimport',
    ], None)

570
    def make_builtins(self):
571
572
        "NOT_RPYTHON: only for initializing the space."

Armin Rigo's avatar
Armin Rigo committed
573
        from pypy.module.exceptions import Module
574
575
        w_name = self.wrap('exceptions')
        self.exceptions_module = Module(self, w_name)
576
        self.exceptions_module.install()
Armin Rigo's avatar
Armin Rigo committed
577

Justas Sadzevicius's avatar
Justas Sadzevicius committed
578
        from pypy.module.sys import Module
579
        w_name = self.wrap('sys')
Justas Sadzevicius's avatar
Justas Sadzevicius committed
580
        self.sys = Module(self, w_name)
581
        self.sys.install()
582

583
584
        from pypy.module.imp import Module
        w_name = self.wrap('imp')
585
586
        mod = Module(self, w_name)
        mod.install()
Armin Rigo's avatar
Armin Rigo committed
587

Justas Sadzevicius's avatar
Justas Sadzevicius committed
588
        from pypy.module.__builtin__ import Module
589
        w_name = self.wrap('__builtin__')
Justas Sadzevicius's avatar
Justas Sadzevicius committed
590
        self.builtin = Module(self, w_name)
591
        w_builtin = self.wrap(self.builtin)
592
        w_builtin.install()
Justas Sadzevicius's avatar
Justas Sadzevicius committed
593
        self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin)
594

595
596
        bootstrap_modules = set(('sys', 'imp', '__builtin__', 'exceptions'))
        installed_builtin_modules = list(bootstrap_modules)
597

598
        exception_types_w = self.export_builtin_exceptions()
Armin Rigo's avatar
Armin Rigo committed
599

600
        # initialize with "bootstrap types" from objspace  (e.g. w_None)
Armin Rigo's avatar
Armin Rigo committed
601
602
        types_w = (self.get_builtin_types().items() +
                   exception_types_w.items())
603
604
        for name, w_type in types_w:
            self.setitem(self.builtin.w_dict, self.wrap(name), w_type)
605

Alex Gaynor's avatar
Alex Gaynor committed
606
        # install mixed modules
607
        for mixedname in self.get_builtinmodule_to_install():
Alex Gaynor's avatar
Alex Gaynor committed
608
            if mixedname not in bootstrap_modules:
609
                self.install_mixedmodule(mixedname, installed_builtin_modules)
610
611
612
613
614
615
616
617
618

        installed_builtin_modules.sort()
        w_builtin_module_names = self.newtuple(
            [self.wrap(fn) for fn in installed_builtin_modules])

        # force this value into the dict without unlazyfying everything
        self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'),
                     w_builtin_module_names)

619
620
621
622
623
    def get_builtin_types(self):
        """Get a dictionary mapping the names of builtin types to the type
        objects."""
        raise NotImplementedError

Armin Rigo's avatar
Armin Rigo committed
624
625
    def export_builtin_exceptions(self):
        """NOT_RPYTHON"""
626
        w_dic = self.exceptions_module.getdict(self)
627
628
629
        w_keys = self.call_method(w_dic, "keys")
        exc_types_w = {}
        for w_name in self.unpackiterable(w_keys):
Armin Rigo's avatar
Armin Rigo committed
630
631
632
633
            name = self.str_w(w_name)
            if not name.startswith('__'):
                excname = name
                w_exc = self.getitem(w_dic, w_name)
634
635
636
                exc_types_w[name] = w_exc
                setattr(self, "w_" + excname, w_exc)
        return exc_types_w
Armin Rigo's avatar
Armin Rigo committed
637

638
    def install_mixedmodule(self, mixedname, installed_builtin_modules):
Justas Sadzevicius's avatar
Justas Sadzevicius committed
639
        """NOT_RPYTHON"""
640
641
642
643
644
645
        modname = self.setbuiltinmodule(mixedname)
        if modname:
            assert modname not in installed_builtin_modules, (
                "duplicate interp-level module enabled for the "
                "app-level module %r" % (modname,))
            installed_builtin_modules.append(modname)
646

647
648
    def setup_builtin_modules(self):
        "NOT_RPYTHON: only for initializing the space."
649
650
651
        if self.config.objspace.usemodules.cpyext:
            from pypy.module.cpyext.state import State
            self.fromcache(State).build_api(self)
652
653
654
655
656
        self.getbuiltinmodule('sys')
        self.getbuiltinmodule('imp')
        self.getbuiltinmodule('__builtin__')
        for mod in self.builtin_modules.values():
            mod.setup_after_space_initialization()
657

658
659
660
661
662
663
    def initialize(self):
        """NOT_RPYTHON: Abstract method that should put some minimal
        content into the w_builtins."""

    def getexecutioncontext(self):
        "Return what we consider to be the active execution context."
664
665
        # Important: the annotator must not see a prebuilt ExecutionContext:
        # you should not see frames while you translate
666
667
        # so we make sure that the threadlocals never *have* an
        # ExecutionContext during translation.
Armin Rigo's avatar
Armin Rigo committed
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
        if not we_are_translated():
            if self.config.translating:
                assert self.threadlocals.get_ec() is None, (
                    "threadlocals got an ExecutionContext during translation!")
                try:
                    return self._ec_during_translation
                except AttributeError:
                    ec = self.createexecutioncontext()
                    self._ec_during_translation = ec
                    return ec
            else:
                ec = self.threadlocals.get_ec()
                if ec is None:
                    self.threadlocals.enter_thread(self)
                    ec = self.threadlocals.get_ec()
683
                return ec
Armin Rigo's avatar
Armin Rigo committed
684
685
686
        else:
            # translated case follows.  self.threadlocals is either from
            # 'pypy.interpreter.miscutils' or 'pypy.module.thread.threadlocals'.
687
688
689
690
691
            # the result is assumed to be non-null: enter_thread() was called
            # by space.startup().
            ec = self.threadlocals.get_ec()
            assert ec is not None
            return ec
692
693

    def _freeze_(self):
Justas Sadzevicius's avatar
Justas Sadzevicius committed
694
        return True
695
696
697
698
699

    def createexecutioncontext(self):
        "Factory function for execution contexts."
        return ExecutionContext(self)

700
701
    def createcompiler(self):
        "Factory function creating a compiler object."
702
703
704
        try:
            return self.default_compiler
        except AttributeError:
705
            from pypy.interpreter.pycompiler import PythonAstCompiler
Benjamin Peterson's avatar
Benjamin Peterson committed
706
            compiler = PythonAstCompiler(self)
707
708
            self.default_compiler = compiler
            return compiler
709

710
    def createframe(self, code, w_globals, outer_func=None):
711
        "Create an empty PyFrame suitable for this code object."
712
        return self.FrameClass(self, code, w_globals, outer_func)
713

714
715
716
    def allocate_lock(self):
        """Return an interp-level Lock object if threads are enabled,
        and a dummy object if they are not."""
Brian Kearns's avatar
Brian Kearns committed
717
718
719
        from rpython.rlib import rthread
        if not self.config.objspace.usemodules.thread:
            return rthread.dummy_lock
720
721
722
723
724
        # hack: we can't have prebuilt locks if we're translating.
        # In this special situation we should just not lock at all
        # (translation is not multithreaded anyway).
        if not we_are_translated() and self.config.translating:
            raise CannotHaveLock()
725
        try:
Brian Kearns's avatar
Brian Kearns committed
726
727
            return rthread.allocate_lock()
        except rthread.error:
Philip Jenvey's avatar
Philip Jenvey committed
728
            raise oefmt(self.w_RuntimeError, "out of resources")
729

730
731
732
733
734
735
736
    # Following is a friendly interface to common object space operations
    # that can be defined in term of more primitive ones.  Subclasses
    # may also override specific functions for performance.

    def not_(self, w_obj):
        return self.wrap(not self.is_true(w_obj))

737
    def eq_w(self, w_obj1, w_obj2):
Armin Rigo's avatar
Armin Rigo committed
738
        """Implements equality with the double check 'x is y or x == y'."""
739
        return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))
740

Armin Rigo's avatar
Armin Rigo committed
741
742
743
744
745
746
747
    def is_(self, w_one, w_two):
        return self.newbool(self.is_w(w_one, w_two))

    def is_w(self, w_one, w_two):
        # done by a method call on w_two (and not on w_one, because of the
        # expected programming style where we say "if x is None" or
        # "if x is object").
748
        assert w_two is not None
Armin Rigo's avatar
Armin Rigo committed
749
        return w_two.is_w(self, w_one)
750

751
752
753
754
755
756
    def is_none(self, w_obj):
        """ mostly for checking inputargs that have unwrap_spec and
        can accept both w_None and None
        """
        return w_obj is None or self.is_w(w_obj, self.w_None)

Armin Rigo's avatar
Armin Rigo committed
757
    def id(self, w_obj):
Armin Rigo's avatar
Armin Rigo committed
758
759
        w_result = w_obj.immutable_unique_id(self)
        if w_result is None:
760
761
            # in the common case, returns an unsigned value
            w_result = self.wrap(r_uint(compute_unique_id(w_obj)))
Armin Rigo's avatar
Armin Rigo committed
762
        return w_result
Armin Rigo's avatar
Armin Rigo committed
763

Armin Rigo's avatar
Armin Rigo committed
764
765
766
767
    def hash_w(self, w_obj):
        """shortcut for space.int_w(space.hash(w_obj))"""
        return self.int_w(self.hash(w_obj))

768
    def len_w(self, w_obj):
769
        """shortcut for space.int_w(space.len(w_obj))"""
770
771
        return self.int_w(self.len(w_obj))

772
773
774
775
    def contains_w(self, w_container, w_item):
        """shortcut for space.is_true(space.contains(w_container, w_item))"""
        return self.is_true(self.contains(w_container, w_item))

Armin Rigo's avatar
Armin Rigo committed
776
    def setitem_str(self, w_obj, key, w_value):
777
778
779
780
        return self.setitem(w_obj, self.wrap(key), w_value)

    def finditem_str(self, w_obj, key):
        return self.finditem(w_obj, self.wrap(key))
Justas Sadzevicius's avatar
Justas Sadzevicius committed
781

782
783
784
    def finditem(self, w_obj, w_key):
        try:
            return self.getitem(w_obj, w_key)
785
        except OperationError as e:
786
787
788
789
            if e.match(self, self.w_KeyError):
                return None
            raise

790
791
792
    def findattr(self, w_object, w_name):
        try:
            return self.getattr(w_object, w_name)
793
        except OperationError as e:
794
795
796
797
798
            # a PyPy extension: let SystemExit and KeyboardInterrupt go through
            if e.async(self):
                raise
            return None

Brian Kearns's avatar
Brian Kearns committed
799
    @signature(types.any(), types.bool(), returns=types.instance(W_Root))
800
801
802
803
804
805
    def newbool(self, b):
        if b:
            return self.w_True
        else:
            return self.w_False

806
    def new_interned_w_str(self, w_s):
807
        assert isinstance(w_s, W_Root)   # and is not None
808
        s = self.str_w(w_s)
Armin Rigo's avatar
Armin Rigo committed
809
810
        if not we_are_translated():
            assert type(s) is str
811
812
813
814
815
        w_s1 = self.interned_strings.get(s)
        if w_s1 is None:
            w_s1 = w_s
            self.interned_strings.set(s, w_s1)
        return w_s1
816

Anders Chrigstrom's avatar
Anders Chrigstrom committed
817
    def new_interned_str(self, s):
Armin Rigo's avatar
Armin Rigo committed
818
819
        if not we_are_translated():
            assert type(s) is str
820
821
822
823
824
        w_s1 = self.interned_strings.get(s)
        if w_s1 is None:
            w_s1 = self.wrap(s)
            self.interned_strings.set(s, w_s1)
        return w_s1
Anders Chrigstrom's avatar
Anders Chrigstrom committed
825

826
827
828
829
830
831
    def is_interned_str(self, s):
        # interface for marshal_impl
        if not we_are_translated():
            assert type(s) is str
        return self.interned_strings.get(s) is not None

Samuele Pedroni's avatar
Samuele Pedroni committed
832
    def descr_self_interp_w(self, RequiredClass, w_obj):
Armin Rigo's avatar
Armin Rigo committed
833
        if not isinstance(w_obj, RequiredClass):
Samuele Pedroni's avatar
Samuele Pedroni committed
834
            raise DescrMismatch()
Armin Rigo's avatar
Armin Rigo committed
835
        return w_obj
Samuele Pedroni's avatar
Samuele Pedroni committed
836
    descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)'
Justas Sadzevicius's avatar
Justas Sadzevicius committed
837

Adrien Di Mascio's avatar
Adrien Di Mascio committed
838
839
    def interp_w(self, RequiredClass, w_obj, can_be_None=False):
        """
840
        Unwrap w_obj, checking that it is an instance of the required internal
841
        interpreter class.
842
        """
Armin Rigo's avatar
Armin Rigo committed
843
        assert RequiredClass is not None
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
844
        if can_be_None and self.is_none(w_obj):
845
            return None
Armin Rigo's avatar
Armin Rigo committed
846
        if not isinstance(w_obj, RequiredClass):   # or obj is None
847
848
849
850
            raise oefmt(self.w_TypeError,
                        "'%s' object expected, got '%N' instead",
                        wrappable_class_name(RequiredClass),
                        w_obj.getclass(self))
Armin Rigo's avatar
Armin Rigo committed
851
        return w_obj
Armin Rigo's avatar
Armin Rigo committed
852
    interp_w._annspecialcase_ = 'specialize:arg(1)'
Adrien Di Mascio's avatar
Adrien Di Mascio committed
853

854
    def unpackiterable(self, w_iterable, expected_length=-1):
855
856
        """Unpack an iterable into a real (interpreter-level) list.

Armin Rigo's avatar
Armin Rigo committed
857
        Raise an OperationError(w_ValueError) if the length is wrong."""
858
        w_iterator = self.iter(w_iterable)
859
860
861
862
863
864
865
866
867
868
869
870
871
        if expected_length == -1:
            # xxx special hack for speed
            from pypy.interpreter.generator import GeneratorIterator
            if isinstance(w_iterator, GeneratorIterator):
                lst_w = []
                w_iterator.unpack_into(lst_w)
                return lst_w
            # /xxx
            return self._unpackiterable_unknown_length(w_iterator, w_iterable)
        else:
            lst_w = self._unpackiterable_known_length(w_iterator,
                                                      expected_length)
            return lst_w[:]     # make the resulting list resizable
872

873
    def iteriterable(self, w_iterable):
874
        return InterpIterable(self, w_iterable)
875

876
    def _unpackiterable_unknown_length(self, w_iterator, w_iterable):
877
878
879
        """Unpack an iterable of unknown length into an interp-level
        list.
        """
880
881
        # If we can guess the expected length we can preallocate.
        try:
882
            items = newlist_hint(self.length_hint(w_iterable, 0))
883
        except MemoryError:
884
            items = [] # it might have lied
885

886
        tp = self.type(w_iterator)
887
        while True:
888
889
890
            unpackiterable_driver.jit_merge_point(tp=tp,
                                                  w_iterator=w_iterator,
                                                  items=items)
891
892
            try:
                w_item = self.next(w_iterator)
893
            except OperationError as e:
894
                if not e.match(self, self.w_StopIteration):
895
                    raise
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
                break  # done
            items.append(w_item)
        #
        return items

    @jit.dont_look_inside
    def _unpackiterable_known_length(self, w_iterator, expected_length):
        # Unpack a known length list, without letting the JIT look inside.
        # Implemented by just calling the @jit.unroll_safe version, but
        # the JIT stopped looking inside already.
        return self._unpackiterable_known_length_jitlook(w_iterator,
                                                         expected_length)

    @jit.unroll_safe
    def _unpackiterable_known_length_jitlook(self, w_iterator,
                                             expected_length):
        items = [None] * expected_length
913
        idx = 0
914
915
916
        while True:
            try:
                w_item = self.next(w_iterator)
917
            except OperationError as e:
918
919
920
                if not e.match(self, self.w_StopIteration):
                    raise
                break  # done
921
            if idx == expected_length:
Philip Jenvey's avatar
Philip Jenvey committed
922
                raise oefmt(self.w_ValueError, "too many values to unpack")
923
            items[idx] = w_item
924
            idx += 1
925
        if idx < expected_length:
926
927
928
            raise oefmt(self.w_ValueError,
                        "need more than %d value%s to unpack",
                        idx, "" if idx == 1 else "s")
929
930
        return items

931
932
933
934
935
936
937
938
    def unpackiterable_unroll(self, w_iterable, expected_length):
        # Like unpackiterable(), but for the cases where we have
        # an expected_length and want to unroll when JITted.
        # Returns a fixed-size list.
        w_iterator = self.iter(w_iterable)
        assert expected_length != -1
        return self._unpackiterable_known_length_jitlook(w_iterator,
                                                         expected_length)
939

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955

    def unpackiterable_int(self, w_obj):
        """
        Return a RPython list of unwrapped ints out of w_obj. The list is
        guaranteed to be acopy of the actual data contained in w_obj, so you
        can freely modify it. It might return None if not supported.
        """
        return w_obj.unpackiterable_int(self)

    def unpackiterable_float(self, w_obj):
        """
        Same as unpackiterable_int, but for floats.
        """
        return w_obj.unpackiterable_float(self)


956
957
958
959
960
961
    def length_hint(self, w_obj, default):
        """Return the length of an object, consulting its __length_hint__
        method if necessary.
        """
        try:
            return self.len_w(w_obj)
962
        except OperationError as e:
963
964
965
966
967
968
969
970
971
            if not (e.match(self, self.w_TypeError) or
                    e.match(self, self.w_AttributeError)):
                raise

        w_descr = self.lookup(w_obj, '__length_hint__')
        if w_descr is None:
            return default
        try:
            w_hint = self.get_and_call_function(w_descr, w_obj)
972
        except OperationError as e:
973
974
975
976
            if not (e.match(self, self.w_TypeError) or
                    e.match(self, self.w_AttributeError)):
                raise
            return default
Philip Jenvey's avatar
Philip Jenvey committed
977
978