As CSV is a very loosely defined interpretation, there are several ways that the data can be stored. This is represented in the csv module as dialects. For example, the values can be delimited by commas, semicolons, or tabs. The list of default accepted dialects can be displayed by calling csv.list_dialect.
But dialects can also be inferred from the file itself through the Sniffer class. The Sniffer class analyzes a sample of the file (or the whole file) and returns a dialect object to allow reading in the proper way.
Notice that the file is open with no new lines, to not make any assumptions about it:
>>> with ...