OLD | NEW |
1 # | 1 # |
2 # Pyrex - Parse tree nodes for expressions | 2 # Pyrex - Parse tree nodes for expressions |
3 # | 3 # |
4 | 4 |
5 import operator | 5 import operator |
6 | 6 |
7 from Errors import error, warning, warn_once, InternalError | 7 from Errors import error, warning, warn_once, InternalError |
8 from Errors import hold_errors, release_errors, held_errors, report_error | 8 from Errors import hold_errors, release_errors, held_errors, report_error |
9 from Code import UtilityCode | 9 from Code import UtilityCode |
10 import StringEncoding | 10 import StringEncoding |
(...skipping 4383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4394 self.key.generate_disposal_code(code) | 4394 self.key.generate_disposal_code(code) |
4395 self.value.generate_disposal_code(code) | 4395 self.value.generate_disposal_code(code) |
4396 | 4396 |
4397 def free_temps(self, code): | 4397 def free_temps(self, code): |
4398 self.key.free_temps(code) | 4398 self.key.free_temps(code) |
4399 self.value.free_temps(code) | 4399 self.value.free_temps(code) |
4400 ········ | 4400 ········ |
4401 def __iter__(self): | 4401 def __iter__(self): |
4402 return iter([self.key, self.value]) | 4402 return iter([self.key, self.value]) |
4403 | 4403 |
| 4404 class ModuleNameMixin(object): |
| 4405 def set_mod_name(self, env): |
| 4406 self.module_name = env.global_scope().qualified_name |
4404 | 4407 |
4405 class ClassNode(ExprNode): | 4408 def get_py_mod_name(self, code): |
| 4409 return code.get_py_string_const( |
| 4410 self.module_name, identifier=True) |
| 4411 |
| 4412 class ClassNode(ExprNode, ModuleNameMixin): |
4406 # Helper class used in the implementation of Python | 4413 # Helper class used in the implementation of Python |
4407 # class definitions. Constructs a class object given | 4414 # class definitions. Constructs a class object given |
4408 # a name, tuple of bases and class dictionary. | 4415 # a name, tuple of bases and class dictionary. |
4409 # | 4416 # |
4410 # name EncodedString Name of the class | 4417 # name EncodedString Name of the class |
4411 # bases ExprNode Base class tuple | 4418 # bases ExprNode Base class tuple |
4412 # dict ExprNode Class dict (not owned by this node) | 4419 # dict ExprNode Class dict (not owned by this node) |
4413 # doc ExprNode or None Doc string | 4420 # doc ExprNode or None Doc string |
4414 # module_name string Name of defining module | 4421 # module_name EncodedString Name of defining module |
4415 ···· | 4422 ···· |
4416 subexprs = ['bases', 'doc'] | 4423 subexprs = ['bases', 'doc'] |
4417 | 4424 |
4418 def analyse_types(self, env): | 4425 def analyse_types(self, env): |
4419 self.bases.analyse_types(env) | 4426 self.bases.analyse_types(env) |
4420 if self.doc: | 4427 if self.doc: |
4421 self.doc.analyse_types(env) | 4428 self.doc.analyse_types(env) |
4422 self.doc = self.doc.coerce_to_pyobject(env) | 4429 self.doc = self.doc.coerce_to_pyobject(env) |
4423 self.module_name = env.global_scope().qualified_name | |
4424 self.type = py_object_type | 4430 self.type = py_object_type |
4425 self.is_temp = 1 | 4431 self.is_temp = 1 |
4426 env.use_utility_code(create_class_utility_code); | 4432 env.use_utility_code(create_class_utility_code); |
| 4433 #TODO(craig,haoyu) This should be moved to a better place |
| 4434 self.set_mod_name(env) |
4427 | 4435 |
4428 def may_be_none(self): | 4436 def may_be_none(self): |
4429 return False | 4437 return False |
4430 | 4438 |
4431 gil_message = "Constructing Python class" | 4439 gil_message = "Constructing Python class" |
4432 | 4440 |
4433 def generate_result_code(self, code): | 4441 def generate_result_code(self, code): |
4434 cname = code.intern_identifier(self.name) | 4442 cname = code.intern_identifier(self.name) |
4435 if self.doc: | 4443 if self.doc: |
4436 code.put_error_if_neg(self.pos,· | 4444 code.put_error_if_neg(self.pos,· |
4437 'PyDict_SetItemString(%s, "__doc__", %s)' % ( | 4445 'PyDict_SetItemString(%s, "__doc__", %s)' % ( |
4438 self.dict.py_result(), | 4446 self.dict.py_result(), |
4439 self.doc.py_result())) | 4447 self.doc.py_result())) |
| 4448 py_mod_name = self.get_py_mod_name(code) |
4440 code.putln( | 4449 code.putln( |
4441 '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); %s' % ( | 4450 '%s = __Pyx_CreateClass(%s, %s, %s, %s); %s' % ( |
4442 self.result(), | 4451 self.result(), |
4443 self.bases.py_result(), | 4452 self.bases.py_result(), |
4444 self.dict.py_result(), | 4453 self.dict.py_result(), |
4445 cname, | 4454 cname, |
4446 self.module_name, | 4455 py_mod_name, |
4447 code.error_goto_if_null(self.result(), self.pos))) | 4456 code.error_goto_if_null(self.result(), self.pos))) |
4448 code.put_gotref(self.py_result()) | 4457 code.put_gotref(self.py_result()) |
4449 | 4458 |
4450 class BoundMethodNode(ExprNode): | 4459 class BoundMethodNode(ExprNode): |
4451 # Helper class used in the implementation of Python | 4460 # Helper class used in the implementation of Python |
4452 # class definitions. Constructs an bound method | 4461 # class definitions. Constructs an bound method |
4453 # object from a class and a function. | 4462 # object from a class and a function. |
4454 # | 4463 # |
4455 # function ExprNode Function object | 4464 # function ExprNode Function object |
4456 # self_object ExprNode self object | 4465 # self_object ExprNode self object |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4498 class_cname = code.pyclass_stack[-1].classobj.result() | 4507 class_cname = code.pyclass_stack[-1].classobj.result() |
4499 code.putln( | 4508 code.putln( |
4500 "%s = PyMethod_New(%s, 0, %s); %s" % ( | 4509 "%s = PyMethod_New(%s, 0, %s); %s" % ( |
4501 self.result(), | 4510 self.result(), |
4502 self.function.py_result(), | 4511 self.function.py_result(), |
4503 class_cname, | 4512 class_cname, |
4504 code.error_goto_if_null(self.result(), self.pos))) | 4513 code.error_goto_if_null(self.result(), self.pos))) |
4505 code.put_gotref(self.py_result()) | 4514 code.put_gotref(self.py_result()) |
4506 | 4515 |
4507 | 4516 |
4508 class PyCFunctionNode(ExprNode): | 4517 class PyCFunctionNode(ExprNode, ModuleNameMixin): |
4509 # Helper class used in the implementation of Python | 4518 # Helper class used in the implementation of Python |
4510 # class definitions. Constructs a PyCFunction object | 4519 # class definitions. Constructs a PyCFunction object |
4511 # from a PyMethodDef struct. | 4520 # from a PyMethodDef struct. |
4512 # | 4521 # |
4513 # pymethdef_cname string PyMethodDef structure | 4522 # pymethdef_cname string PyMethodDef structure |
4514 # self_object ExprNode or None | 4523 # self_object ExprNode or None |
4515 # binding bool | 4524 # binding bool |
| 4525 # module_name EncodedString Name of defining module |
4516 | 4526 |
4517 subexprs = [] | 4527 subexprs = [] |
4518 self_object = None | 4528 self_object = None |
4519 binding = False | 4529 binding = False |
4520 ···· | 4530 ···· |
4521 type = py_object_type | 4531 type = py_object_type |
4522 is_temp = 1 | 4532 is_temp = 1 |
4523 ···· | 4533 ···· |
4524 def analyse_types(self, env): | 4534 def analyse_types(self, env): |
4525 if self.binding: | 4535 if self.binding: |
4526 env.use_utility_code(binding_cfunc_utility_code) | 4536 env.use_utility_code(binding_cfunc_utility_code) |
4527 | 4537 |
| 4538 #TODO(craig,haoyu) This should be moved to a better place |
| 4539 self.set_mod_name(env) |
| 4540 |
4528 def may_be_none(self): | 4541 def may_be_none(self): |
4529 return False | 4542 return False |
4530 ···· | 4543 ···· |
4531 gil_message = "Constructing Python function" | 4544 gil_message = "Constructing Python function" |
4532 | 4545 |
4533 def self_result_code(self): | 4546 def self_result_code(self): |
4534 if self.self_object is None: | 4547 if self.self_object is None: |
4535 self_result = "NULL" | 4548 self_result = "NULL" |
4536 else: | 4549 else: |
4537 self_result = self.self_object.py_result() | 4550 self_result = self.self_object.py_result() |
4538 return self_result | 4551 return self_result |
4539 | 4552 |
4540 def generate_result_code(self, code): | 4553 def generate_result_code(self, code): |
4541 if self.binding: | 4554 if self.binding: |
4542 constructor = "%s_New" % Naming.binding_cfunc | 4555 constructor = "%s_NewEx" % Naming.binding_cfunc |
4543 else: | 4556 else: |
4544 constructor = "PyCFunction_New" | 4557 constructor = "PyCFunction_NewEx" |
| 4558 py_mod_name = self.get_py_mod_name(code) |
4545 code.putln( | 4559 code.putln( |
4546 "%s = %s(&%s, %s); %s" % ( | 4560 '%s = %s(&%s, %s, %s); %s' % ( |
4547 self.result(), | 4561 self.result(), |
4548 constructor, | 4562 constructor, |
4549 self.pymethdef_cname, | 4563 self.pymethdef_cname, |
4550 self.self_result_code(), | 4564 self.self_result_code(), |
| 4565 py_mod_name, |
4551 code.error_goto_if_null(self.result(), self.pos))) | 4566 code.error_goto_if_null(self.result(), self.pos))) |
4552 code.put_gotref(self.py_result()) | 4567 code.put_gotref(self.py_result()) |
4553 | 4568 |
4554 class InnerFunctionNode(PyCFunctionNode): | 4569 class InnerFunctionNode(PyCFunctionNode): |
4555 # Special PyCFunctionNode that depends on a closure class | 4570 # Special PyCFunctionNode that depends on a closure class |
4556 # | 4571 # |
4557 binding = True | 4572 binding = True |
4558 ···· | 4573 ···· |
4559 def self_result_code(self): | 4574 def self_result_code(self): |
4560 return "((PyObject*)%s)" % Naming.cur_scope_cname | 4575 return "((PyObject*)%s)" % Naming.cur_scope_cname |
(...skipping 2498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7059 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", | 7074 PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", |
7060 Py_TYPE(obj)->tp_name, type->tp_name); | 7075 Py_TYPE(obj)->tp_name, type->tp_name); |
7061 return 0; | 7076 return 0; |
7062 } | 7077 } |
7063 """) | 7078 """) |
7064 | 7079 |
7065 #-------------------------------------------------------------------------------
----- | 7080 #-------------------------------------------------------------------------------
----- |
7066 | 7081 |
7067 create_class_utility_code = UtilityCode( | 7082 create_class_utility_code = UtilityCode( |
7068 proto = """ | 7083 proto = """ |
7069 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *na
me, const char *modname); /*proto*/ | 7084 static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *na
me, PyObject *modname); /*proto*/ |
7070 """, | 7085 """, |
7071 impl = """ | 7086 impl = """ |
7072 static PyObject *__Pyx_CreateClass( | 7087 static PyObject *__Pyx_CreateClass( |
7073 PyObject *bases, PyObject *dict, PyObject *name, const char *modname) | 7088 PyObject *bases, PyObject *dict, PyObject *name, PyObject *modname) |
7074 { | 7089 { |
7075 PyObject *py_modname; | |
7076 PyObject *result = 0; | 7090 PyObject *result = 0; |
7077 | 7091 |
7078 #if PY_MAJOR_VERSION < 3 | 7092 if (PyDict_SetItemString(dict, "__module__", modname) < 0) |
7079 py_modname = PyString_FromString(modname); | |
7080 #else | |
7081 py_modname = PyUnicode_FromString(modname); | |
7082 #endif | |
7083 if (!py_modname) | |
7084 goto bad; | |
7085 if (PyDict_SetItemString(dict, "__module__", py_modname) < 0) | |
7086 goto bad; | 7093 goto bad; |
7087 #if PY_MAJOR_VERSION < 3 | 7094 #if PY_MAJOR_VERSION < 3 |
7088 result = PyClass_New(bases, dict, name); | 7095 result = PyClass_New(bases, dict, name); |
7089 #else | 7096 #else |
7090 result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases,
dict, NULL); | 7097 result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases,
dict, NULL); |
7091 #endif | 7098 #endif |
7092 bad: | 7099 bad: |
7093 Py_XDECREF(py_modname); | |
7094 return result; | 7100 return result; |
7095 } | 7101 } |
7096 """) | 7102 """) |
7097 | 7103 |
7098 #-------------------------------------------------------------------------------
----- | 7104 #-------------------------------------------------------------------------------
----- |
7099 | 7105 |
7100 cpp_exception_utility_code = UtilityCode( | 7106 cpp_exception_utility_code = UtilityCode( |
7101 proto = """ | 7107 proto = """ |
7102 #ifndef __Pyx_CppExn2PyErr | 7108 #ifndef __Pyx_CppExn2PyErr |
7103 static void __Pyx_CppExn2PyErr() { | 7109 static void __Pyx_CppExn2PyErr() { |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7605 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc; | 7611 %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc; |
7606 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get; | 7612 %(binding_cfunc)s_type.tp_descr_get = %(binding_cfunc)s_descr_get; |
7607 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) { | 7613 if (PyType_Ready(&%(binding_cfunc)s_type) < 0) { |
7608 return -1; | 7614 return -1; |
7609 } | 7615 } |
7610 %(binding_cfunc)s = &%(binding_cfunc)s_type; | 7616 %(binding_cfunc)s = &%(binding_cfunc)s_type; |
7611 return 0; | 7617 return 0; |
7612 | 7618 |
7613 } | 7619 } |
7614 """ % Naming.__dict__) | 7620 """ % Naming.__dict__) |
OLD | NEW |