On Sunday, June 16, 2013 1:48:02 PM UTC-4, Wouter Bijlsma wrote: > > Hello fellow Pyramid users, > > I'm currently in the process of writing a web application proof-of-concept > using Pyramid 1.4 + MongoDB, which is starting to morph into a something > resembling a 'web application framework on top of Pyramid' more than just a > 'web application using Pyramid'. As a result, I find myself re-defining and > extending some of the core Pyramid functionality, which up to now was > relatively painless (one of the nicest features of Pyramid IMO, it's not > very opinionated). Today I hit a strange corner case though, which I > haven't been able to workaround the way I'd like to. > > Some background: instead of setting up routes from Python code, I'm using > JSON hyper-schema to automatically generate routes from my resource > schema's. The routes are embedded in the hyper-schema 'link' relations, as > URI templates very much like what pyramid.config.Configurator.add_route > uses. Because the routes for each resource are completely embedded into > their schema, and are also used to generate link relations from resource > instance attributes, the route URI templates use resource attribute names > and hence may be ambiguous when used in functions referring different > resource classes. Example: I have an 'account' resource with a 'self' > relation defined by a route '{name}', and a 'projects' relation defined by > a route '{name}/projects'. At the same time I have a 'project' resource > that has a 'self' relation defined by a route '{account}/projects/{name}'. > In other words: the 'name' variable refers to an account name in the first > 2 URI templates, but to a project name in the last one. > > For reasons not relevant for this discussion I don't want to change the > route URI template definitions, and I don't want to embed additional > information in the resource schema's to disambiguate URI template > variables. Somehow, I want to be able to include an URI template variable > mapping where the view callable is declared using the view_config > decorator, so I can lookup which entries in the request matchdict > correspond with which attributes of my resource classes. So I tried to > create my own view_config decorator that extends pyramid.view.view_config, > looking somewhat like this: > > import pyramid.view > class view_config(pyramid.view.view_config): > def __init__(self, matchdict_attributes, **kwargs): > super(view_config, self).__init__(**kwargs) > self.matchdict_attributes = matchdict_attributes > def __call__(self, wrapped): > f = super(view_config, self).__call__(wrapped) > m = self.matchdict_attributes > def wrapped_f(*args): > return f(*args, matchdict_attributes=m) > return wrapped_f > > > > > The basic idea is that I simply want to add an extra initialisation > parameter to my view_config decorator, which is passed to the wrapped > method when it is called. > > For some reason when I use this decorator, the view callable is not found > by the route scan anymore. I don't get any syntax errors or runtime errors, > it's just that the any view callables declared with this decorator appear > to be ignored. Suspecting a problem in my decorator, I reduced it to the > following: > > class view_config(pyramid.view.view_config): > def __init__(self, **kwargs): > super(view_config, self).__init__(**kwargs) > > def __call__(self, wrapped): > return super(view_config, self).__call__(wrapped) > > > This decorator basically does nothing but directly wrap the Pyramid > view_config decorator, but even using this decorator, my view callables are > ignored by Pyramid. > > So I removed the __call__ method altogether, and declaring my view > callables with that decorator everything works. So it seems something is > going on in pyramid.view.view_config.__call__ which breaks the > configuration scan for view callables if you override the __call__ method > of the standard view_config decorator. > > I looked up the source code of the pyramid.view.view_config.__call__ > decorator method and pasted it verbatim in my derived decorator class, and > that works as well. I can't get it to work without duplicating any Pyramid > framework code though. > > Looking at the pyramid.view.view_config.__call__ code, there's a few > things I don't really follow, some venusian callback stuff that uses the > module name, but nothing directly indicating why I cannot override the > method in my own class without breaking route scanning... > > Does anyone know what's going on here? What am I missing? > > Thanks and regards, Wouter Bijlsma >
I don't know the solution, but I had the same problem. I found that you cannot call view_config.__call__ from within your subclass' __call__ method. To workaround this I just copied the code from view_config.__call__ into my class' __call__ method. It's only about 20 lines, so I'm not too concerned about the maintainability of the workaround. -- Jason -- You received this message because you are subscribed to the Google Groups "pylons-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discuss+unsubscr...@googlegroups.com. To post to this group, send email to pylons-discuss@googlegroups.com. Visit this group at http://groups.google.com/group/pylons-discuss. For more options, visit https://groups.google.com/groups/opt_out.