0

I am using the Django Rest Framework to build an api, and have an implementation on my development machine. I wanted to quickly deploy it today and it is proving far more error prone than I expected. I have re-installed dependancies, re-installed Django, spent hours hunting down bugs, but this latest one has defeated me and Google.

On the development machine, when I call one of the views from the framework I get the correct response (minus the static files but I'll deal with that later.) On the deployment machine however, I get this error:

'SplitResult' object has no attribute '_replace'

The traceback goes through a template tag in the rest framework, but the error seems to be thrown in urlobject in this method:

def __replace(self, **replace):
        """Replace a field in the ``urlparse.SplitResult`` for this URL."""
        return type(self)(urlparse.urlunsplit(
            urlparse.urlsplit(self)._replace(**replace))) 

I cannot reproduce this on my development machine, and I cannot find any references to this error anywhere. Just in case I have tried it on the deployment server with Django 1.2, 1.3, and 1.4, but the error seems to be unrelated to Django itself.

Here is the full traceback:

Django Version: 1.3.1
Python Version: 2.5.2
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'staticfiles',
 'django.contrib.admin',
 'django.contrib.admindocs',
 'char',
 'djangorestframework']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.5/site-packages/django/views/generic/base.py" in view
  47.             return self.dispatch(request, *args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
  39.         resp = view_func(*args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/views/decorators/csrf.py" in wrapped_view
  52.         return view_func(*args, **kwargs)
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/django-rest-framework/djangorestframework/views.py" in dispatch
  243.         return self.final(request, response, *args, **kwargs)
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/django-rest-framework/djangorestframework/views.py" in final
  196.         return self.render(response)
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/django-rest-framework/djangorestframework/mixins.py" in render
  251.             content = renderer.render(response.cleaned_content, media_type)
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/django-rest-framework/djangorestframework/renderers.py" in render
  351.         ret = template.render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render
  123.             return self._render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in _render
  117.         return self.nodelist.render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render
  744.                 bits.append(self.render_node(node, context))
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render_node
  757.         return node.render(context)
File "/usr/lib/python2.5/site-packages/django/template/loader_tags.py" in render
  127.         return compiled_parent._render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in _render
  117.         return self.nodelist.render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render
  744.                 bits.append(self.render_node(node, context))
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render_node
  757.         return node.render(context)
File "/usr/lib/python2.5/site-packages/django/template/defaulttags.py" in render
  311.             return self.nodelist_true.render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render
  744.                 bits.append(self.render_node(node, context))
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render_node
  757.         return node.render(context)
File "/usr/lib/python2.5/site-packages/django/template/defaulttags.py" in render
  227.                 nodelist.append(node.render(context))
File "/usr/lib/python2.5/site-packages/django/template/defaulttags.py" in render
  500.         output = self.nodelist.render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render
  744.                 bits.append(self.render_node(node, context))
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render_node
  757.         return node.render(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in render
  792.             output = self.filter_expression.resolve(context)
File "/usr/lib/python2.5/site-packages/django/template/base.py" in resolve
  536.                 new_obj = func(obj, *arg_vals)
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/django-rest-framework/djangorestframework/templatetags/add_query_param.py" in add_query_param
  7.     return unicode(URLObject(url).with_query(param))
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/urlobject/lib/urlobject/urlobject.py" in with_query
  117.         return self.__replace(query=query)
File "/home/wfrp/wfrp-django/DjangoWfrp/external apps/urlobject/lib/urlobject/urlobject.py" in __replace
  181.             urlparse.urlsplit(self)._replace(**replace)))

Exception Type: AttributeError at /api/
Exception Value: 'SplitResult' object has no attribute '_replace'

This is my first time on Stack Overflow — thanks for the help.

1
  • My guess is python version mismatch. My 2.7 does indeed have a _replace but I can't find docs on it. Commented Apr 10, 2012 at 18:29

1 Answer 1

1

I suspect your development and deployment machines are running different Python versions. The Python docs for SplitResult don't mention anything about the internal _replace method, but the leading underscore suggests that it is an internal API. This is a Django Rest Framework bug, I suggest filing a bug report with them.

If you're curious, SplitResult is a subclass of namedtuple (introduced in Python 2.6). It takes kwargs and returns a new SplitResult with the relevant values replaced.

In [16]: sr = urlparse.urlsplit("http:///www.google.com")

In [17]: sr
Out[17]: SplitResult(scheme='http', netloc='', path='/www.google.com', query='', fragment='')

In [18]: sr._replace(scheme='https')
Out[18]: SplitResult(scheme='https', netloc='', path='/www.google.com', query='', fragment='')

I believe the version of SplitResult in Python < 2.6 was a subclass of tuple, which does not have a _replace method, which would explain the error that you are seeing

Sign up to request clarification or add additional context in comments.

1 Comment

Of course! That's brilliant, thank you. I think the Python version did enter my mind because of the namedtuple, but I thought my server had 2.5 so didn't check. It is, of course, actually 2.4. Many thanks. I would +1 your answer but I don't have the reputation yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.