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/

Reply via email to