Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

"Jesus may love you, but I think you're garbage wrapped in skin." -- Michael O'Donohugh


devel / comp.lang.python / Re: Defining a Python enum in a C extension - am I doing this right?

SubjectAuthor
* Re: Defining a Python enum in a C extension - am I doing this right?Bartosz Golaszewski
`- Re: Defining a Python enum in a C extension - am I doing this right?Sean DiZazzo

1
Re: Defining a Python enum in a C extension - am I doing this right?

<mailman.307.1627985039.4164.python-list@python.org>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=18813&group=comp.lang.python#18813

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: brgl@bgdev.pl (Bartosz Golaszewski)
Newsgroups: comp.lang.python
Subject: Re: Defining a Python enum in a C extension - am I doing this right?
Date: Tue, 3 Aug 2021 12:03:47 +0200
Lines: 166
Message-ID: <mailman.307.1627985039.4164.python-list@python.org>
References: <CAMRc=MehhhAGOt=u3qpYzHRhgqpeStew30qiLRNoA5mScgf=PA@mail.gmail.com>
<se0cqh$13ol$1@ciao.gmane.io>
<CAMRc=MeZtzZuotXL8SUZ=G68HYV4ogbXg9bvFayY3RpHZeM71Q@mail.gmail.com>
<CAMRc=MfUQswzi2Xpwrp69T8B7yDYiNOnT8iwft9C+Dn7hi_4qw@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de Skx5WcYnn1pwbKRIePOQQwSF3nBnD3Vr2JL7E5aWr/WQ==
Return-Path: <brgl@bgdev.pl>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=bgdev-pl.20150623.gappssmtp.com
header.i=@bgdev-pl.20150623.gappssmtp.com
header.b=lX/qLlw7; dkim-adsp=unknown (unprotected policy);
dkim-atps=neutral
X-Spam-Status: OK 0.000
X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'this:': 0.03; 'jul': 0.04;
'31,': 0.05; 'string': 0.05; "'''": 0.09; 'cc:addr:python-list':
0.09; 'code?': 0.09; 'const': 0.09; 'int': 0.09; 'subject:Python':
0.12; 'import': 0.14; '#include': 0.16; 'bart': 0.16;
'cc:name:python': 0.16; 'char': 0.16; 'expose': 0.16; 'follow-
up:': 0.16; 'mean:': 0.16; 'nested': 0.16; 'sounds': 0.16;
'static': 0.16; 'subject:extension': 0.16;
'\xd0\xbf\xd0\xb8\xd1\x88\xd0\xb5:': 0.16; 'wrote:': 0.16;
'python': 0.16; 'pull': 0.18; 'cc:addr:python.org': 0.19;
'python,': 0.21; 'fri,': 0.23; 'sat,': 0.23; 'extension': 0.24;
'code': 0.24; 'skip:p 30': 0.26; 'cc:2**0': 0.27; '(as': 0.27;
"i'll": 0.28; 'module': 0.28; 'think': 0.31; 'code,': 0.31; "i'm":
0.32; 'message-id:@mail.gmail.com': 0.33; 'class': 0.33; 'skip:"
20': 0.33; 'header:In-Reply-To:1': 0.33; 'received:google.com':
0.34; 'bar': 0.35; 'received:209.85.208': 0.36; 'able': 0.36;
'received:209.85': 0.38; 'received:209': 0.38; 'skip:e 10': 0.60;
'subject:this': 0.63; 'your': 0.64; 'resulting': 0.68; 'skip:*
10': 0.73; 'skip:f 20': 0.76; '2021': 0.84; '-1;': 0.84;
'bartosz': 0.84; 'null;': 0.84
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=bgdev-pl.20150623.gappssmtp.com; s=20150623;
h=mime-version:references:in-reply-to:from:date:message-id:subject:to
:cc:content-transfer-encoding;
bh=0H0R7ie5cG5f3OKmNXaC0zVAjdzyijKv/LV8dninfVo=;
b=lX/qLlw7cqkugu8zzIHL44YSC0TPT6ENTA9tunBNwL147O0Z5afhZKxghfF/VgIshD
JdiNYSb8StHeLMIO+SA/EesmJWhiEgr5c/+cGnw8QPtrFTaUmd4HmRWPUTjVG5jrTJHI
NpDysxo0O9gw3tI54gqOSg7w3491f1NufnPy5KEVPiH0HlcsoKgsE73kha907FSEUrkL
AAcRgLN1qZ2XUx06fDZUOEZewh8SrHsdSJTZArOPM+pM9GzqnZXaCC6gBXpwt0mSWeKB
4OFFEUHxAMTz1kxFJyQ3h6w2pJgPQ/f5RjdNejecYqhhA/sGxFywB7n6QTRbbyfcDnd8
J+Bg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20161025;
h=x-gm-message-state:mime-version:references:in-reply-to:from:date
:message-id:subject:to:cc:content-transfer-encoding;
bh=0H0R7ie5cG5f3OKmNXaC0zVAjdzyijKv/LV8dninfVo=;
b=lhqaThg+rmeZBQyEGAa4WhMgSbT1v4MPbYa01f82UFxuocULj6uByWArEbEYcdBkom
npbfIDSzNpX8QdldhfppJXPDqd9xIppApcuT/x+SVUBkdhaX+Y0tP7OEeJcb6SZN+KXg
pbvgCegc4wytXIiWuu0ak0AVA5Wz84Ux+tJJrr2xage+nHAzD0XQzRiTXAzmv2kbk6xn
59+VkfNu0+/pcmanOx3TWK98aVTn0CpUkInJMpvAnmCUytjIxGmzEvdba1CyAa7cFqoZ
2LsPlVwE5xu/A4cc6e3iM46yFfj88bFV9HAc82+Q0fgAPqkdXHBl5ID2viXJAgjkYbo0
9p/Q==
X-Gm-Message-State: AOAM530Mp58wqwV66vLATBsUpHvL2+HvkO3uytYtVkwVPxk1hM/wNgGG
N66Nkl4TEXn92GAj0TtBYda91TKD9V7fdwvxuSCGJw==
X-Google-Smtp-Source: ABdhPJwHi9VoVNaPk0nzjq+tc76B0r3SZ1xjabGOdRQRUQjBaLosH88VCDN7iSW6/WY3tJIN3w0hAo7AyXqpd1Bzk5I=
X-Received: by 2002:a05:6402:1a3a:: with SMTP id
be26mr24281444edb.232.1627985037814;
Tue, 03 Aug 2021 03:03:57 -0700 (PDT)
In-Reply-To: <CAMRc=MeZtzZuotXL8SUZ=G68HYV4ogbXg9bvFayY3RpHZeM71Q@mail.gmail.com>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CAMRc=MfUQswzi2Xpwrp69T8B7yDYiNOnT8iwft9C+Dn7hi_4qw@mail.gmail.com>
X-Mailman-Original-References: <CAMRc=MehhhAGOt=u3qpYzHRhgqpeStew30qiLRNoA5mScgf=PA@mail.gmail.com>
<se0cqh$13ol$1@ciao.gmane.io>
<CAMRc=MeZtzZuotXL8SUZ=G68HYV4ogbXg9bvFayY3RpHZeM71Q@mail.gmail.com>
 by: Bartosz Golaszewski - Tue, 3 Aug 2021 10:03 UTC

On Sat, Jul 31, 2021 at 3:01 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> On Fri, Jul 30, 2021 at 2:41 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
> >
> > 23.07.21 11:20, Bartosz Golaszewski пише:
> > > I'm working on a Python C extension and I would like to expose a
> > > custom enum (as in: a class inheriting from enum.Enum) that would be
> > > entirely defined in C.
> >
> > I think that it would be much easier to define it in Python, and then
> > either import a Python module in your C code, or exec a Python code as a
> > string.
> >
>
> You mean: evaluate a string like this:
>
> '''
> import enum
>
> class FooBar(enum.Enum):
> FOO = 1
> BAR = 2
> BAZ = 3
> '''
>
> And then pull in the FooBar type from the resulting dictionary into my
> C code? Sounds good actually. I think I'll be able to add the FooBar
> type to another type's tp_dict too - because some enums I want to
> create will be nested in other classes.
>
> Bart

Just a follow-up: this is how I did it eventually:

```
#include <Python.h>

typedef struct {
PyObject_HEAD;
} dummy_object;

PyDoc_STRVAR(dummy_type_doc, "Dummy type in which the enum will be nested.");

static PyTypeObject dummy_type = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "pycenum.DummyType",
.tp_basicsize = sizeof(dummy_object),
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_doc = dummy_type_doc,
.tp_new = PyType_GenericNew,
.tp_dealloc = (destructor)PyObject_Del,
};

PyDoc_STRVAR(module_doc,
"C extension module defining a class inheriting from enum.Enum.");

static PyModuleDef module_def = {
PyModuleDef_HEAD_INIT,
.m_name = "pycenum",
.m_doc = module_doc,
.m_size = -1,
};

static int add_foobar_enum(PyObject *module)
{ static const char *foobar_src "class FooBar(enum.Enum):\n"
" FOO = 1\n"
" BAR = 2\n"
" BAZ = 3\n";

PyObject *main_mod, *main_dict, *enum_mod, *result, *foobar_type;
int ret;

main_mod = PyImport_AddModule("__main__");
if (!main_mod)
return -1;

main_dict = PyModule_GetDict(main_mod);
if (!main_dict) {
Py_DECREF(main_mod);
return -1;
}

enum_mod = PyImport_ImportModule("enum");
if (!enum_mod) {
Py_DECREF(main_mod);
return -1;
}

ret = PyDict_SetItemString(main_dict, "enum", enum_mod);
Py_DECREF(enum_mod);
if (ret) {
Py_DECREF(main_mod);
return -1;
}

result = PyRun_String(foobar_src, Py_single_input,
main_dict, main_dict);
if (!result) {
Py_DECREF(main_mod);
return -1;
}

foobar_type = PyDict_GetItemString(main_dict, "FooBar");
if (!foobar_type) {
Py_DECREF(main_mod);
return -1;
}

ret = PyDict_SetItemString(dummy_type.tp_dict, "FooBar", foobar_type);
Py_DECREF(foobar_type);
Py_DECREF(main_mod);
if (ret)
return -1;

PyType_Modified(&dummy_type);

return ret;
}

PyMODINIT_FUNC PyInit_pycenum(void)
{ PyObject *module;
int ret;

module = PyModule_Create(&module_def);
if (!module)
return NULL;

ret = PyModule_AddStringConstant(module, "__version__", "0.0.1");
if (ret) {
Py_DECREF(module);
return NULL;
}

ret = PyType_Ready(&dummy_type);
if (ret) {
Py_DECREF(module);
return NULL;
}

ret = add_foobar_enum(module);
if (ret) {
Py_DECREF(module);
return NULL;
}

Py_INCREF(&dummy_type);
ret = PyModule_AddObject(module, "DummyType", (PyObject *)&dummy_type);
if (ret) {
Py_DECREF(&dummy_type);
Py_DECREF(module);
return NULL;
}

return module;
} ```

Bart

Re: Defining a Python enum in a C extension - am I doing this right?

<4a5d5824-b47d-4d4c-9cc6-026ddac0808bn@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=18830&group=comp.lang.python#18830

  copy link   Newsgroups: comp.lang.python
X-Received: by 2002:a05:6214:29cb:: with SMTP id gh11mr24334866qvb.55.1628043882243;
Tue, 03 Aug 2021 19:24:42 -0700 (PDT)
X-Received: by 2002:a05:6214:14e6:: with SMTP id k6mr22053411qvw.53.1628043882040;
Tue, 03 Aug 2021 19:24:42 -0700 (PDT)
Path: i2pn2.org!i2pn.org!paganini.bofh.team!usenet.pasdenom.info!usenet-fr.net!proxad.net!feeder1-2.proxad.net!209.85.160.216.MISMATCH!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.python
Date: Tue, 3 Aug 2021 19:24:41 -0700 (PDT)
In-Reply-To: <mailman.307.1627985039.4164.python-list@python.org>
Injection-Info: google-groups.googlegroups.com; posting-host=107.184.139.178; posting-account=VwOTGAoAAABdvSJ32UwWkHul6J-TC6KW
NNTP-Posting-Host: 107.184.139.178
References: <CAMRc=MehhhAGOt=u3qpYzHRhgqpeStew30qiLRNoA5mScgf=PA@mail.gmail.com>
<se0cqh$13ol$1@ciao.gmane.io> <CAMRc=MfUQswzi2Xpwrp69T8B7yDYiNOnT8iwft9C+Dn7hi_4qw@mail.gmail.com>
<CAMRc=MeZtzZuotXL8SUZ=G68HYV4ogbXg9bvFayY3RpHZeM71Q@mail.gmail.com> <mailman.307.1627985039.4164.python-list@python.org>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <4a5d5824-b47d-4d4c-9cc6-026ddac0808bn@googlegroups.com>
Subject: Re: Defining a Python enum in a C extension - am I doing this right?
From: sean.dizazzo@gmail.com (Sean DiZazzo)
Injection-Date: Wed, 04 Aug 2021 02:24:42 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
 by: Sean DiZazzo - Wed, 4 Aug 2021 02:24 UTC

On Tuesday, August 3, 2021 at 3:04:19 AM UTC-7, Bartosz Golaszewski wrote:
> On Sat, Jul 31, 2021 at 3:01 PM Bartosz Golaszewski <br...@bgdev.pl> wrote:
> >
> > On Fri, Jul 30, 2021 at 2:41 PM Serhiy Storchaka <stor...@gmail.com> wrote:
> > >
> > > 23.07.21 11:20, Bartosz Golaszewski пише:
> > > > I'm working on a Python C extension and I would like to expose a
> > > > custom enum (as in: a class inheriting from enum.Enum) that would be
> > > > entirely defined in C.
> > >
> > > I think that it would be much easier to define it in Python, and then
> > > either import a Python module in your C code, or exec a Python code as a
> > > string.
> > >
> >
> > You mean: evaluate a string like this:
> >
> > '''
> > import enum
> >
> > class FooBar(enum.Enum):
> > FOO = 1
> > BAR = 2
> > BAZ = 3
> > '''
> >
> > And then pull in the FooBar type from the resulting dictionary into my
> > C code? Sounds good actually. I think I'll be able to add the FooBar
> > type to another type's tp_dict too - because some enums I want to
> > create will be nested in other classes.
> >
> > Bart
> Just a follow-up: this is how I did it eventually:
>
> ```
> #include <Python.h>
>
> typedef struct {
> PyObject_HEAD;
> } dummy_object;
>
> PyDoc_STRVAR(dummy_type_doc, "Dummy type in which the enum will be nested..");
>
> static PyTypeObject dummy_type = {
> PyVarObject_HEAD_INIT(NULL, 0)
> .tp_name = "pycenum.DummyType",
> .tp_basicsize = sizeof(dummy_object),
> .tp_flags = Py_TPFLAGS_DEFAULT,
> .tp_doc = dummy_type_doc,
> .tp_new = PyType_GenericNew,
> .tp_dealloc = (destructor)PyObject_Del,
> };
> PyDoc_STRVAR(module_doc,
> "C extension module defining a class inheriting from enum.Enum.");
>
> static PyModuleDef module_def = {
> PyModuleDef_HEAD_INIT,
> .m_name = "pycenum",
> .m_doc = module_doc,
> .m_size = -1,
> };
> static int add_foobar_enum(PyObject *module)
> {
> static const char *foobar_src =
> "class FooBar(enum.Enum):\n"
> " FOO = 1\n"
> " BAR = 2\n"
> " BAZ = 3\n";
>
> PyObject *main_mod, *main_dict, *enum_mod, *result, *foobar_type;
> int ret;
>
> main_mod = PyImport_AddModule("__main__");
> if (!main_mod)
> return -1;
>
> main_dict = PyModule_GetDict(main_mod);
> if (!main_dict) {
> Py_DECREF(main_mod);
> return -1;
> }
>
> enum_mod = PyImport_ImportModule("enum");
> if (!enum_mod) {
> Py_DECREF(main_mod);
> return -1;
> }
>
> ret = PyDict_SetItemString(main_dict, "enum", enum_mod);
> Py_DECREF(enum_mod);
> if (ret) {
> Py_DECREF(main_mod);
> return -1;
> }
>
> result = PyRun_String(foobar_src, Py_single_input,
> main_dict, main_dict);
> if (!result) {
> Py_DECREF(main_mod);
> return -1;
> }
>
> foobar_type = PyDict_GetItemString(main_dict, "FooBar");
> if (!foobar_type) {
> Py_DECREF(main_mod);
> return -1;
> }
>
> ret = PyDict_SetItemString(dummy_type.tp_dict, "FooBar", foobar_type);
> Py_DECREF(foobar_type);
> Py_DECREF(main_mod);
> if (ret)
> return -1;
>
> PyType_Modified(&dummy_type);
>
> return ret;
> }
>
> PyMODINIT_FUNC PyInit_pycenum(void)
> {
> PyObject *module;
> int ret;
>
> module = PyModule_Create(&module_def);
> if (!module)
> return NULL;
>
> ret = PyModule_AddStringConstant(module, "__version__", "0.0.1");
> if (ret) {
> Py_DECREF(module);
> return NULL;
> }
>
> ret = PyType_Ready(&dummy_type);
> if (ret) {
> Py_DECREF(module);
> return NULL;
> }
>
> ret = add_foobar_enum(module);
> if (ret) {
> Py_DECREF(module);
> return NULL;
> }
>
> Py_INCREF(&dummy_type);
> ret = PyModule_AddObject(module, "DummyType", (PyObject *)&dummy_type);
> if (ret) {
> Py_DECREF(&dummy_type);
> Py_DECREF(module);
> return NULL;
> }
>
> return module;
> }
> ```
>
> Bart
No


devel / comp.lang.python / Re: Defining a Python enum in a C extension - am I doing this right?

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor