[Python-Dev] Py_SIZE vs PyXXX_GET_SIZE
What is the preferable way of getting the size of tuple, list, bytes, bytearray: Py_SIZE or PyTuple_GET_SIZE, PyList_GET_SIZE, PyBytes_GET_SIZE, PyByteArray_GET_SIZE? Are macros for concrete types more preferable or they are outdated? On one hand concrete type macros are longer than Py_SIZE, and since concrete type macros are defined not for all PyVarObject types we need to use Py_SIZE for them in any case (for example for PyLongObject and PyTypeObject). On other hand we can add asserts for checking that concrete type macros are used with correct types. When I wrote a patch that replaces Py_SIZE with concrete type macros I found two cases of misusing Py_SIZE with dict object: one in _json.c (already fixed in 3023ebb43f7607584c3e123aff56e867cb04a418) and other in dictobject.c (still not fixed). If prefer using concrete type macros this would unlikely happen. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] PEP 544: Protocols
Hi all, PEP 484 specifies semantics for type hints. These type hints are used by various tools, including static type checkers. However, PEP 484 only specifies the semantics for nominal subtyping (subtyping based on subclassing). Here we propose a specification for semantics of structural subtyping (static duck typing). Previous discussions on this PEP happened at: https://mail.python.org/pipermail/python-ideas/2015-September/thread.html#35859 https://github.com/python/typing/issues/11 https://github.com/python/peps/pull/224 -- Ivan === PEP: 544 Title: Protocols Version: $Revision$ Last-Modified: $Date$ Author: Ivan Levkivskyi , Jukka Lehtosalo < [email protected]>, Łukasz Langa Discussions-To: Python-Dev Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 05-Mar-2017 Python-Version: 3.7 Abstract Type hints introduced in PEP 484 can be used to specify type metadata for static type checkers and other third party tools. However, PEP 484 only specifies the semantics of *nominal* subtyping. In this PEP we specify static and runtime semantics of protocol classes that will provide a support for *structural* subtyping (static duck typing). .. _rationale: Rationale and Goals === Currently, PEP 484 and the ``typing`` module [typing]_ define abstract base classes for several common Python protocols such as ``Iterable`` and ``Sized``. The problem with them is that a class has to be explicitly marked to support them, which is unpythonic and unlike what one would normally do in idiomatic dynamically typed Python code. For example, this conforms to PEP 484:: from typing import Sized, Iterable, Iterator class Bucket(Sized, Iterable[int]): ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[int]: ... The same problem appears with user-defined ABCs: they must be explicitly subclassed or registered. This is particularly difficult to do with library types as the type objects may be hidden deep in the implementation of the library. Also, extensive use of ABCs might impose additional runtime costs. The intention of this PEP is to solve all these problems by allowing users to write the above code without explicit base classes in the class definition, allowing ``Bucket`` to be implicitly considered a subtype of both ``Sized`` and ``Iterable[int]`` by static type checkers using structural [wiki-structural]_ subtyping:: from typing import Iterator, Iterable class Bucket: ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[int]: ... def collect(items: Iterable[int]) -> int: ... result: int = collect(Bucket()) # Passes type check Note that ABCs in ``typing`` module already provide structural behavior at runtime, ``isinstance(Bucket(), Iterable)`` returns ``True``. The main goal of this proposal is to support such behavior statically. The same functionality will be provided for user-defined protocols, as specified below. The above code with a protocol class matches common Python conventions much better. It is also automatically extensible and works with additional, unrelated classes that happen to implement the required protocol. Nominal vs structural subtyping --- Structural subtyping is natural for Python programmers since it matches the runtime semantics of duck typing: an object that has certain properties is treated independently of its actual runtime class. However, as discussed in PEP 483, both nominal and structural subtyping have their strengths and weaknesses. Therefore, in this PEP we *do not propose* to replace the nominal subtyping described by PEP 484 with structural subtyping completely. Instead, protocol classes as specified in this PEP complement normal classes, and users are free to choose where to apply a particular solution. See section on `rejected`_ ideas at the end of this PEP for additional motivation. Non-goals - At runtime, protocol classes will be simple ABCs. There is no intent to provide sophisticated runtime instance and class checks against protocol classes. This would be difficult and error-prone and will contradict the logic of PEP 484. As well, following PEP 484 and PEP 526 we state that protocols are **completely optional**: * No runtime semantics will be imposed for variables or parameters annotated with a protocol class. * Any checks will be performed only by third-party type checkers and other tools. * Programmers are free to not use them even if they use type annotations. * There is no intent to make protocols non-optional in the future. Existing Approaches to Structural Subtyping === Before describing the actual specification, we review and comment on existing approaches related to structural subtyping in Python and other languages: * ``zope.interface`` [zope-interfaces]_ was one of the first widely used approaches to st
Re: [Python-Dev] Py_SIZE vs PyXXX_GET_SIZE
On Mon, 20 Mar 2017 at 04:28 Serhiy Storchaka wrote: > What is the preferable way of getting the size of tuple, list, bytes, > bytearray: Py_SIZE or PyTuple_GET_SIZE, PyList_GET_SIZE, > PyBytes_GET_SIZE, PyByteArray_GET_SIZE? Are macros for concrete types > more preferable or they are outdated? > > On one hand concrete type macros are longer than Py_SIZE, and since > concrete type macros are defined not for all PyVarObject types we need > to use Py_SIZE for them in any case (for example for PyLongObject and > PyTypeObject). > > On other hand we can add asserts for checking that concrete type macros > are used with correct types. When I wrote a patch that replaces Py_SIZE > with concrete type macros I found two cases of misusing Py_SIZE with > dict object: one in _json.c (already fixed in > 3023ebb43f7607584c3e123aff56e867cb04a418) and other in dictobject.c > (still not fixed). If prefer using concrete type macros this would > unlikely happen. > Personally I have always used the concrete versions when available when it doesn't forcibly constrain the input to the function. In other words I wouldn't force a function to only take a list so I could use PyList_GET_SIZE, but if I'm constructing some internal list object or a function is defined to return a list already then I would just use the concrete versions. But I also wouldn't worry about changing uses of Py_SIZE unless I was already changing the surrounding code. I guess we could clarify this in PEP 7 if it doesn't say when to care about this and once we reach consensus on what we all prefer. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] __del__ is not called after creating a new reference
Hello,
I already tried to ask on python-list, see
https://mail.python.org/pipermail/python-list/2017-March/720037.html
but it seems that this list is not for technical questions.
Let me resend my question to python-dev. Please tell me if I should not spam
this list with newbiesh questions, and thanks in advance.
---
I started to learn python a few days ago and I am trying to understand what
__del__() actually does. https://docs.python.org/3/reference/datamodel.html
says:
object.__del__(self)
...
Note that it is possible (though not recommended!) for the __del__()
method to postpone destruction of the instance by creating a new
reference to it. It may then be called at a later time when this new
reference is deleted.
However, this trivial test-case
class C:
def __del__(self):
print("DEL")
global X
X = self
C()
print(X)
X = 0
print(X)
shows that __del__ is called only once, it is not called again after "X = 0":
DEL
<__main__.C object at 0x7f067695f4a8>
0
(Just in case, I verified later that this object actually goes away and its
memory is freed, so the problem is not that it still has a reference).
I've cloned https://github.com/python/cpython.git and everything looks clear
at first glance (but let me repeat that I am very new to python):
PyObject_CallFinalizerFromDealloc() calls PyObject_CallFinalizer()
which finally calls "__del__" method in slot_tp_finalize(), then it
notices that "X = self" creates the new reference and does:
/* tp_finalize resurrected it! Make it look like the original Py_DECREF
* never happened.
*/
refcnt = self->ob_refcnt;
_Py_NewReference(self);
self->ob_refcnt = refcnt;
However, PyObject_CallFinalizer() also does _PyGC_SET_FINALIZED(self, 1)
and that is why __del__ is not called again after "X = 0":
/* tp_finalize should only be called once. */
if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self))
return;
The comment and the code are very explicit, so this does nt look like a
bug in cpython.
Probably the docs should be fixed?
Or this code is actually wrong? The test-case works as documented if I
remove _PyGC_SET_FINALIZED() in PyObject_CallFinalizer() or add another
_PyGC_SET_FINALIZED(self, 0) into PyObject_CallFinalizerFromDealloc()
after _Py_NewReference(self), but yes, yes, I understand that this is
not correct and won't really help.
Oleg.
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] why _PyGen_Finalize(gen) propagates close() to _PyGen_yf() ?
Hello,
Let me first clarify, I do not claim this is a bug, I am trying to learn
python and now I trying to understand yield-from.
This simple test-case
g = (x for x in range(10))
def fg():
for x in g:
yield x
print(next(fg()))
print(next(g))
works as expected and prints:
0
1
However, if I change fg() to use yield-from
g = (x for x in range(10))
def fg():
yield from g
print(next(fg()))
print(next(g))
then next(g) raises StopIteration:
0
Traceback (most recent call last):
File "/tmp/T.py", line 10, in
print(next(g))
StopIteration
because g.close() is called by destructor of the object returned by fg().
To me this looks strange and confusing. I tried to google, and found
https://docs.python.org/3/whatsnew/3.3.html#pep-380 but it doesn't document
this behaviour. I understand that yield-from should propagate .close(), but
why _PyGen_Finalize() should send close() to the gi_yieldfrom object?
I applied the patch below just to verify that I actually understand what's
going on, and with this patch the 2nd test-case works as I'd expect. But
since I am very new to python I'd suspect that the code is fine and I simply
do not understand why it works this way.
So. could someone please explain the rationale behind this behaviour? And
probably update the docs should be updated?
Thanks in advance.
Oleg.
---
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 24a1da6..d5152eb 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -6,6 +6,7 @@
#include "opcode.h"
static PyObject *gen_close(PyGenObject *, PyObject *);
+static PyObject *do_gen_close(PyGenObject *, PyObject *);
static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *);
static PyObject *async_gen_athrow_new(PyAsyncGenObject *, PyObject *);
@@ -71,7 +72,7 @@ _PyGen_Finalize(PyObject *self)
}
}
else {
-res = gen_close(gen, NULL);
+res = do_gen_close(gen, NULL);
}
if (res == NULL) {
@@ -373,10 +374,9 @@ _PyGen_yf(PyGenObject *gen)
}
static PyObject *
-gen_close(PyGenObject *gen, PyObject *args)
+do_gen_close(PyGenObject *gen, PyObject *yf)
{
PyObject *retval;
-PyObject *yf = _PyGen_yf(gen);
int err = 0;
if (yf) {
@@ -407,6 +407,11 @@ gen_close(PyGenObject *gen, PyObject *args)
return NULL;
}
+static PyObject *
+gen_close(PyGenObject *gen, PyObject *args)
+{
+return do_gen_close(gen, _PyGen_yf(gen));
+}
PyDoc_STRVAR(throw_doc,
"throw(typ[,val[,tb]]) -> raise exception in generator,\n\
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
I'm overall very supportive of seeing something like this make it into Python to further strengthen duck typing in the language. I know I've wanted something something like this since ABCs were introduced. I personally only have one issue/clarification for the PEP. On Mon, 20 Mar 2017 at 05:02 Ivan Levkivskyi wrote: > [SNIP] > Protocol members > > > All methods defined in the protocol class body are protocol members, both > normal and decorated with ``@abstractmethod``. If some or all parameters of > protocol method are not annotated, then their types are assumed to be > ``Any`` > (see PEP 484). Bodies of protocol methods are type checked, except for > methods > decorated with ``@abstractmethod`` with trivial bodies. A trivial body can > contain a docstring. > What is a "trivial body"? I don't know of any such definition anywhere in Python so this is too loosely defined. You also don't say what happens if the body isn't trivial. Are tools expected to raise an error? > Example:: > > from typing import Protocol > from abc import abstractmethod > > class Example(Protocol): > def first(self) -> int: # This is a protocol member > return 42 > > @abstractmethod > def second(self) -> int:# Method without a default implementation > """Some method.""" > > Note that although formally the implicit return type of a method with > a trivial body is ``None``, > This seems to suggest a trivial body is anything lacking a return statement. > type checker will not warn about above example, > such convention is similar to how methods are defined in stub files. > Static methods, class methods, and properties are equally allowed > in protocols. > Personally, I think even an abstract method should be properly typed. So in the example above, second() should either return a reasonable default value or raise NotImplementedError. My argument is "explicit is better than implicit" and you make errors when people call super() on an abstract method that doesn't return None when it doesn't make sense. I would also argue that you can't expect an abstract method to always be simple. For instance, I might define an abstract method that has horrible complexity characteristics (e.g. O(n**2)), but which might be acceptable in select cases. By making the method abstract you force subclasses to explicitly opt-in to using the potentially horrible implementation. -Brett > > To define a protocol variable, one must use PEP 526 variable > annotations in the class body. Additional attributes *only* defined in > the body of a method by assignment via ``self`` are not allowed. The > rationale > for this is that the protocol class implementation is often not shared by > subtypes, so the interface should not depend on the default implementation. > Examples:: > > from typing import Protocol, List > > class Template(Protocol): > name: str# This is a protocol member > value: int = 0 # This one too (with default) > > def method(self) -> None: > self.temp: List[int] = [] # Error in type checker > > To distinguish between protocol class variables and protocol instance > variables, the special ``ClassVar`` annotation should be used as specified > by PEP 526. > > > ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
On 20 March 2017 at 19:07, Brett Cannon wrote: > I'm overall very supportive of seeing something like this make it into > Python to further strengthen duck typing in the language. > Thanks! > Personally, I think even an abstract method should be properly typed. > [SNIP] > or raise NotImplementedError. > Yes, I think this is a reasonable requirement. (Also assuming unconditional raise is a bottom type, raising body is properly typed). Initially I thought a type checker could warn about invalid calls to super(), but this complicates things, and indeed "explicit is better than implicit". -- Ivan ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
On Mon, Mar 20, 2017, at 14:07, Brett Cannon wrote: > What is a "trivial body"? I don't know of any such definition anywhere in > Python so this is too loosely defined. You also don't say what happens if > the body isn't trivial. Are tools expected to raise an error? My assumption would be that a trivial body is any body consisting of only a docstring and/or a "pass" statement. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Py_SIZE vs PyXXX_GET_SIZE
On Mon, 20 Mar 2017 13:26:34 +0200 Serhiy Storchaka wrote: > What is the preferable way of getting the size of tuple, list, bytes, > bytearray: Py_SIZE or PyTuple_GET_SIZE, PyList_GET_SIZE, > PyBytes_GET_SIZE, PyByteArray_GET_SIZE? Are macros for concrete types > more preferable or they are outdated? +1 for using concrete macros. Py_SIZE is a low-level internal thing (e.g. it will return a negative size on negative ints). Regards Antoine. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] __del__ is not called after creating a new reference
Hello Oleg, On Mon, 20 Mar 2017 18:28:29 +0100 Oleg Nesterov wrote: > I started to learn python a few days ago and I am trying to understand what > __del__() actually does. https://docs.python.org/3/reference/datamodel.html > says: > > object.__del__(self) > ... > Note that it is possible (though not recommended!) for the __del__() > method to postpone destruction of the instance by creating a new > reference to it. It may then be called at a later time when this new > reference is deleted. This sentence is not technically wrong, but it can easily be misleading. It says "it *may* then be called at a later time" and probably it should say "it may or may not be called at a later time, depending on the Python implementation you are using". Indeed CPython, the reference implementation, only calls __del__ once and doesn't call it again on resurrected objects. It is an implementation detail, though, and other implementations are free to behave otherwise, as garbage collectors are delicate beasts, difficult to tame. Regards Antoine. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] __del__ is not called after creating a new reference
On 2017-03-20 20:23, Antoine Pitrou wrote: Hello Oleg, On Mon, 20 Mar 2017 18:28:29 +0100 Oleg Nesterov wrote: I started to learn python a few days ago and I am trying to understand what __del__() actually does. https://docs.python.org/3/reference/datamodel.html says: object.__del__(self) ... Note that it is possible (though not recommended!) for the __del__() method to postpone destruction of the instance by creating a new reference to it. It may then be called at a later time when this new reference is deleted. This sentence is not technically wrong, but it can easily be misleading. It says "it *may* then be called at a later time" and probably it should say "it may or may not be called at a later time, depending on the Python implementation you are using". [snip] I don't think I'd say it's misleading, but only that it might be misunderstood. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
I'm a big fan of this. I really want structural subtyping for http://github.com/google/pytype. On Mon, Mar 20, 2017 at 5:00 AM, Ivan Levkivskyi wrote: > Explicitly declaring implementation > --- > > To explicitly declare that a certain class implements the given protocols, > Why is this necessary? The whole point of ducktyping is that you *don't* have to declare what you implement. I get that it looks convenient to have your protocol A also supply some of the methods you'd expect classes of type A to have. But completing an implementation in that way should be done explicitly (via including a utility class or using a decorator like functools.total_ordering), not as side-effect of an (unnecessary) protocol declaration. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] __del__ is not called after creating a new reference
On Mar 20, 2017 1:26 PM, "Antoine Pitrou" wrote: Hello Oleg, On Mon, 20 Mar 2017 18:28:29 +0100 Oleg Nesterov wrote: > I started to learn python a few days ago and I am trying to understand what > __del__() actually does. https://docs.python.org/3/ reference/datamodel.html > says: > > object.__del__(self) > ... > Note that it is possible (though not recommended!) for the __del__() > method to postpone destruction of the instance by creating a new > reference to it. It may then be called at a later time when this new > reference is deleted. This sentence is not technically wrong, but it can easily be misleading. It says "it *may* then be called at a later time" and probably it should say "it may or may not be called at a later time, depending on the Python implementation you are using". Modern CPython, and all extant versions of PyPy and Jython, guarantee that __del__ is called at most once. MicroPython doesn't support user-defined __del__ methods. It's fine if the text wants to leave that open, but the current phrasing is pretty misleading IMO. I also read it as saying that __del__ would be called again if the object is collected again (which may or may not happen). But AFAICT there are actually zero implementations where this is true. Probably worth a small edit :-) -n ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
On 20 March 2017 at 22:11, Matthias Kramm wrote: > I'm a big fan of this. I really want structural subtyping for > http://github.com/google/pytype. > > I am glad you like it. > > On Mon, Mar 20, 2017 at 5:00 AM, Ivan Levkivskyi > wrote: > >> Explicitly declaring implementation >> --- >> >> To explicitly declare that a certain class implements the given protocols, >> > > Why is this necessary? The whole point of ducktyping is that you *don't* > have to declare what you implement. > > I get that it looks convenient to have your protocol A also supply some of > the methods you'd expect classes of type A to have. But completing an > implementation in that way should be done explicitly (via including a > utility class or using a decorator like functools.total_ordering), not as > side-effect of an (unnecessary) protocol declaration. > I would put the question backwards: do we need to *prohibit* explicit subclassing? I think we shouldn't. Mostly for two reasons: 1. Backward compatibility: People are already using ABCs, including generic ABCs from typing module. If we prohibit explicit subclassing of these ABCs, then quite a lot of code will break. 2. Convenience: There are existing protocol-like ABCs (that will be turned into protocols) that have many useful "mix-in" (non-abstract) methods. For example in case of Sequence one only needs to implement __getitem__ and __len__ in an explicit subclass, and one gets __iter__, __contains__, __reversed__, index, and count for free. Another example is Mapping, one needs to implement only __getitem__, __len__, and __iter__, and one gets __contains__, keys, items, values, get, __eq__, and __ne__ for free. If you think it makes sense to add a note that implicit subtyping is preferred (especially for user defined protocols), then this certainly could be done. -- Ivan ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
On Mar 20, 2017, at 01:00 PM, Ivan Levkivskyi wrote:
>from zope.interface import Interface, Attribute, implements
>
>class IEmployee(Interface):
>
>name = Attribute("Name of employee")
>
>def do(work):
>"""Do some work"""
>
>class Employee(object):
>implements(IEmployee)
IIUC, the Python 3 way to spell this is with a decorator.
from zope.interface import implementer
@implementer(IEmployee)
class Employee:
(also, since this is Python 3, do you really need to inherit from object?)
Cheers,
-Barry
pgpieJvP53ib2.pgp
Description: OpenPGP digital signature
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 544: Protocols
On 21 March 2017 at 00:23, Barry Warsaw wrote: > On Mar 20, 2017, at 01:00 PM, Ivan Levkivskyi wrote: > > [SNIP] > > IIUC, the Python 3 way to spell this is with a decorator. > Thanks, I will update this. > [SNIP] > (also, since this is Python 3, do you really need to inherit from object?) > Indeed. -- Ivan ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Py_SIZE vs PyXXX_GET_SIZE
On Mon, Mar 20, 2017, at 13:18, Antoine Pitrou wrote: > On Mon, 20 Mar 2017 13:26:34 +0200 > Serhiy Storchaka wrote: > > What is the preferable way of getting the size of tuple, list, bytes, > > bytearray: Py_SIZE or PyTuple_GET_SIZE, PyList_GET_SIZE, > > PyBytes_GET_SIZE, PyByteArray_GET_SIZE? Are macros for concrete types > > more preferable or they are outdated? > > +1 for using concrete macros. Py_SIZE is a low-level internal thing > (e.g. it will return a negative size on negative ints). +1 Py_SIZE is an implementation detail of varsize types. Using the concrete macros also the implementation to change without altering API consumers. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Py_SIZE vs PyXXX_GET_SIZE
We may modify PyXXX_GET_SIZE() to add assert(PyXXX_Check()) to help to detect bugs and misuses of these macros in debug mode. The problem is that I expect a compilation error on PyXXX_GET_SIZE()=size. The new PyDict_GET_SIZE() macro has the assertion. Use Py_SIZE() to set the size. Victor Le 20 mars 2017 12:28, "Serhiy Storchaka" a écrit : > What is the preferable way of getting the size of tuple, list, bytes, > bytearray: Py_SIZE or PyTuple_GET_SIZE, PyList_GET_SIZE, PyBytes_GET_SIZE, > PyByteArray_GET_SIZE? Are macros for concrete types more preferable or they > are outdated? > > On one hand concrete type macros are longer than Py_SIZE, and since > concrete type macros are defined not for all PyVarObject types we need to > use Py_SIZE for them in any case (for example for PyLongObject and > PyTypeObject). > > On other hand we can add asserts for checking that concrete type macros > are used with correct types. When I wrote a patch that replaces Py_SIZE > with concrete type macros I found two cases of misusing Py_SIZE with dict > object: one in _json.c (already fixed in > 3023ebb43f7607584c3e123aff56e867cb04a418) > and other in dictobject.c (still not fixed). If prefer using concrete type > macros this would unlikely happen. > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/victor. > stinner%40gmail.com > ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
