Sean W.
Sean W.

Reputation: 5142

Have I found a bug in Python's str.endswith()?

According to the Python documentation:

str.endswith(suffix[, start[, end]])

Return True if the string ends with the specified suffix, otherwise return False. suffix can also be a tuple of suffixes to look for. With optional start, test beginning at that position. Withoptional end, stop comparing at that position.

Changed in version 2.5: Accept tuples as suffix.

The following code should return True, but it returns False in Python 2.7.3:

"hello-".endswith(('.', ',', ':', ';', '-' '?', '!'))

It seems str.endswith() ignores anything beyond the forth tuple element:

>>> "hello-".endswith(('.', ',', ':', '-', ';' '?', '!'))
>>> True
>>> "hello;".endswith(('.', ',', ':', '-', ';' '?', '!'))
>>> False

Have I found a bug, or am I missing something?

Upvotes: 0

Views: 1946

Answers (3)

Rohit Jain
Rohit Jain

Reputation: 213351

or am I missing something?

You're missing a comma after the ';' in your tuple:

>>> "hello;".endswith(('.', ',', ':', '-', ';' '?', '!'))
                                         #    ^
                                         # comma missing
False

Due to this, ; and ? are concatenated. So, the string ending with ;? will return True for this case:

>>> "hello;?".endswith(('.', ',', ':', '-', ';' '?', '!'))
True

After adding a comma, it would work as expected:

>>> "hello;".endswith(('.', ',', ':', '-', ';', '?', '!'))
True

Upvotes: 10

Chris L
Chris L

Reputation: 53

It has already been pointed out that adjacent string literals are concatenated, but I wanted to add a little additional information and context.

This is a feature that is shared with (and borrowed from) C.

Additionally, this is doesn't act like a concatenation operator like '+', and is treated identically as if they were literally joined together in the source without any additional overhead.

For example:

>>> 'a' 'b' * 2
'abab'

Whether this is useful feature or an annoying design is really a matter of opinion, but it does allow for breaking up string literals among multiple lines by encapsulating the literals within parentheses.

>>> print("I don't want to type this whole string"
          "literal all on one line.")
I don't want to type this whole stringliteral all on one line.

That type of usage (along with being used with #defines) is why it was useful in C in the first place and was subsequently brought along in Python.

Upvotes: 0

mitchelllc
mitchelllc

Reputation: 1657

If you write tuple as

>>> tuple_example = ('.', ',', ':', '-', ';' '?', '!')

then the tuple will become

>>> tuple_example
('.', ',', ':', '-', ';?', '!')
                          ^
                   # concatenate together 

So that is why return False

Upvotes: 0

Related Questions