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 <gu...@python.org> 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 <brandtbuc...@gmail.com> 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 <philippe.pra...@gmail.com> >> 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 <levkivs...@gmail.com> a >> écrit : >> >>> You will need to rewrite most of things in C. >>> >>> -- >>> Ivan >>> >>> >>> On Tue 8 Oct 2019, 08:53 Philippe Prados, <philippe.pra...@gmail.com> >>> 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 <random...@fastmail.com> 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 -- python-dev@python.org >>>> To unsubscribe send an email to python-dev-le...@python.org >>>> https://mail.python.org/mailman3/lists/python-dev.python.org/ >>>> Message archived at >>>> https://mail.python.org/archives/list/python-dev@python.org/message/GD7WXPD26VUPMZT6WAATCJJBB42DDYYQ/ >>>> Code of Conduct: http://python.org/psf/codeofconduct/ >>>> >>> _______________________________________________ >> Python-Dev mailing list -- python-dev@python.org >> To unsubscribe send an email to python-dev-le...@python.org >> https://mail.python.org/mailman3/lists/python-dev.python.org/ >> >> Message archived at >> https://mail.python.org/archives/list/python-dev@python.org/message/4K7WZ3RBGG7K6E6XK65MS44VQYZIKQS2/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> >> _______________________________________________ >> Python-Dev mailing list -- python-dev@python.org >> To unsubscribe send an email to python-dev-le...@python.org >> https://mail.python.org/mailman3/lists/python-dev.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-dev@python.org/message/RYGHVWJZT76GNDWNRSOLA74SHZFNDW42/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > -- > --Guido (mobile) >
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/IOFI5TMPSDBXTD5B4S3SJUE2CTHQGYOX/ Code of Conduct: http://python.org/psf/codeofconduct/