AttributeError: can't set attribute

90,005

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
Share:
90,005
austiine
Author by

austiine

Application Developer at ThoughtWorks

Updated on February 10, 2022

Comments

  • austiine
    austiine over 2 years

    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'}))