(original) (raw)



On Sat, Mar 3, 2012 at 03:08, Stefan Krah <stefan@bytereef.org> wrote:

Stefan Behnel <stefan\_ml@behnel.de> wrote:
> > 1\. assert() is the wrong tool for this job
>
> Absolutely.

I disagree. This assert() is meant for extension authors and not end users. I
can't see how a reasonable release procedure would fail to trigger the assert().

My procedure as a C extension author is to test against a new Python version
and \*then\* set the PyPI classifier for that version.

Do you test against pydebug builds of Python, or otherwise a build that actually enables asserts? Because I suspect most people don't, so they don't trigger the assert. Python is normally (that is, a release build on Windows or a regular, non-pydebug build on the rest) built without asserts. Asserts are disabled by the NDEBUG symbol, which Python passes for regular builds.

Even that aside, asserts are for internal invariants, not external ones. You can use asserts in your extension module to check that your own code is passing what you think it should pass, but you shouldn't really use them to check that a library or API you use is, and Python certainly shouldn't be using it to check what code outside of the core is giving it. Aborting (which is what failed asserts do) is just not the right thing to do.



If I download a C extension that doesn't have the 3.3 classifier set,
then as a user I would not be upset if the extension throws an assert or,
as Thomas Wouters pointed out, continues to work as before if not compiled
in debug mode.



> > 2\. the current check is too strict (it should just check for obj !=
> > NULL, not obj == &exporter)
>
> I don't know. The documentation isn't very clear on the cases where obj may
> be NULL. Definitely on error, ok, but otherwise, the bf\_getbuffer() docs do
> not explicitly say that it must not be NULL (they just mention a "standard"
> case):
>
> http://docs.python.org/dev/c-api/typeobj.html#buffer-object-structures

How about this:

"The value of view.obj is the equivalent of the return value of any C-API
function that returns a new reference. The value must be NULL on error
or a valid new reference to an exporting object.

For a chain or a tree of views, there are two possible schemes:

1) Re-export: Each member of the tree pretends to be the exporting
object and sets view.obj to a new reference to itself.

2) Redirect: The buffer request is redirected to the root object
of the tree. Here view.obj will be a reference to the root object."



I think it's better not to complicate this familiar scheme of owning
a reference by allowing view.obj==NULL for the general case.


view.obj==NULL was introduced for temporary wrapping of ad-hoc memoryviews
via PyBuffer\_FillInfo() and now also PyMemoryView\_FromMemory().

That's why I explicitly wrote the following in the documentation of
PyBuffer\_FillInfo():

"If this function is used as part of a getbufferproc, exporter MUST be
set to the exporting object. Otherwise, exporter MUST be NULL."


Stefan Krah



\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/thomas%40python.org



--
Thomas Wouters <thomas@python.org>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!