Path: csiph.com!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder1.enfer-du-nord.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'kind,': 0.05; 'bits': 0.07; 'bytes.': 0.07; 'item.': 0.07; 'nicely': 0.07; 'reason,': 0.07; 'type,': 0.07; 'python': 0.09; 'bytes,': 0.09; 'bytes;': 0.09; 'enum': 0.09; 'it;': 0.09; 'itself,': 0.09; "object's": 0.09; 'objects.': 0.09; 'pointers': 0.09; 'slices': 0.09; 'subject:()': 0.09; 'tracing': 0.09; 'tuple': 0.09; 'typedef': 0.09; 'itself.': 0.11; '24,': 0.16; 'count,': 0.16; 'count.': 0.16; 'elsewhere.': 0.16; 'expression,': 0.16; 'index;': 0.16; 'lower,': 0.16; 'merely': 0.16; 'oct': 0.16; 'pointer,': 0.16; 'pointers,': 0.16; 'subject:array': 0.16; 'value;': 0.16; 'mon,': 0.16; 'wrote:': 0.17; 'bytes': 0.17; 'odd': 0.17; 'pieces': 0.17; 'pointer': 0.17; 'are:': 0.20; 'earlier': 0.21; 'object.': 0.22; 'struct': 0.22; 'tuples': 0.22; 'for?': 0.23; 'downloaded': 0.24; 'header:In-Reply-To:1': 0.25; 'fit': 0.26; 'skip:" 20': 0.26; 'am,': 0.27; 'andrew': 0.27; 'start,': 0.27; 'message- id:@mail.gmail.com': 0.27; 'fixed': 0.28; 'actual': 0.28; 'pointer.': 0.29; 'objects': 0.29; 'included': 0.29; 'source': 0.29; 'knows': 0.30; 'notes': 0.30; 'figure': 0.30; 'expect': 0.31; 'code': 0.31; 'structure': 0.32; 'getting': 0.33; 'int': 0.33; 'to:addr:python-list': 0.33; 'received:google.com': 0.34; 'list': 0.35; 'whatever': 0.35; 'data,': 0.35; 'so,': 0.35; 'expected': 0.35; 'received:209.85': 0.35; 'but': 0.36; 'be.': 0.36; 'skip:{ 10': 0.36; 'should': 0.36; 'does': 0.37; 'two': 0.37; 'item': 0.37; 'rather': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'object': 0.38; 'some': 0.38; 'gives': 0.39; 'to:addr:python.org': 0.39; 'step': 0.39; 'where': 0.40; 'header:Received:5': 0.40; 'back': 0.62; 'more': 0.63; 'note:': 0.64; 'contents.': 0.65; 'union': 0.66; 'contrary': 0.71; 'grow': 0.74; '24.': 0.84; 'elements:': 0.84; 'ref': 0.84; 'stop,': 0.84; 'step.': 0.91; 'imagine': 0.96 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type:x-gm-message-state; bh=nMMkfBwUgvo7of4epZH65QldANejntefijm5hXFGqac=; b=fJU2z6ZyVwJIXb6762XigjoHKs4WIottknMm1nRaoVGNoM+9DxDDupUUJ2JJ/u1urG NbEeBWQu+c3BMGDjBorXBU6ZeluWCmLx8aqfExQdcTRATiquvKcieezQHZFGAUCAfIPU addmBF3xXGYMP3N4yDjw/1sxZSbS87mLv4mc4u/a3velGYh+OGxB5DBAtTiOnMXDArNk JEHWK4OaexTVSTMyeVrd/wA0KQSALl2K00F/u42KNOr0l695mQtdeGwJQlwLhdUIs3J9 RmRzl3mZ2jwUjPGXt3hLr0T7LUrlIXvRH0g2GQyyirODcKq0+TrznKjldyRiirJtrswi v8SQ== MIME-Version: 1.0 In-Reply-To: <508EC428.5080808@r3dsolutions.com> References: <6998a955-7b34-4f4f-b8d6-62d1028f7561@googlegroups.com> <4c024364-84df-403b-8b9e-4a4c8f06121c@googlegroups.com> <508e6649$0$29967$c3e8da3$5496439d@news.astraweb.com> <508E1BC9.3000308@r3dsolutions.com> <508EC428.5080808@r3dsolutions.com> From: Chris Kaynor Date: Mon, 29 Oct 2012 18:49:19 -0700 Subject: Re: Negative array indicies and slice() To: python-list@python.org Content-Type: text/plain; charset=ISO-8859-1 X-Gm-Message-State: ALoCoQmRxH9UKKUZsfEaVuOsoGrp4jWPZ0X2mFgFi256/k83gtirrcyhauzHkhIq9ehSizOaD/8u X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 93 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1351561789 news.xs4all.nl 6898 [2001:888:2000:d::a6]:33370 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:32454 On Mon, Oct 29, 2012 at 11:00 AM, Andrew Robinson wrote: > > Let's look at the source code rather than the web notes -- the source must > be the true answer anyhow. > > I downloaded the source code for python 3.3.0, as the tbz; > In the directory "Python-3.3.0/Python", look at Python-ast.c, line 2089 & > ff. > > Clearly a slice is malloced for a slice_ty type. > It has four elements: kind, lower, upper, and step. > > So, tracing it back to the struct definition... > > "Include/Python-ast.h" has "typedef struct _slice *slice_ty;" > > And, here's the answer!: > > enum _slice_kind {Slice_kind=1, ExtSlice_kind=2, Index_kind=3}; > struct _slice { > enum _slice_kind kind; > union { > struct { > expr_ty lower; > expr_ty upper; > expr_ty step; > } Slice; > > struct { > asdl_seq *dims; > } ExtSlice; > > struct { > expr_ty value; > } Index; > > } v; > }; > > > So, slice() does indeed have arbitrary python types included in it; contrary > to what I read elsewhere. > expr_ty is a pointer to an arbitrary expression, so the actual structure is > 4 pointers, at 32 bits each = 16 bytes. > The size of the structure itself, given in an earlier post, is 20 bytes -- > which means one more pointer is involved, perhaps the one pointing to the > slice structure itself. > > Hmm...! > > An empty tuple gives sys.getsizeof( () ) = 24. > > But, I would expect a tuple to be merely a list of object pointers; hence I > would expect 4 bytes for len(), and then a head pointer 4 bytes, and then a > pointer for each object. > 3 objects gives 12 bytes, + 8 = 16 bytes. > > Then we need one more pointer so Python knows where the struct is... > So a Tuple of 3 objects ought to fit nicely into 20 bytes; the same size as > slice() -- > > but it's 24, even when empty... > And 36 when initialized... > What are the extra 16 bytes for? Every Python object requires two pieces of data, both of which are pointer-sized (one is a pointer, one is an int the size of a pointer). These are: a pointer to the object's type, and the object's reference count. A tuple actually does not need a head pointer: the head pointer is merely an offset from the tuple's pointer. It merely has a ref count, type, an item count, and pointers to its contents. A slice has the same type pointer and reference count, then three pointers to the start, stop, and step objects. This means a slice object should be the same size as a two-item tuple: the tuple needs a count, while that is fixed at 3 for a slice (though some items may be unset). NOTE: The above is taken from reading the source code for Python 2.6. For some odd reason, I am getting that an empty tuple consists of 6 pointer-sized objects (48 bytes on x64), rather than the expected 3 pointer-sized (24 bytes on x64). Slices are showing up as the expected 5 pointer-sized (40 bytes on x64), and tuples grow at the expected 1 pointer (8 bytes on x64) per item. I imagine I am missing something, but cannot figure out what that would be. > > All I see is: > typedef struct { object** whatever } PyTupleObject; >