1

I'm getting an error when attempting to read a JSON file:

def get_mocked_json(self, filename):
    f = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../fixtures', filename)
    if os.path.exists(f) is True:
        return json.loads(f.read())
    else:
        return 'mocked.json'

This is the error:

           if os.path.exists(f) is True:
---->          return json.loads(f.read())
           else:
               return 'mocked.json'

AttributeError: 'str' object has no attribute 'read'

Any help in what I am doing wrong would be much appreciated.

2
  • ' '.join() results in a string type. so you're performing .read() on a string Commented Aug 31, 2017 at 13:21
  • 1
    f - is your string with path, you can not call read() method on string Commented Aug 31, 2017 at 13:21

1 Answer 1

2

Your f is just a string and strings can't be read. I think the source of the confusion here is that the os.path functions just ensure that the string represents a valid file-path on your operating system.

To actually read it, you need to open the file first. That will return a stream that can be read:

def get_mocked_json(self, filename):
    f = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../fixtures', filename)
    if os.path.exists(f) is True:
        with open(f) as fin:  # this is new
            return json.loads(fin.read())
    else:
        ...

Note that if os.path.exists(...) could be subject to race conditions. What would happen if between the if and the open the file was removed by another process? Or if you don't have permission to open it?

This can be avoided by trying to open it and handling the case where it wasn't possible:

def get_mocked_json(self, filename):
    f = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../fixtures', filename)
    try:
        with open(f) as fin:
            return json.loads(fin.read())
    except Exception:  # or IOError
        ...
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @MSeifert much, appreciated

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.