In my current implementation (proof of concept), I must use a trick to
detect the _GenericAlias, without import. I check the tp_name.
static PyObject*
union_to_tuple(PyObject* cls) {
//printf("union_to_tuple");
if (!strcmp(Py_TYPE(cls)->tp_name,"_GenericAlias")) {
PyObject* origin = PyObject_GetAttrString(cls, "__origin__");
//printf("origin = %p\n",origin);
if (origin == NULL) {
printf("origin == NULL, return cls");
return cls;
}
//printf("X origin = %s\n",Py_TYPE(cls)->tp_name);
if (PyObject_HasAttrString(origin, "_name")) {
PyObject* name = PyObject_GetAttrString(origin, "_name");
if (name==NULL) {
printf("_name = NULL\n");
Py_DECREF(origin);
return cls;
}
//printf("name = %s\n",Py_TYPE(name)->tp_name);
const char* data = (char*)PyUnicode_1BYTE_DATA(name);
//printf("DATA=%s\n",data);
if (data != NULL && !strcmp(data,"Union")) {
PyObject* new_cls = PyObject_GetAttrString(cls, "__args__");
if (new_cls != NULL) {
cls = new_cls;
}
}
Py_DECREF(name);
}
Py_DECREF(origin);
}
return cls;
}
I can't use PyImport_ImportModule("typing") because of infinite recursivity.
One version of type_or (__or__) use the import.
static PyObject *
type_or(PyTypeObject* self, PyObject* param) {
PyObject* typing=PyImport_ImportModule("typing");
PyTypeObject* genericAlias =
(PyTypeObject*)PyObject_GetAttrString(typing,"_GenericAlias");
// Check param is a PyType or GenericAlias
if ((param == NULL) ||
(
(param != Py_None) &&
! PyType_IsSubtype(genericAlias, Py_TYPE(param)) &&
(PyObject_IsInstance(param, (PyObject *) &PyType_Type) != 1)
)
) {
PyErr_SetString(PyExc_TypeError, "'type' expected");
Py_DECREF(genericAlias);
Py_DECREF(typing);
return NULL;
}
// 1. Create a tuple with types
PyObject *tuple=PyTuple_Pack(2,self, param);
// 2. Create Union with tuple
PyObject* unionType = PyObject_GetAttrString(typing,"Union");
PyObject *newUnion=PyObject_GetItem(unionType, tuple);
// 3. Clean memory
Py_DECREF(genericAlias);
Py_DECREF(typing);
Py_DECREF(unionType);
Py_DECREF(tuple);
// 4. Return instance
return newUnion;
It's may be acceptable, but I'm not sure of that.
Philippe
Le mar. 8 oct. 2019 à 18:25, Guido van Rossum <[email protected]> a écrit :
> That would mean that all of typing will be imported as part of startup,
> and that module is too heavy for that. Also it might end up on recursion.
>
> On Tue, Oct 8, 2019 at 09:06 Brandt Bucher <[email protected]> wrote:
>
>> I’m a bit confused. For my own understanding: what’s stopping
>> PyObject_IsInstance/PyObject_IsSubclass from just trying
>> PyImport_GetModule("typing") here?
>>
>> If NULL, carry on. Otherwise, check the Union case.
>>
>> Brandt
>>
>> On Oct 8, 2019, at 05:44, Philippe Prados <[email protected]>
>> wrote:
>>
>>
>>
>> Glups.
>>
>> I am not an expert of Pyhton source code. May be after this patch ;-)
>>
>> I think I should discuss with the authors of the module typing, to
>> identify the best strategy.
>> Who is he ?
>>
>> Philippe
>>
>>
>> Le mar. 8 oct. 2019 à 10:19, Ivan Levkivskyi <[email protected]> a
>> écrit :
>>
>>> You will need to rewrite most of things in C.
>>>
>>> --
>>> Ivan
>>>
>>>
>>> On Tue 8 Oct 2019, 08:53 Philippe Prados, <[email protected]>
>>> wrote:
>>>
>>>> Ok,
>>>>
>>>> But _GenericAlias and dependencies are written with Python
>>>> (Lib/typing.py), not with C.
>>>> So, I must rewrite the _GenericAlias in C or it's possible to merge the
>>>> C and Python in builtin and add a direct reference to _GenericAlias with C,
>>>> and add the reference in builtin module ?
>>>>
>>>> Philippe
>>>>
>>>>
>>>> Le lun. 7 oct. 2019 à 22:58, Random832 <[email protected]> a
>>>> écrit :
>>>>
>>>>> On Mon, Oct 7, 2019, at 12:02, Philippe Prados wrote:
>>>>> > Because this PEP propose to accept, for all classes
>>>>> > assert isinstance("", int | str)
>>>>> > assert issubclass(int, int | str)
>>>>> > and add an operator __or__() for type type.
>>>>> > def f(list: List[int | str], param: int | None) -> float | str:
>>>>> > pass
>>>>>
>>>>> Oh, sorry, I didn't realize that this also included the | operator, I
>>>>> thought this was just for isinstance("", Union[int, str]).
>>>>>
>>>> _______________________________________________
>>>> Python-Dev mailing list -- [email protected]
>>>> To unsubscribe send an email to [email protected]
>>>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>>>> Message archived at
>>>> https://mail.python.org/archives/list/[email protected]/message/GD7WXPD26VUPMZT6WAATCJJBB42DDYYQ/
>>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>>
>>> _______________________________________________
>> Python-Dev mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]
>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>>
>> Message archived at
>> https://mail.python.org/archives/list/[email protected]/message/4K7WZ3RBGG7K6E6XK65MS44VQYZIKQS2/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>> _______________________________________________
>> Python-Dev mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]
>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/[email protected]/message/RYGHVWJZT76GNDWNRSOLA74SHZFNDW42/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> --
> --Guido (mobile)
>
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/IOFI5TMPSDBXTD5B4S3SJUE2CTHQGYOX/
Code of Conduct: http://python.org/psf/codeofconduct/