1

I have a class with a string property defined on it.

class Foo(object):
    @property
    def kind(self):
        return 'bar'

There's some third party code that I want to pass this property to that asserts that the property is a str:

third party:

def baz(kind):
    if not isinstance(kind, (str, unicode)):
        message = ('%.1024r has type %s, but expected one of: %s' %
                   (kind, type(kind), (str, unicode)))
        raise TypeError(message)

me:

foo = Foo()
baz(foo.kind)

output:

TypeError: <property object at 0x11013e940> has type <type 'property'>, but expected one of: (<type 'str'>, <type 'unicode'>)

Is there any way I can make the python object have a property with str type rather than property type?

EDIT:

Original question is wrong, I was actually calling

Foo.kind

as pointed out by Martijn Pieters below.

Community
  • 1
  • 1
brandones
  • 1,847
  • 2
  • 18
  • 36

2 Answers2

4

You are accessing the property directly on the class:

>>> Foo.kind
<property object at 0x104a22c00>
>>> baz(Foo.kind)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in baz
TypeError: <property object at 0x104a22c00> has type <type 'property'>, but expected one of: (<type 'str'>, <type 'unicode'>)

If you actually had an instance, the function you posted works just fine:

>>> Foo().kind
'bar'
>>> baz(Foo().kind)

That's because only when a property is bound to an instance does it use the getter function when accessed. When bound to a class the property object is returned directly.

Also see How does the @property decorator work?

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Yep, my question was wrong -- I was indeed accessing the method from the class rather than an instance. Good catch. – brandones Dec 30 '14 at 01:25
0

Your code works fine for me:

class Foo(object):
    @property
    def kind(self):
        return 'bar'

def baz(kind):
    if not isinstance(kind, (str, unicode)):
        message = ('%.1024r has type %s, but expected one of: %s' %
                   (kind, type(kind), (str, unicode)))
        raise TypeError(message)


foo = Foo()
print foo.kind

baz(foo.kind)


--output:--
bar
7stud
  • 46,922
  • 14
  • 101
  • 127