Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-39481: WIP: PEP 585 #18239

Open
wants to merge 20 commits into
base: master
from
Open

bpo-39481: WIP: PEP 585 #18239

wants to merge 20 commits into from

Conversation

@gvanrossum
Copy link
Member

gvanrossum commented Jan 28, 2020

@gvanrossum gvanrossum requested a review from serhiy-storchaka Jan 28, 2020
@gvanrossum gvanrossum requested review from methane and rhettinger as code owners Jan 28, 2020
@gvanrossum gvanrossum removed the request for review from rhettinger Jan 28, 2020
Objects/descrobject.c Outdated Show resolved Hide resolved
Objects/descrobject.c Outdated Show resolved Hide resolved
Objects/descrobject.c Outdated Show resolved Hide resolved
Objects/descrobject.c Outdated Show resolved Hide resolved
};

static PyMemberDef ga_members[] = {
{"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},

This comment has been minimized.

Copy link
@serhiy-storchaka

serhiy-storchaka Jan 28, 2020

Member

Maybe T_OBJECT_EX?

This comment has been minimized.

Copy link
@gvanrossum

gvanrossum Jan 28, 2020

Author Member

I think not. The two attributes should never be allowed to be NULL. (This is a change from an earlier design.)

Objects/descrobject.c Outdated Show resolved Hide resolved
static PyObject *
ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
if (kwds != NULL) {

This comment has been minimized.

Copy link
@serhiy-storchaka

serhiy-storchaka Jan 28, 2020

Member

It is worth to use Argument Clinic which generates simpler code using non-public C API similar to the following:

if (!_PyArg_NoKeywords("GenericAlias", kwds) ||
    !_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 2))
{
    return NULL;
}
Objects/descrobject.c Outdated Show resolved Hide resolved
Objects/descrobject.c Outdated Show resolved Hide resolved
};

static PyObject *
ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

This comment has been minimized.

Copy link
@serhiy-storchaka

serhiy-storchaka Jan 28, 2020

Member

Do we need a __new__ method? Why not set tp_new = NULL?

This comment has been minimized.

Copy link
@gvanrossum

gvanrossum Jan 28, 2020

Author Member

I first had a tp_init. Then calling GenericAlias() somehow worked and produced an object with NULL attributes (or maybe it was some more clever incantation, I forget, but I definitely saw it). I do want the class instantiable from Python (so it can potentially be used from typing.py). Using tp_new instead solved that problem.

@gvanrossum gvanrossum changed the title WIP: PEP 585 bpo-39481: WIP: PEP 585 Jan 28, 2020
blurb-it bot and others added 6 commits Jan 28, 2020
By Ethan Smith.
Also strengthen test for repr(MyList[int])
Note that UserDict and UserList are now generic
@gvanrossum

This comment has been minimized.

Copy link
Member Author

gvanrossum commented Jan 29, 2020

So I'm looking into the test failures. I've fixed two simple ones, but now I'm stuck with at least two:

  • test_typing.py, see below
  • test_genericalias.py (i.e. the very PEP 585 test) crashes on Ubuntu, but not for me locally

The problem with test_typing.py is that when we have a class that derives from Tuple[xxx], like so:

from typing import Tuple
class C(Tuple[int]): pass
print(C.mro())  # C, tuple, typing.Generic, object

its MRO contains tuple before Generic, and the new tuple.__class_getitem__ shadows the intended Generic.__class_getitem__. I'm not sure what to do about this. @ambv @ilevkivskyi @serhiy-storchaka

@gvanrossum

This comment has been minimized.

Copy link
Member Author

gvanrossum commented Jan 29, 2020

Using a debug build I can repro the test_genericalias.py crash. The upper few lines of the stack trace are:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007fff72e217fa libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff72edebc1 libsystem_pthread.dylib`pthread_kill + 432
    frame #2: 0x00007fff72da8a1c libsystem_c.dylib`abort + 120
    frame #3: 0x00007fff72da7cd6 libsystem_c.dylib`__assert_rtn + 314
    frame #4: 0x00000001000df936 python.exe`_PyType_Lookup(type=0x0000000100401d30, name=0x00000001035f1d60) at typeobject.c:3155:5
    frame #5: 0x00000001000c0b8f python.exe`_PyObject_GenericGetAttrWithDict(obj=0x0000000100401ec8, name=0x00000001035f1d60, dict=0x0000000000000000, suppress=0) at object.c:1319:13
    frame #6: 0x00000001000c0ab3 python.exe`PyObject_GenericGetAttr(obj=0x0000000100401ec8, name=0x00000001035f1d60) at object.c:1407:12
    frame #7: 0x00000001000c0268 python.exe`PyObject_GetAttr(v=0x0000000100401ec8, name=0x00000001035f1d60) at object.c:1013:16
    frame #8: 0x00000001000c01a4 python.exe`PyObject_GetAttrString(v=0x0000000100401ec8, name="__module__") at object.c:918:11
    frame #9: 0x0000000100056154 python.exe`ga_repr_item(writer=0x00007ffeefbe9078, p=0x0000000100401ec8) at descrobject.c:1828:24
    frame #10: 0x0000000100054015 python.exe`ga_repr(self=0x00000001040349b0) at descrobject.c:1890:13
    frame #11: 0x00000001000beefb python.exe`PyObject_Repr(v=0x00000001040349b0) at object.c:543:11
    frame #12: 0x00000001001e9d49 python.exe`builtin_repr(module=0x0000000101221dd0, obj=0x00000001040349b0) at bltinmodule.c:2141:12

@ethanhs does this give you a clue? Methinks there's a refcount bug in ga_repr(). :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.