473,382 Members | 1,409 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Weakrefs to classes that derive from str

Why doesn't this work?
from weakref import ref
class C(str): pass .... ref(C()) Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot create weak reference to 'C' object
Note that this does work:
class D(int): pass .... ref(D()) <weakref at 0x53e10; dead>


Likewise for floats, lists, etc. Everything but strs.

rg
Jul 18 '05 #1
12 2690
Ron Garret wrote:
Why doesn't this work?
from weakref import ref
class C(str): pass ...ref(C())

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot create weak reference to 'C' object


Note that you don't need the class redirection:

py> ref('')
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: cannot create weak reference to 'str' object

But I don't know why strings aren't valid arguments to ref...

STeVe
Jul 18 '05 #2
In article <bv********************@comcast.com>,
Steven Bethard <st************@gmail.com> wrote:
Ron Garret wrote:
Why doesn't this work?
>from weakref import ref
>class C(str): pass

...
>ref(C())

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot create weak reference to 'C' object


Note that you don't need the class redirection:

py> ref('')
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: cannot create weak reference to 'str' object

But I don't know why strings aren't valid arguments to ref...


None of the native types (int, float, list, tuple, etc.) can have weak
references, but wrapping them in a class is supposed to get around that.
And it does -- for all classes except str.

rg
Jul 18 '05 #3
Ron Garret wrote:
Note that you don't need the class redirection:

py> ref('')
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: cannot create weak reference to 'str' object

But I don't know why strings aren't valid arguments to ref...


None of the native types (int, float, list, tuple, etc.) can have weak
references, but wrapping them in a class is supposed to get around that.
And it does -- for all classes except str.


Interesting. Is the wrapping thing documented somewhere? I didn't see
it in the documentation for weakref.ref (though I have been known to be
blind occasionally) ;)

STeVe
Jul 18 '05 #4
Steven Bethard wrote:
Ron Garret wrote:
None of the native types (int, float, list, tuple, etc.) can have weak
references, but wrapping them in a class is supposed to get around
that. And it does -- for all classes except str.


Interesting. Is the wrapping thing documented somewhere? I didn't see
it in the documentation for weakref.ref (though I have been known to be
blind occasionally) ;)


I believe it's here: http://docs.python.org/lib/module-weakref.html
if you search for the string "Not all" and read the next two
paragraphs.

On the other hand, it says (there) only that "several builtin
types such as list and dict ... can add support through
subclassing", and does not say anything about int, str, etc...

-Peter
Jul 18 '05 #5
Peter Hansen wrote:
I believe it's here: http://docs.python.org/lib/module-weakref.html
if you search for the string "Not all" and read the next two
paragraphs.

On the other hand, it says (there) only that "several builtin
types such as list and dict ... can add support through
subclassing", and does not say anything about int, str, etc...


Ahh, thanks for the help. I guess there are at least two solutions to
the OP's problem then:

(1) Document that str and subclasses of str can't be weakreffed (easy)
(2) Change str so that it (or at least its subclasses) can be weakreffed
(hard)

Probably either way a feature request should be filed.

STeVe
Jul 18 '05 #6
In article <tu********************@powergate.ca>,
Peter Hansen <pe***@engcorp.com> wrote:
Steven Bethard wrote:
Ron Garret wrote:
None of the native types (int, float, list, tuple, etc.) can have weak
references, but wrapping them in a class is supposed to get around
that. And it does -- for all classes except str.


Interesting. Is the wrapping thing documented somewhere? I didn't see
it in the documentation for weakref.ref (though I have been known to be
blind occasionally) ;)


I believe it's here: http://docs.python.org/lib/module-weakref.html
if you search for the string "Not all" and read the next two
paragraphs.

On the other hand, it says (there) only that "several builtin
types such as list and dict ... can add support through
subclassing", and does not say anything about int, str, etc...


Empirically:
from weakref import ref
def foo(c): .... class C(c): pass
.... ref(C())
.... foo(int)
foo(float)
foo(dict)
foo(list)
foo(str) Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in foo
TypeError: cannot create weak reference to 'C' object foo(tuple) Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in foo
TypeError: cannot create weak reference to 'C' object foo(long) Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in foo
TypeError: cannot create weak reference to 'C' object


Ah, it appears that non-immediate immutable types don't support
weakrefs. Hm...

rg
Jul 18 '05 #7
Ron Garret wrote:
foo(int)
foo(float)
foo(dict)
foo(list)
foo(str) TypeError: cannot create weak reference to 'C' object
foo(tuple) TypeError: cannot create weak reference to 'C' object
foo(long)

TypeError: cannot create weak reference to 'C' object

Ah, it appears that non-immediate immutable types don't support
weakrefs. Hm...


I see the same results you do, and yet I don't understand
the comment. Can you please explain what "immediate"
means in this context?

-Peter
Jul 18 '05 #8
[Ron Garret]
Why doesn't this work?
from weakref import ref
class C(str): pass ... ref(C())
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot create weak reference to 'C' object

. . . Everything but strs.


Also subclasses of tuple are not weak referencable.

The issue is in the design of the C structure as a variable-sized immutable
object. Both strings and tuples allocate as a single unit of memory that holds
both the header information and the content information (the characters in a
string or the array of object pointers for a tuple). Since the size varies from
one string or tuple to the next, there is no straight-forward way for a subclass
to add an additional header field pointing to a list of weak references.

For lists and dicts, this is not a problem because the object is allocated in
two sections, a fixed size header component and a pointer to another area of
memory to hold the contents of the collection. This makes it possible for a
subclass to graft-on a weak reference pointer at a known, fixed offset from the
beginning of the header.

There are two ways to fix this. One is to add a weak reference pointer to every
string object -- that way you wouldn't even have to subclass it. Another way is
to break the object into two pieces as is done for mutable containers like dicts
and lists.

Both approaches consume time and space. In general, that is not a big deal, but
fast, memory efficient strings and tuples are at the center of all things
Python. The need to weak reference this objects is somewhat rare in comparison
to the frequency of their other uses. It did not make sense to always pay a
time/space penalty just to create the possibility of weak referencing.

While the design decision is unlikely to change, the docs could certainly be
improved. A doc patch would be welcome.

FWIW, the work-arounds are to weak-reference instances of UserString or to
create a custom class with a has-a relationship instead of an is-a relationship.
Raymond Hettinger
Jul 18 '05 #9
In article <-4********************@powergate.ca>,
Peter Hansen <pe***@engcorp.com> wrote:
Ron Garret wrote:
>foo(int)
>foo(float)
>foo(dict)
>foo(list)
>foo(str)

TypeError: cannot create weak reference to 'C' object
>foo(tuple)

TypeError: cannot create weak reference to 'C' object
>foo(long)

TypeError: cannot create weak reference to 'C' object

Ah, it appears that non-immediate immutable types don't support
weakrefs. Hm...


I see the same results you do, and yet I don't understand
the comment. Can you please explain what "immediate"
means in this context?


"Immediate" means a data type that will fit entirely in a machine
register, and therefore doesn't need to actually be stored in memory.
Ints and floats are the only two immediate types in Python. They are
immutable, but you can still create weakrefs to classes that derive from
them.

rg
Jul 18 '05 #10
In article <RbB2e.52616$u76.11019@trndny08>,
"Raymond Hettinger" <vz******@verizon.net> wrote:
[Ron Garret]
Why doesn't this work?
>> from weakref import ref
>> class C(str): pass

...
>> ref(C())

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot create weak reference to 'C' object

. . .
Everything but strs.


Also subclasses of tuple are not weak referencable.

The issue is in the design of the C structure as a variable-sized immutable
object. Both strings and tuples allocate as a single unit of memory that
holds
both the header information and the content information (the characters in a
string or the array of object pointers for a tuple). Since the size varies
from
one string or tuple to the next, there is no straight-forward way for a
subclass
to add an additional header field pointing to a list of weak references.

For lists and dicts, this is not a problem because the object is allocated in
two sections, a fixed size header component and a pointer to another area of
memory to hold the contents of the collection. This makes it possible for a
subclass to graft-on a weak reference pointer at a known, fixed offset from
the
beginning of the header.

There are two ways to fix this. One is to add a weak reference pointer to
every
string object -- that way you wouldn't even have to subclass it. Another way
is
to break the object into two pieces as is done for mutable containers like
dicts
and lists.

Both approaches consume time and space. In general, that is not a big deal,
but
fast, memory efficient strings and tuples are at the center of all things
Python. The need to weak reference this objects is somewhat rare in
comparison
to the frequency of their other uses. It did not make sense to always pay a
time/space penalty just to create the possibility of weak referencing.

While the design decision is unlikely to change, the docs could certainly be
improved. A doc patch would be welcome.

FWIW, the work-arounds are to weak-reference instances of UserString or to
create a custom class with a has-a relationship instead of an is-a
relationship.


Thanks for the detailed explanation. I understand now why you can't
create weakrefs to these types. What I don't understand still is why
you can't create weakrefs to user-defined classes that inherit from
these types. I would think that instances of user-defined classes have
the same header structure regardless of what they inherit from. This
would seem to be supported by the fact that you can create weakrefs to
instances of user-defined classes that inherit from int and float.

rg
Jul 18 '05 #11
[Ron Garret]
Thanks for the detailed explanation. I understand now why you can't
create weakrefs to these types. What I don't understand still is why
you can't create weakrefs to user-defined classes that inherit from
these types. I would think that instances of user-defined classes have
the same header structure regardless of what they inherit from. This
would seem to be supported by the fact that you can create weakrefs to
instances of user-defined classes that inherit from int and float.


It is an over-statement to say that it can't be done. In fact, Michael Hudson
is already working on a patch.

It is more accurate to say that the current mechanism doesn't allow it.
Michael's solution is to build a new mechanism.

The existing mechanism has a subclass extend the superclass's structure:

[--someobj--][--subclassdata--]
^
|
|---- offset to wr table ---

The offset is fixed for the type and must be the same across instances.

This is a problem for tuples and ints because someobj is of varying length:

[--tuple header, elem0, elem1, elem2--]
[--tuple header, elem0 ]

In contrast, ints and floats floats have no problem because they are always the
same size:

[--int header, int value--]
Raymond Hettinger


Jul 18 '05 #12
In article <RgJ2e.26268$I16.3183@trndny03>,
"Raymond Hettinger" <vz******@verizon.net> wrote:
[Ron Garret]
Thanks for the detailed explanation. I understand now why you can't
create weakrefs to these types. What I don't understand still is why
you can't create weakrefs to user-defined classes that inherit from
these types. I would think that instances of user-defined classes have
the same header structure regardless of what they inherit from. This
would seem to be supported by the fact that you can create weakrefs to
instances of user-defined classes that inherit from int and float.


It is an over-statement to say that it can't be done. In fact, Michael
Hudson
is already working on a patch.

It is more accurate to say that the current mechanism doesn't allow it.
Michael's solution is to build a new mechanism.

The existing mechanism has a subclass extend the superclass's structure:

[--someobj--][--subclassdata--]
^
|
|---- offset to wr table ---

The offset is fixed for the type and must be the same across instances.

This is a problem for tuples and ints because someobj is of varying length:

[--tuple header, elem0, elem1, elem2--]
[--tuple header, elem0 ]

In contrast, ints and floats floats have no problem because they are always
the
same size:

[--int header, int value--]
Raymond Hettinger


I see. Thanks!

rg
Jul 18 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: William Trenker | last post by:
I'm trying to get a better grasp on the difference between weakref.ref and weakref.proxy. I've read PEP 205 and goolged for additional description information on weakrefs, but I'm not finding...
2
by: | last post by:
I have this class ------------- class Component { /*class*/ Data *d; /*class*/ Draw *a; }; ------------- from "Component" derive classes like "TextBox", "Button", "Label", "ComboBox" etc from...
11
by: mem | last post by:
Concrete classes are ones that can be instantiated directly, as long as it doesn't have pure virtual function. However, people suggest that "Don't derive from concrete classes." Does this mean...
2
by: Indiana Epilepsy and Child Neurology | last post by:
Before asking this questions I've spent literally _years_ reading (Meyer, Stroustrup, Holub), googling, asking more general design questions, and just plain thinking about it. I am truly unable to...
9
by: Sean Kirkpatrick | last post by:
To my eye, there doesn't seem to be a whole lot of difference between the two of them from a functional point of view. Can someone give me a good explanation of why one vs the other? Sean
6
by: Peter Oliphant | last post by:
I just discovered that the ImageList class can't be inherited. Why? What could go wrong? I can invision a case where someone would like to add, say, an ID field to an ImageList, possible so that...
0
by: Kamilche | last post by:
''' event.py An event manager using publish/subscribe, and weakrefs. Any function can publish any event without registering it first, and any object can register interest in any event, even...
6
by: ivan.leben | last post by:
I want to write a Mesh class using half-edges. This class uses three other classes: Vertex, HalfEdge and Face. These classes should be linked properly in the process of building up the mesh by...
11
by: Mathias Panzenboeck | last post by:
Hi. I have a problem with weak refs and bound methods. The best explanation for the problem is a short bit of code. I have the three classes Wrapper, Foo and Bar: import weakref class...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.