Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AttributeError: can't set attribute

I am working on a legacy django project, in there somewhere there is a class defined as follows;

from django.http import HttpResponse  class Response(HttpResponse):     def __init__(self, template='', calling_context='' status=None):         self.template = template         self.calling_context = calling_context         HttpResponse.__init__(self, get_template(template).render(calling_context), status) 

and this class is used in views as follows

def some_view(request):     #do some stuff     return Response('some_template.html', RequestContext(request, {'some keys': 'some values'})) 

this class was mainly created so that they could use it to perform assertions in the unit tests .i.e they are not using django.test.Client to test the views but rather they create a mock request and pass that to view as(calling the view as a callable) in the tests as follows

def test_for_some_view(self):     mock_request = create_a_mock_request()     #call the view, as a function     response = some_view(mock_request) #returns an instance of the response class above     self.assertEquals('some_template.html', response.template)     self.assertEquals({}, response.context) 

The problem is that half way through the test suite(quite a huge test suite), some tests begin blowing up when executing the

return Response('some_template.html', RequestContext(request, {'some keys': 'some values'})) 

and the stack trace is

self.template = template AttributeError: can't set attribute  

the full stack trace looks something like

====================================================================== ERROR: test_should_list_all_users_for_that_specific_sales_office  ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/austiine/Projects/mped/console/metrics/tests/unit/views/sales_office_views_test.py",   line 106, in test_should_list_all_users_for_that_specific_sales_office     response = show(request, sales_office_id=sales_office.id) File "/Users/austiine/Projects/mped/console/metrics/views/sales_office_views.py", line 63, in show     "sales_office_users": sales_office_users})) File "/Users/austiine/Projects/mped/console/metrics/utils/response.py", line 9, in __init__     self.template = template     AttributeError: can't set attribute 

the actual failing test is

def test_should_list_all_users_for_that_specific_sales_office(self):     user_company = CompanyFactory.create()     request = self.mock_request(user_company)     #some other stuff      #calling the view     response = show(request, sales_office_id=sales_office.id)     self.assertIn(user, response.calling_context["sales_office_users"])     self.assertNotIn(user2, response.calling_context["sales_office_users"]) 

code for the show view

def show(request, sales_office_id):     user = request.user     sales_office = []     sales_office_users = []     associated_market_names = []     try:         sales_office = SalesOffice.objects.get(id=sales_office_id)         sales_office_users = User.objects.filter(userprofile__sales_office=sales_office)         associated_market_names = Market.objects.filter(id__in=           (sales_office.associated_markets.all())).values_list("name", flat=True)         if user.groups.all()[0].name == UserProfile.COMPANY_AO:             associated_market_names = [market.name for market in sales_office.get_sales_office_user_specific_markets(user)]         except:             pass     return Response("sales_office/show.html", RequestContext(request, {'keys': 'values'})) 
like image 842
austiine Avatar asked Dec 10 '14 08:12

austiine


People also ask

Can't set attribute values?

How is it possible? The explanation you are getting this error is that you are naming the setter method mistakenly. You have named the setter method as set_x which is off base, this is the reason you are getting the Attribute Error.

How do I fix attribute error in Python?

Solution for AttributeError Errors and exceptions in Python can be handled using exception handling i.e. by using try and except in Python. Example: Consider the above class example, we want to do something else rather than printing the traceback Whenever an AttributeError is raised.

What is @property in Python?

The @property Decorator In Python, property() is a built-in function that creates and returns a property object. The syntax of this function is: property(fget=None, fset=None, fdel=None, doc=None) where, fget is function to get value of the attribute. fset is function to set value of the attribute.

How do you create a class property in Python?

Python property() function returns the object of the property class and it is used to create property of a class. Parameters: fget() – used to get the value of attribute. fset() – used to set the value of attribute.


1 Answers

This answer doesn't address the specifics of this question, but explains the underlying issue. This specific exception "AttributeError: can't set attribute" is raised (see source) when the attribute you're attempting to change is actually a property that doesn't have a setter. If you have access to the library's code, adding a setter would solve the problem.

EDIT: updated source link to new location in the code.

Edit2:

Example of a setter:

class MAMLMetaLearner(nn.Module):     def __init__(             self,             args,             base_model,              inner_debug=False,             target_type='classification'     ):         super().__init__()         self.args = args  # args for experiment         self.base_model = base_model         assert base_model is args.model          self.inner_debug = inner_debug         self.target_type = target_type      @property     def lr_inner(self) -> float:         return self.args.inner_lr      @lr_inner.setter     def lr_inner(self, new_val: float):         self.args.inner_lr = new_val 
like image 104
yoniLavi Avatar answered Oct 02 '22 18:10

yoniLavi