Eefret
Eefret

Reputation: 4774

Weird behaviour with len and str.splitlines()

I'm making a HTTP request with the requests library and I want to make a Simple Response Object that parses my data. The problem I'm having is the following. When passing the response object to my ApiResponse I split the Response.text in lines, to count them and know if it has multiple or single lines. the problem is that the splitlines list gives me an error when applying len() to that but in the console it works ok.

This is the class:

class ApiResponse(object):
pattern = re.compile(r'([a-zA-Z]+): ([a-zA-Z0-9]+)')  # original ([a-zA-Z]+)\: ([a-zA-Z0-9]+)
response_type = ResponseType.OK
response_mode = ResponseMode.SINGLE

def __init__(self, r: resp):
    self.r = r
    self.parse(r)
    self.data = None

def parse(self, r: resp):
    """
    Method that parses the response from the API
    :param r:Response
    """
    if r.status_code != 200:
        self.response_type = ResponseType.ERR

    if len(r.text.splitlines()) > 1:
        self.response_mode = ResponseMode.MULTI

    for line in r.text.splitlines():
        match = self.pattern.search(line)
        if match is None:
            break
        print(match.group(1, 2))  # REMOVE testing
        self.response_type = ResponseType[match.group(1)]

This is the console output:

>>> import sys
>>> print(sys.version)
3.4.2 (default, Oct  8 2014, 13:08:17) 
[GCC 4.9.1]
>>> import requests
>>> from clickapy.response import ApiResponse
>>> r = requests.get(API_URL, {'user': USER, 'password': PASS, 'api_id': API_ID})
>>> api_response = ApiResponse(r)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/eefret/PycharmProjects/clickapy/clickapy/response.py", line 32, in __init__
    self.parse(r)
  File "/home/eefret/PycharmProjects/clickapy/clickapy/response.py", line 43, in parse
    if len(r.text.splitlines()) > 1:
TypeError: object of type 'builtin_function_or_method' has no len()
>>> len(r.text.splitlines())
1

Why this is happening? It doesn't make sense to me, I'm executing the same pieces of code, any help or feedback is welcome.

Upvotes: 3

Views: 426

Answers (1)

Eefret
Eefret

Reputation: 4774

A friend of mine (all credits to Mariano Garcia) has helped me and as he doesn't have SO account I will post what solved this behavior, my console was enforcing utf-8 but internally the text still had to be encoded so what solved this changing this if len(r.text.splitlines()) > 1: to this if len(r.text.encode("utf-8").splitlines()) > 1:

The complete code :

class ApiResponse(object):
    pattern = re.compile(r'([a-zA-Z]+): ([a-zA-Z0-9]+)')  # original ([a-zA-Z]+)\: ([a-zA-Z0-9]+)
    response_type = ResponseType.OK
    response_mode = ResponseMode.SINGLE

    def __init__(self, r: resp):
        self.r = r
        self.parse(r)
        self.data = None

    def parse(self, r: resp):
        """
        Method that parses the response from the API
        :param r:Response
        """
        if r.status_code != 200:
            self.response_type = ResponseType.ERR

        if len(r.text.encode("utf-8").splitlines()) > 1:
            self.response_mode = ResponseMode.MULTI

        for line in r.text.splitlines():
            match = self.pattern.search(line)
            if match is None:
                break
            print(match.group(1, 2))  # REMOVE testing
            self.response_type = ResponseType[match.group(1)]

Upvotes: 1

Related Questions