1

I have a library (caffe) that has the following definition:

class NetSpec(object):
    def __init__(self):
        super(NetSpec, self).__setattr__('tops', OrderedDict())

    def __setattr__(self, name, value):
        self.tops[name] = value

    def __getattr__(self, name):
        return self.tops[name]

    def to_proto(self):
        names = {v: k for k, v in self.tops.iteritems()}
        autonames = {}
        layers = OrderedDict()
        for name, top in self.tops.iteritems():
            top.fn._to_proto(layers, names, autonames)
        net = caffe_pb2.NetParameter()
        net.layer.extend(layers.values())
        return net

When I try to call it using n = caffe.NetSpec() I get the following error:

  File "../../python/caffe/layers.py", line 84, in __init__
    super(NetSpec, self).__setattr__('tops', OrderedDict())

TypeError: must be type, not None

I checked SO-9698614,SO-576169 and SO-489269 but they did not lead to a solution. My class is a new type class and I could not see why it was not working.

Full trace:

Traceback (most recent call last):

  File "<ipython-input-72-694741de221d>", line 1, in <module>
    runfile('/home/shaunak/caffe-pr2086/examples/wine/classify.py', wdir='/home/shaunak/caffe-pr2086/examples/wine')

  File "/home/shaunak/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 682, in runfile
    execfile(filename, namespace)

  File "/home/shaunak/anaconda/lib/python2.7/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 78, in execfile
    builtins.execfile(filename, *where)

  File "/home/shaunak/caffe-pr2086/examples/wine/classify.py", line 26, in <module>
    f.write(str(logreg('examples/hdf5_classification/data/train.txt', 10)))

  File "/home/shaunak/caffe-pr2086/examples/wine/classify.py", line 18, in logreg
    n = caffe.NetSpec()

  File "../../python/caffe/layers.py", line 84, in __init__
    super(NetSpec, self).__setattr__('tops', OrderedDict())

TypeError: must be type, not None
Community
  • 1
  • 1
shaunakde
  • 3,009
  • 3
  • 24
  • 39
  • @MartijnPieters I rechecked the trace and un-did my changes on the library. The error is still: `super(NetSpec, self).__setattr__('tops', OrderedDict())` - updating code – shaunakde Apr 21 '15 at 14:21
  • 1
    @shaunakde: do you set `NetSpec` to `None` somewhere? Or otherwise run this code when the module is cleared? – Martijn Pieters Apr 21 '15 at 14:22
  • @MartijnPieters - No it gives me error on initialization itself. `def logreg(hdf5, batch_size): # logistic regression: data, matrix multiplication, and 2-class softmax loss n = caffe.NetSpec()`. Also could you please give me some reference material for this. I am having a hard time following you. – shaunakde Apr 21 '15 at 14:24
  • @VivekSable - What is exactly the problem with my code? I am using the standard example. – shaunakde Apr 21 '15 at 14:25
  • can u print `print caffe.NetSpec` before `n = caffe.NetSpec()` line ? – Vivek Sable Apr 21 '15 at 14:26
  • @MartijnPieters yes sory:) I means `print caffe.NetSpec` – Vivek Sable Apr 21 '15 at 14:29
  • @MartijnPieters - The old traceback was from my tinkering. Apologies. – shaunakde Apr 21 '15 at 14:29
  • @VivekSable: that'd not give enough info either; we don't know if `caffe.NetSpec` is the right global here.. – Martijn Pieters Apr 21 '15 at 14:30
  • @VivekSable - print works. I get `` – shaunakde Apr 21 '15 at 14:30
  • @shaunakde: so you import the class from `caffe` but defined it in `caffe.layers` originally. What does `print caffe.layers.NetSpec` give? – Martijn Pieters Apr 21 '15 at 14:31
  • @MartijnPieters - print caffe.layers.NetSpec `` – shaunakde Apr 21 '15 at 14:32
  • @shaunakde: so how did you define this class and what happened afterwards? You are doing something very funky here. Why is `caffe.layers.NetSpec` now a function object? – Martijn Pieters Apr 21 '15 at 14:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75835/discussion-between-shaunakde-and-martijn-pieters). – shaunakde Apr 21 '15 at 14:34

1 Answers1

2

Somehow you managed to bind NetSpec to None somewhere:

>>> super(None, object())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be type, not None

The error indicates that the NetSpec global is bound to None.

You could also bypass the NetSpec.__setattr__ method by going directly to the instance __dict__ attribute:

class NetSpec(object):
    def __init__(self):
       self.__dict__['tops'] = OrderedDict()

From the code you shared it could be that this is the culprit:

from .layers import layers, params, NetSpec

This imports caffe.layers but rebinds caffe.layers to the Layers() instance. This could then trigger Python to delete the module again as there are no other references to it yet (depending on when and how the sys.modules reference is created), causing all globals to be rebound to None (including NetSpec).

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I have updated the stack track. it was unfortunately from my tinkering. – shaunakde Apr 21 '15 at 14:28
  • File "../../python/caffe/layers.py", line 84, in __init__ self.__dict__['tops'] = OrderedDict() TypeError: 'NoneType' object is not callable – shaunakde Apr 21 '15 at 15:14
  • @shaunakde: yes, because **all** your globals are set to `None`. That includes `OrderedDict`. – Martijn Pieters Apr 21 '15 at 15:16
  • @MartijnPieters congrats on your new mod position! good luck! – Shai Apr 22 '15 at 05:51
  • @MartijnPieters - Congrats on becoming a mod. I was not able to fully solve it but I was about to get around by modifying the library. But this is the best possible explanation. PS: I voted for you :P – shaunakde Apr 22 '15 at 13:24