Can someone else with a reasonable understanding of the type machinery in
CPython help Philippe? IMO the entire _GenericAlias class that's currently
implemented in Python in typing.py needs to be reimplemented in C.

However for a prototype (to show how other aspects of the proposal will
look) it is probably fine to import the implementation from typing.py.

Remember the ultimate goal is to be able to write int|str (or e.g.
str|list[str], assuming PEP 585 makes it too) and receive an object that
knows it represents a union and has an __args__ attribute that's a tuple of
the arguments of the | operator. A few other things too (__origin__,
__parameters__). It's possible that this doesn't need the full generality
of _GenericAlias (which is used for some other purposes too) but it should
definitely be usable for unions.

On Wed, Oct 9, 2019 at 12:45 AM Philippe Prados <philippe.pra...@gmail.com>
wrote:

> 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)
>>
>

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
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/H2T37NNUPLPMPAXKXSABPOZ5K6F7CXSM/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to