Search code examples
pythonpropertiesstatic-methodsclass-method

Property Function Returns Property Object instead of Value


I am having an issue with property methods in my code. I'm building a library and I'm making the tests for it. Part of the testing is to make sure the library handles the json api response properly. I have a very large and long amount of json responses that I consolidated into one file that I want to reference in my tests. My first thought is to make separate classes and property functions that return the json for each call. Ideally I wanted to make these staticmethods and classmethods so that I wouldn't have to instantiate the object. i.e. return_value=call_json.Login.correct_login. The problem is when I reference the function in my tests it returns the property object instead of the dictionary.

For example:

from . import call_json
import pytest

LOGIN_CALL = call_json.Login.correct_call

Class TestLogin:
    @pytest.fixture
    def api_mock(self, caplog):
        (api call mock & objects initialized)

    def test_correct_login(self, api_mock):
        self.mock_api.return_value = (LOGIN_CALL, 200)
        # The api call responds with a tuple of (dict, 200)

call_json.py:

class Login:

    @property
    @staticmethod
    def correct_call():
        return {code: 0, token: 'tk', ID: 'id'}

The test fails because the LOGIN_CALL returns a property object instead of dictionary. What am I doing wrong?

Is there a more efficient or pythonic way to format the call_json.py to allow for dictionaries or lists to be easily accessed across many files?


Solution

  • You can fix it by changing the order of the decorators and using @classmethod instead of @staticmethod:

    Requires python 3.9+

    class Login:
        @classmethod
        @property
        def correct_call(cls):
            return {'code': 0, 'token': 'tk', 'ID': 'id'}
    

    Looks like the above method is planned to be deprecated in 3.11+. Remind me to update if indeed they go ahead with this.