CleverCSV is a Python package for handling messy CSV files.


Github Actions Build Status PyPI version Documentation Status Downloads Binder

CleverCSV provides a drop-in replacement for the Python csv package with improved dialect detection for messy CSV files. It also provides a handy command line tool that can standardize a messy file or generate Python code to import it.

Useful links:


Contents: Quick Start | Introduction | Installation | Usage | Python Library | Command-Line Tool | Version Control Integration | Contributing | Notes


Quick Start

Click here to go to the introduction with more details about CleverCSV. If you're in a hurry, below is a quick overview of how to get started with the CleverCSV Python package and the command line interface.

For the Python package:

# Import the package
>>> import clevercsv

# Load the file as a list of rows
# This uses the imdb.csv file in the examples directory
>>> rows = clevercsv.read_table('./imdb.csv')

# Load the file as a Pandas Dataframe
# Note that df = pd.read_csv('./imdb.csv') would fail here
>>> df = clevercsv.read_dataframe('./imdb.csv')

# Use CleverCSV as drop-in replacement for the Python CSV module
# This follows the Sniffer example: https://docs.python.org/3/library/csv.html#csv.Sniffer
# Note that csv.Sniffer would fail here
>>> with open('./imdb.csv', newline='') as csvfile:
...     dialect = clevercsv.Sniffer().sniff(csvfile.read())
...     csvfile.seek(0)
...     reader = clevercsv.reader(csvfile, dialect)
...     rows = list(reader)

And for the command line interface:

>> df">
# Install the full version of CleverCSV (this includes the command line interface)
$ pip install clevercsv[full]

# Detect the dialect
$ clevercsv detect ./imdb.csv
Detected: SimpleDialect(',', '', '\\')

# Generate code to import the file
$ clevercsv code ./imdb.csv

import clevercsv

with open("./imdb.csv", "r", newline="", encoding="utf-8") as fp:
    reader = clevercsv.reader(fp, delimiter=",", quotechar="", escapechar="\\")
    rows = list(reader)

# Explore the CSV file as a Pandas dataframe
$ clevercsv explore -p imdb.csv
Dropping you into an interactive shell.
CleverCSV has loaded the data into the variable: df
>>> df

Introduction

  • CSV files are awesome! They are lightweight, easy to share, human-readable, version-controllable, and supported by many systems and tools!
  • CSV files are terrible! They can have many different formats, multiple tables, headers or no headers, escape characters, and there's no support for recording metadata!

CleverCSV is a Python package that aims to solve some of the pain points of CSV files, while maintaining many of the good things. The package automatically detects (with high accuracy) the format (dialect) of CSV files, thus making it easier to simply point to a CSV file and load it, without the need for human inspection. In the future, we hope to solve some of the other issues of CSV files too.

CleverCSV is based on science. We investigated thousands of real-world CSV files to find a robust way to automatically detect the dialect of a file. This may seem like an easy problem, but to a computer a CSV file is simply a long string, and every dialect will give you some table. In CleverCSV we use a technique based on the patterns of row lengths of the parsed file and the data type of the resulting cells. With our method we achieve 97% accuracy for dialect detection, with a 21% improvement on non-standard (messy) CSV files compared to the Python standard library.

We think this kind of work can be very valuable for working data scientists and programmers and we hope that you find CleverCSV useful (if there's a problem, please open an issue!) Since the academic world counts citations, please cite CleverCSV if you use the package. Here's a BibTeX entry you can use:

@article{van2019wrangling,
        title = {Wrangling Messy {CSV} Files by Detecting Row and Type Patterns},
        author = {{van den Burg}, G. J. J. and Naz{\'a}bal, A. and Sutton, C.},
        journal = {Data Mining and Knowledge Discovery},
        year = {2019},
        volume = {33},
        number = {6},
        pages = {1799--1820},
        issn = {1573-756X},
        doi = {10.1007/s10618-019-00646-y},
}

And of course, if you like the package please spread the word! You can do this by Tweeting about it (#CleverCSV) or clicking the ⭐️ on GitHub!

Installation

CleverCSV is available on PyPI. You can install either the full version, which includes the command line interface and all optional dependencies, using

$ pip install clevercsv[full]

or you can install a lighter, core version of CleverCSV with

$ pip install clevercsv

Usage

CleverCSV consists of a Python library and a command line tool called clevercsv.

Python Library

We designed CleverCSV to provide a drop-in replacement for the built-in CSV module, with some useful functionality added to it. Therefore, if you simply want to replace the builtin CSV module with CleverCSV, you can import CleverCSV as follows, and use it as you would use the builtin csv module.

import clevercsv

CleverCSV provides an improved version of the dialect sniffer in the CSV module, but it also adds some useful wrapper functions. These functions automatically detect the dialect and aim to make working with CSV files easier. We currently have the following helper functions:

  • detect_dialect: takes a path to a CSV file and returns the detected dialect
  • read_table: automatically detects the dialect and encoding of the file, and returns the data as a list of rows. A version that returns a generator is also available: stream_table
  • read_dataframe: detects the dialect and encoding of the file and then uses Pandas to read the CSV into a DataFrame. Note that this function requires Pandas to be installed.
  • read_dicts: detect the dialect and return the rows of the file as dictionaries, assuming the first row contains the headers. A streaming version called stream_dicts is also available.
  • write_table: write a table (a list of lists) to a file using the RFC-4180 dialect.

Of course, you can also use the traditional way of loading a CSV file, as in the Python CSV module:

import clevercsv

with open("data.csv", "r", newline="") as fp:
  # you can use verbose=True to see what CleverCSV does
  dialect = clevercsv.Sniffer().sniff(fp.read(), verbose=False)
  fp.seek(0)
  reader = clevercsv.reader(fp, dialect)
  rows = list(reader)

For large files, you can speed up detection by supplying a smaller sample to the sniffer, for example:

dialect = clevercsv.Sniffer().sniff(fp.read(10000))

You can also speed up encoding detection by installing cCharDet, it will automatically be used when it is available on the system.

That's the basics! If you want more details, you can look at the code of the package, the test suite, or the API documentation. If you run into any issues or have comments or suggestions, please open an issue on GitHub.

Command-Line Tool

To use the command line tool, make sure that you install the full version of CleverCSV (see above).

The clevercsv command line application has a number of handy features to make working with CSV files easier. For instance, it can be used to view a CSV file on the command line while automatically detecting the dialect. It can also generate Python code for importing data from a file with the correct dialect. The full help text is as follows:

USAGE
  clevercsv [-h] [-v] [-V]  [
   
    ] ... [
    
     ]

ARGUMENTS
  
            The command to execute
  
     
                 The arguments of the command

GLOBAL OPTIONS
  -h (--help)     Display this help message.
  -v (--verbose)  Enable verbose mode.
  -V (--version)  Display the application version.

AVAILABLE COMMANDS
  code            Generate Python code for importing the CSV file
  detect          Detect the dialect of a CSV file
  explore         Drop into a Python shell with the CSV file loaded
  help            Display the manual of a command
  standardize     Convert a CSV file to one that conforms to RFC-4180
  view            View the CSV file on the command line using TabView

     
    
   

Each of the commands has further options (for instance, the code and explore commands have support for importing the CSV file as a Pandas DataFrame). Use clevercsv help for more information. Below are some examples for each command.

Note that each command accepts the -n or --num-chars flag to set the number of characters used to detect the dialect. This can be especially helpful to speed up dialect detection on large files.

Code

Code generation is useful when you don't want to detect the dialect of the same file over and over again. You simply run the following command and copy the generated code to a Python script!

$ clevercsv code imdb.csv

# Code generated with CleverCSV

import clevercsv

with open("imdb.csv", "r", newline="", encoding="utf-8") as fp:
    reader = clevercsv.reader(fp, delimiter=",", quotechar="", escapechar="\\")
    rows = list(reader)

We also have a version that reads a Pandas dataframe:

$ clevercsv code --pandas imdb.csv

# Code generated with CleverCSV

import clevercsv

df = clevercsv.read_dataframe("imdb.csv", delimiter=",", quotechar="", escapechar="\\")

Detect

Detection is useful when you only want to know the dialect.

$ clevercsv detect imdb.csv
Detected: SimpleDialect(',', '', '\\')

The --plain flag gives the components of the dialect on separate lines, which makes combining it with grep easier.

$ clevercsv detect --plain imdb.csv
delimiter = ,
quotechar =
escapechar = \

Explore

The explore command is great for a command-line based workflow, or when you quickly want to start working with a CSV file in Python. This command detects the dialect of a CSV file and starts an interactive Python shell with the file already loaded! You can either have the file loaded as a list of lists:

$ clevercsv explore milk.csv
Dropping you into an interactive shell.

CleverCSV has loaded the data into the variable: rows
>>>
>>> len(rows)
381

or you can load the file as a Pandas dataframe:

$ clevercsv explore -p imdb.csv
Dropping you into an interactive shell.

CleverCSV has loaded the data into the variable: df
>>>
>>> df.head()
                   fn        tid  ... War Western
0  titles01/tt0012349  tt0012349  ...   0       0
1  titles01/tt0015864  tt0015864  ...   0       0
2  titles01/tt0017136  tt0017136  ...   0       0
3  titles01/tt0017925  tt0017925  ...   0       0
4  titles01/tt0021749  tt0021749  ...   0       0

[5 rows x 44 columns]

Standardize

Use the standardize command when you want to rewrite a file using the RFC-4180 standard:

$ clevercsv standardize --output imdb_standard.csv imdb.csv

In this particular example the use of the escape character is replaced by using quotes.

View

This command allows you to view the file in the terminal. The dialect is of course detected using CleverCSV! Both this command and the standardize command support the --transpose flag, if you want to transpose the file before viewing or saving:

$ clevercsv view --transpose imdb.csv

Version Control Integration

If you'd like to make sure that you never commit a messy (non-standard) CSV file to your repository, you can install a pre-commit hook. First, install pre-commit using the installation instructions. Next, add the following configuration to the .pre-commit-config.yaml file in your repository:

repos:
  - repo: https://github.com/alan-turing-institute/CleverCSV-pre-commit
    rev: v0.6.6   # or any later version
    hooks:
      - id: clevercsv-standardize

Finally, run pre-commit install to set up the git hook. Pre-commit will now use CleverCSV to standardize your CSV files following RFC-4180 whenever you commit a CSV file to your repository.

Contributing

If you want to encourage development of CleverCSV, the best thing to do now is to spread the word!

If you encounter an issue in CleverCSV, please open an issue or submit a pull request. Don't hesitate, you're helping to make this project better for everyone! If GitHub's not your thing but you still want to contact us, you can send an email to gertjanvandenburg at gmail dot com instead. You can also ask questions on Gitter.

Note that all contributions to the project must adhere to the Code of Conduct.

The CleverCSV package was originally written by Gertjan van den Burg and came out of scientific research on wrangling messy CSV files by Gertjan van den Burg, Alfredo Nazabal, and Charles Sutton.

Notes

CleverCSV is licensed under the MIT license. Please cite our research if you use CleverCSV in your work.

Copyright (c) 2018-2021 The Alan Turing Institute.

Owner
The Alan Turing Institute
The UK's national institute for data science and artificial intelligence.
The Alan Turing Institute
Comments
  • Make CleverCSV a pre-commit hook

    Make CleverCSV a pre-commit hook

    Would you consider making CleverCSV a pre-commit hook, by adding a .pre-commit-hooks.yaml file to your repository? This would allow people to have csv files in their repositories to automatically check them whenever they want to commit them.

    The only thing missing to make it work is, as I understand:

    • An option to overwrite the input file instead of printing to STDOUT (I think this could be a flag, like --in-place)
    • The possibility of clevercsv to accept a list of file arguments to process.
    • (Probably implemented already) A different exit status whether the input file was altered (!=0) or not (=0).

    I can file a PR for the .pre-commit-hooks.yaml, if you agree (after the above points are implemented).

    Thanks for your consideration!

  • help for data type detection

    help for data type detection

    CleverCSV looks very promising ! I try to use this package to extract csv to database. We need detect datatype of each column. Is there anyway this package can help ? The other question, is it possible(performance/memory) we can handle multi GB data by using this package ?

    Thanks for help. hong

  • Date delimiter prevales on column delimiter

    Date delimiter prevales on column delimiter

    Hi everyone,

    I have a lot of files with long formated dates (with timestamps). The file is delimited by a "," but the timestamps splits hours, minutes, seconds... with a ":". Example : item1,item2,2022-03-28 17:24:10,item4,2022-01-02 22:43:59,item6

    I should have : Column 1 | Column 2 | Column 3 | Column 4 | Column 5 | Column 6 item1 | item 2 | 22-03...:10| item4 | 22-01...:59| item6 but it gives the following result : C 1 |C2| C3 |C4| C5 item1,item 2,2022-03-28 17|24|10,item4,2022-01-02 22|43|59,item6

    Same thing with some very surprising characters recognised as delimiters when the delimiter is really obvious and more frequent :

    4819736,lilly354128,fr,Alin,lilly354128,,,,Lilly,DARS,,2 rue des ezda,,4581350,SAINT LA FORET,,FR,+330000000,,,,,,,,,,,,644365,"""LE TEMPS DE DÉCOUVRIR...""","* COFFRET DÉCOUVERTE SEPT PARFUMS On this line, CleverCSV have found a delimiter.... and the delimiter is the star "*" ! I really don't understand the logic ?

    I have resolved this issue with a pre-analysis algorithm that verifies, when there are 2 potentials delimiters, if one of them verifies a common formats like, dates, time, adress, floating numbers (coma case). But the annoying thing is that I need to parse two times, one with my pre-analysis and then with CleverCSV. That could be very nice to have a Clever version for this too.

    Have a nice day !

  • Suggestion: Make Pandas dependency optional

    Suggestion: Make Pandas dependency optional

    Hello, First of all thanks for writing this cool library. Is it possible to make Pandas an optional dependency? From looking at the code briefly, it seems it should work without Pandas too if you are just dealing with reading csv files. There are projects that don't need Pandas but could use this library. Thanks

  • delimiter is not correct for some csv file

    delimiter is not correct for some csv file

    hi,

    We have a sample of csv file:

    bytearray(b'fake data'),20:53:06,2019-09-01T19:28:21
    bytearray(b'fake data'),19:33:15,2005-02-15T19:10:31
    bytearray(b'fake data'),10:43:05,1992-10-12T14:49:24
    bytearray(b'fake data'),10:36:49,1999-07-18T17:27:55
    bytearray(b'fake data'),03:33:35,1982-04-24T17:38:45
    bytearray(b'fake data'),14:49:47,1983-01-05T22:17:42
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    bytearray(b'fake data'),10:35:30,2006-10-27T02:30:45
    

    the delimiter guess by clevercsv is ":", it should be ",".

    Thanks.

  • detection is really slow in some cases

    detection is really slow in some cases

    Hey there, first of all, great project!

    The following commands takes a significant amount of time:

    > python3 -m timeit -n 1 -- "from clevercsv import Detector; Detector().detect('fileurl="file://$PROJECT_DIR$/../aaaaaa_aaaaaaa_aaaaa/.aaa/." filepath=$')" 
    1 loop, best of 5: 13.2 sec per loop
    python3 -m timeit "from clevercsv import Detector; Detector().detect('a'*18)" 
    1 loop, best of 5: 8.24 sec per loop
    
    

    After benchmarking a little bit, the apparent cause is that the unix_path and url regexes in the detector are susceptible to a ReDOS .

    These change, which replace the regexes with (hopefully) equivalent ones fixes the most oblivious issues:

    -    "url": "((https?|ftp):\/\/(?!\-))?(((([\p{L}\p{N}]*\-?[\p{L}\p{N}]+)+\.)+([a-z]{2,}|local)(\.[a-z]{2,3})?)|localhost|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\:\d{1,5})?))(\/[\p{L}\p{N}_\/()~?=&%\-\#\.:]*)?(\.[a-z]+)?",
    -    "unix_path": "(\/|~\/|\.\/)(?:[a-zA-Z0-9\.\-\_]+\/?)+",
    +    "url": "((https?|ftp):\/\/(?!\-))?(((?:[\p{L}\p{N}-]+\.)+([a-z]{2,}|local)(\.[a-z]{2,3})?)|localhost|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\:\d{1,5})?))(\/[\p{L}\p{N}_\/()~?=&%\-\#\.:]*)?(\.[a-z]+)?",
    +    "unix_path": "[~.]?(?:\/[a-zA-Z0-9\.\-\_]+)+\/?",
    

    New results:

    > python3 -m timeit -n 1 -- "from clevercsv import Detector; Detector().detect('fileurl="file://$PROJECT_DIR$/../aaaaaa_aaaaaaa_aaaaa/.aaa/." filepath=$')" 
    1 loop, best of 5: 4.17 msec per loop
    :0: UserWarning: The test results are likely unreliable. The worst time (347 msec) was more than four times slower than the best time (4.17 msec).
    > python3 -m timeit "from clevercsv import Detector; Detector().detect('a'*18)" 
    1 loop, best of 5: 217 usec per loop
    

    Python version: 3.8

  • Code generation UnicodeDecodeError

    Code generation UnicodeDecodeError

    UnicodeDecodeError

    'charmap' codec can't decode byte 0x9e in position 1563: character maps to

    at /usr/lib/python3.9/encodings/cp1254.py:23 in decode 19│ return codecs.charmap_encode(input,self.errors,encoding_table)[0] 20│ 21│ class IncrementalDecoder(codecs.IncrementalDecoder): 22│ def decode(self, input, final=False): → 23│ return codecs.charmap_decode(input,self.errors,decoding_table)[0] 24│ 25│ class StreamWriter(Codec,codecs.StreamWriter): 26│ pass 27│

  • delimiter error for json type data

    delimiter error for json type data

    we have attached file, clevercsv guess delimiter ':', instead of ',' The three data type are json, time without time zone and time with time zone.

    "{""fake"": ""json"", ""fake2"":""json2""}",13:31:38,06:00:04+01:00
    "{""fake"": ""json"", ""fake2"":""json2""}",22:13:29,14:20:11+02:00
    "{""fake"": ""json"", ""fake2"":""json2""}",04:37:27,22:04:28+03:00
    "{""fake"": ""json"", ""fake2"":""json2""}",04:25:28,23:12:53+01:00
    "{""fake"": ""json"", ""fake2"":""json2""}",21:04:15,08:23:58+02:00
    "{""fake"": ""json"", ""fake2"":""json2""}",10:37:03,11:06:42+05:30
    "{""fake"": ""json"", ""fake2"":""json2""}",10:17:24,23:38:47+06:00
    "{""fake"": ""json"", ""fake2"":""json2""}",00:02:51,20:04:45-06:00
    

    Would you please help to take a look ?

    Thanks hong

  • Is there a way to distinguish between ,, and ,

    Is there a way to distinguish between ,, and ,"", in the reader?

    PostgreSQL RDBMS has CSV export/import functionality (https://www.postgresql.org/docs/9.6/sql-copy.html) that has a quirk in its CSV format: they treat ,, as SQL NULL and ,"", as a zero length string value. These are different values, and it is important to be able to distinguish between them.

    Is there a way to parse a line like foo,,bar,"",baz as ['foo', None, bar, '', 'baz'] ? Without forking and playing with the state machine in C, of course. :-)

  • Add instructions on using pre-commit

    Add instructions on using pre-commit

    I believe this PR fixes #24.

    @lcnittl I made an attempt at adding the pre-commit hook myself (hope you don't mind). It turned out that registering the hook with the repo link will always require pre-commit to install CleverCSV from the repo, which requires compilation (as you discovered as well). ~~By using repo: local and specifying CleverCSV as a dependency, we ensure that the pre-compiled wheel will be installed from PyPI.~~

    Update for posterity: the solution we went with is to use a dummy package that depends on clevercsv[full], which contains the pre-commit hook. This PR has been updated with the new instructions.

  • Unicode characters cause UnicodeEncodeError from clevercsv.wrappers.write_table on Windows 10

    Unicode characters cause UnicodeEncodeError from clevercsv.wrappers.write_table on Windows 10

    Hello and thank you for your work on this excellent library! I'm running on a Windows 10 machine and encountering a UnicodeEncodeError when attempting to write data that includes Unicode using clevercsv.wrappers.write_table.

    It appears that adding an optional encoding argument to clevercsv.wrappers.write_table would fix this, as it works when I use the clevercsv.writer without the wrapper as a workaround (below).

    Workaround:

    with open("outfile.csv", "w", newline="", encoding="utf-8") as fp:
        w = clevercsv.writer(fp)
        w.writerows(data_list)
    

    Stack Trace:

    Traceback (most recent call last):
      File "<REDACTED>", line 143, in <module>
        report.create_csv_report()
      File "<REDACTED>", line 42, in create_csv_report
      File "<REDACTED>\lib\site-packages\clevercsv\wrappers.py", line 441, in write_table
        w.writerows(table)
      File "<REDACTED>\lib\site-packages\clevercsv\write.py", line 60, in writerows
        return self._writer.writerows(rows)
      File "<REDACTED>\local\programs\python\python37-32\lib\encodings\cp1252.py", line 19, in encode
        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
    UnicodeEncodeError: 'charmap' codec can't encode character '\u2033' in position 250: character maps to <undefined>
    
  • Please migrate away from setup.py

    Please migrate away from setup.py

    Hello!

    setup.py has been deprecated for a while now (although support hasn't yet bet removed). It would be nice if this project moved away from it before something actually breaks :)

    If you want to stick with setuptools, newer versions do support building via a PEP-617-style pyproject.toml file:

    • https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
    • https://peps.python.org/pep-0621

    You can see an example of a migration to pyproject.toml with setuptools that I did here: https://github.com/jaseg/python-mpv/pull/241

    Cheers,

  • Support Python 3.11

    Support Python 3.11

    The csv module now disallows empty strings in Dialect escapechar or quotechar properties bpo-20028.

    Maintain the current CleverCSV Dialect interface, but generate Dialects that Python 3.11 is happy with.

    Fixes: #74

  • Testsuite failure with Python 3.11

    Testsuite failure with Python 3.11

    Hello,

    Debian is currently migrating to Python 3.11 and the clevercsv testsuite fails with the following error:

    I: pybuild base:240: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build; python3.11 -m unittest discover -v -s tests/test_unit
    test_get_best_set_1 (test_consistency.ConsistencyTestCase.test_get_best_set_1) ... ok
    test_get_best_set_2 (test_consistency.ConsistencyTestCase.test_get_best_set_2) ... ok
    test_code_1 (test_console.ConsoleTestCase.test_code_1) ... ERROR
    /usr/lib/python3.11/unittest/case.py:622: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with outcome.testPartExecutor(self):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_code_2 (test_console.ConsoleTestCase.test_code_2) ... ERROR
    test_code_3 (test_console.ConsoleTestCase.test_code_3) ... ERROR
    /usr/lib/python3.11/unittest/case.py:622: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='ISO-8859-1'>
      with outcome.testPartExecutor(self):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_code_4 (test_console.ConsoleTestCase.test_code_4) ... ERROR
    test_code_5 (test_console.ConsoleTestCase.test_code_5) ... ERROR
    test_detect_base (test_console.ConsoleTestCase.test_detect_base) ... 
      test_detect_base (test_console.ConsoleTestCase.test_detect_base) (name='simple') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py:50: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="simple"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
      test_detect_base (test_console.ConsoleTestCase.test_detect_base) (name='escaped') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py:55: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="escaped"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_detect_opts_1 (test_console.ConsoleTestCase.test_detect_opts_1) ... ERROR
    /usr/lib/python3.11/unittest/case.py:622: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='windows-1252'>
      with outcome.testPartExecutor(self):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_detect_opts_2 (test_console.ConsoleTestCase.test_detect_opts_2) ... ERROR
    test_detect_opts_3 (test_console.ConsoleTestCase.test_detect_opts_3) ... ERROR
    test_standardize_1 (test_console.ConsoleTestCase.test_standardize_1) ... ERROR
    test_standardize_2 (test_console.ConsoleTestCase.test_standardize_2) ... ERROR
    test_standardize_3 (test_console.ConsoleTestCase.test_standardize_3) ... ERROR
    test_standardize_in_place (test_console.ConsoleTestCase.test_standardize_in_place) ... ERROR
    test_standardize_in_place_multi (test_console.ConsoleTestCase.test_standardize_in_place_multi) ... ok
    test_standardize_in_place_multi_noop (test_console.ConsoleTestCase.test_standardize_in_place_multi_noop) ... ok
    test_standardize_in_place_noop (test_console.ConsoleTestCase.test_standardize_in_place_noop) ... ok
    test_standardize_multi (test_console.ConsoleTestCase.test_standardize_multi) ... ok
    test_standardize_multi_encoding (test_console.ConsoleTestCase.test_standardize_multi_encoding) ... ok
    test_standardize_multi_errors (test_console.ConsoleTestCase.test_standardize_multi_errors) ... ok
    test_parse_builtin_1 (test_cparser.ParserTestCase.test_parse_builtin_1) ... ok
    test_parse_builtin_10 (test_cparser.ParserTestCase.test_parse_builtin_10) ... ok
    test_parse_builtin_11 (test_cparser.ParserTestCase.test_parse_builtin_11) ... ok
    test_parse_builtin_12 (test_cparser.ParserTestCase.test_parse_builtin_12) ... ok
    test_parse_builtin_13 (test_cparser.ParserTestCase.test_parse_builtin_13) ... ok
    test_parse_builtin_14 (test_cparser.ParserTestCase.test_parse_builtin_14) ... ok
    test_parse_builtin_15 (test_cparser.ParserTestCase.test_parse_builtin_15) ... ok
    test_parse_builtin_2 (test_cparser.ParserTestCase.test_parse_builtin_2) ... ok
    test_parse_builtin_3 (test_cparser.ParserTestCase.test_parse_builtin_3) ... ok
    test_parse_builtin_4 (test_cparser.ParserTestCase.test_parse_builtin_4) ... ok
    test_parse_builtin_5 (test_cparser.ParserTestCase.test_parse_builtin_5) ... ok
    test_parse_builtin_6 (test_cparser.ParserTestCase.test_parse_builtin_6) ... ok
    test_parse_builtin_7 (test_cparser.ParserTestCase.test_parse_builtin_7) ... ok
    test_parse_builtin_8 (test_cparser.ParserTestCase.test_parse_builtin_8) ... ok
    test_parse_builtin_9 (test_cparser.ParserTestCase.test_parse_builtin_9) ... ok
    test_parse_differ_1 (test_cparser.ParserTestCase.test_parse_differ_1) ... ok
    test_parse_differ_2 (test_cparser.ParserTestCase.test_parse_differ_2) ... ok
    test_parse_dq_1 (test_cparser.ParserTestCase.test_parse_dq_1) ... ok
    test_parse_dq_2 (test_cparser.ParserTestCase.test_parse_dq_2) ... ok
    test_parse_escape_1 (test_cparser.ParserTestCase.test_parse_escape_1) ... ok
    test_parse_escape_2 (test_cparser.ParserTestCase.test_parse_escape_2) ... ok
    test_parse_mix_double_escape_1 (test_cparser.ParserTestCase.test_parse_mix_double_escape_1) ... ok
    test_parse_no_delim_1 (test_cparser.ParserTestCase.test_parse_no_delim_1) ... ok
    test_parse_no_delim_2 (test_cparser.ParserTestCase.test_parse_no_delim_2) ... ok
    test_parse_no_delim_3 (test_cparser.ParserTestCase.test_parse_no_delim_3) ... ok
    test_parse_no_delim_4 (test_cparser.ParserTestCase.test_parse_no_delim_4) ... ok
    test_parse_no_delim_5 (test_cparser.ParserTestCase.test_parse_no_delim_5) ... ok
    test_parse_no_delim_6 (test_cparser.ParserTestCase.test_parse_no_delim_6) ... ok
    test_parse_other_1 (test_cparser.ParserTestCase.test_parse_other_1) ... ok
    test_parse_other_2 (test_cparser.ParserTestCase.test_parse_other_2) ... ok
    test_parse_other_3 (test_cparser.ParserTestCase.test_parse_other_3) ... ok
    test_parse_other_4 (test_cparser.ParserTestCase.test_parse_other_4) ... ok
    test_parse_other_5 (test_cparser.ParserTestCase.test_parse_other_5) ... ok
    test_parse_other_6 (test_cparser.ParserTestCase.test_parse_other_6) ... ok
    test_parse_quote_mismatch_1 (test_cparser.ParserTestCase.test_parse_quote_mismatch_1) ... ok
    test_parse_quote_mismatch_2 (test_cparser.ParserTestCase.test_parse_quote_mismatch_2) ... ok
    test_parse_quote_mismatch_3 (test_cparser.ParserTestCase.test_parse_quote_mismatch_3) ... ok
    test_parse_quote_mismatch_4 (test_cparser.ParserTestCase.test_parse_quote_mismatch_4) ... ok
    test_parse_return_quoted_1 (test_cparser.ParserTestCase.test_parse_return_quoted_1) ... ok
    test_parse_return_quoted_2 (test_cparser.ParserTestCase.test_parse_return_quoted_2) ... ok
    test_parse_return_quoted_3 (test_cparser.ParserTestCase.test_parse_return_quoted_3) ... ok
    test_parse_simple_1 (test_cparser.ParserTestCase.test_parse_simple_1) ... ok
    test_parse_simple_2 (test_cparser.ParserTestCase.test_parse_simple_2) ... ok
    test_parse_simple_3 (test_cparser.ParserTestCase.test_parse_simple_3) ... ok
    test_parse_simple_4 (test_cparser.ParserTestCase.test_parse_simple_4) ... ok
    test_parse_simple_5 (test_cparser.ParserTestCase.test_parse_simple_5) ... ok
    test_parse_simple_6 (test_cparser.ParserTestCase.test_parse_simple_6) ... ok
    test_parse_simple_7 (test_cparser.ParserTestCase.test_parse_simple_7) ... ok
    test_parse_single_1 (test_cparser.ParserTestCase.test_parse_single_1) ... ok
    test_delimiters (test_detect.DetectorTestCase.test_delimiters) ... ok
    test_detect (test_detect.DetectorTestCase.test_detect) ... ok
    test_has_header (test_detect.DetectorTestCase.test_has_header) ... ok
    test_has_header_regex_special_delimiter (test_detect.DetectorTestCase.test_has_header_regex_special_delimiter) ... ok
    test_abstraction_1 (test_detect_pattern.PatternTestCase.test_abstraction_1) ... ok
    test_abstraction_10 (test_detect_pattern.PatternTestCase.test_abstraction_10) ... ok
    test_abstraction_11 (test_detect_pattern.PatternTestCase.test_abstraction_11) ... ok
    test_abstraction_12 (test_detect_pattern.PatternTestCase.test_abstraction_12) ... ok
    test_abstraction_13 (test_detect_pattern.PatternTestCase.test_abstraction_13) ... ok
    test_abstraction_14 (test_detect_pattern.PatternTestCase.test_abstraction_14) ... ok
    test_abstraction_15 (test_detect_pattern.PatternTestCase.test_abstraction_15) ... ok
    test_abstraction_16 (test_detect_pattern.PatternTestCase.test_abstraction_16) ... ok
    test_abstraction_2 (test_detect_pattern.PatternTestCase.test_abstraction_2) ... ok
    test_abstraction_3 (test_detect_pattern.PatternTestCase.test_abstraction_3) ... ok
    test_abstraction_4 (test_detect_pattern.PatternTestCase.test_abstraction_4) ... ok
    test_abstraction_5 (test_detect_pattern.PatternTestCase.test_abstraction_5) ... ok
    test_abstraction_6 (test_detect_pattern.PatternTestCase.test_abstraction_6) ... ok
    test_abstraction_7 (test_detect_pattern.PatternTestCase.test_abstraction_7) ... ok
    test_abstraction_8 (test_detect_pattern.PatternTestCase.test_abstraction_8) ... ok
    test_abstraction_9 (test_detect_pattern.PatternTestCase.test_abstraction_9) ... ok
    test_fill_empties_1 (test_detect_pattern.PatternTestCase.test_fill_empties_1) ... ok
    test_pattern_score_1 (test_detect_pattern.PatternTestCase.test_pattern_score_1) ... ok
    test_pattern_score_2 (test_detect_pattern.PatternTestCase.test_pattern_score_2) ... ok
    test_pattern_score_3 (test_detect_pattern.PatternTestCase.test_pattern_score_3) ... ok
    test_bytearray (test_detect_type.TypeDetectorTestCase.test_bytearray) ... ok
    test_date (test_detect_type.TypeDetectorTestCase.test_date) ... ok
    test_datetime (test_detect_type.TypeDetectorTestCase.test_datetime) ... ok
    test_number (test_detect_type.TypeDetectorTestCase.test_number) ... ok
    test_type_score_1 (test_detect_type.TypeDetectorTestCase.test_type_score_1) ... ok
    test_type_score_2 (test_detect_type.TypeDetectorTestCase.test_type_score_2) ... ok
    test_type_score_3 (test_detect_type.TypeDetectorTestCase.test_type_score_3) ... ok
    test_unicode_alphanum (test_detect_type.TypeDetectorTestCase.test_unicode_alphanum) ... ok
    test_unix_path (test_detect_type.TypeDetectorTestCase.test_unix_path) ... ok
    test_url (test_detect_type.TypeDetectorTestCase.test_url) ... ok
    test_read_dict_fieldnames_chain (test_dict.DictTestCase.test_read_dict_fieldnames_chain) ... ok
    test_read_dict_fieldnames_from_file (test_dict.DictTestCase.test_read_dict_fieldnames_from_file) ... ok
    test_read_dict_fields (test_dict.DictTestCase.test_read_dict_fields) ... ok
    test_read_dict_no_fieldnames (test_dict.DictTestCase.test_read_dict_no_fieldnames) ... ok
    test_read_duplicate_fieldnames (test_dict.DictTestCase.test_read_duplicate_fieldnames) ... ok
    test_read_long (test_dict.DictTestCase.test_read_long) ... ok
    test_read_long_with_rest (test_dict.DictTestCase.test_read_long_with_rest) ... ok
    test_read_long_with_rest_no_fieldnames (test_dict.DictTestCase.test_read_long_with_rest_no_fieldnames) ... ok
    test_read_multi (test_dict.DictTestCase.test_read_multi) ... ok
    test_read_semi_sep (test_dict.DictTestCase.test_read_semi_sep) ... ok
    test_read_short (test_dict.DictTestCase.test_read_short) ... ok
    test_read_with_blanks (test_dict.DictTestCase.test_read_with_blanks) ... ok
    test_typo_in_extrasaction_raises_error (test_dict.DictTestCase.test_typo_in_extrasaction_raises_error) ... ok
    test_write_field_not_in_field_names_ignore (test_dict.DictTestCase.test_write_field_not_in_field_names_ignore) ... ok
    test_write_field_not_in_field_names_raise (test_dict.DictTestCase.test_write_field_not_in_field_names_raise) ... ok
    test_write_fields_not_in_fieldnames (test_dict.DictTestCase.test_write_fields_not_in_fieldnames) ... ok
    test_write_multiple_dict_rows (test_dict.DictTestCase.test_write_multiple_dict_rows) ... ok
    test_write_no_fields (test_dict.DictTestCase.test_write_no_fields) ... ok
    test_write_simple_dict (test_dict.DictTestCase.test_write_simple_dict) ... ok
    test_writeheader_return_value (test_dict.DictTestCase.test_writeheader_return_value) ... ok
    test_encoding_1 (test_encoding.EncodingTestCase.test_encoding_1) ... ok
    test_encoding_2 (test_encoding.EncodingTestCase.test_encoding_2) ... ok
    test_encoding_3 (test_encoding.EncodingTestCase.test_encoding_3) ... ok
    test_sniffer_fuzzing (test_fuzzing.FuzzingTestCase.test_sniffer_fuzzing) ... ok
    test_form_1 (test_normal_forms.NormalFormTestCase.test_form_1) ... ok
    test_form_2 (test_normal_forms.NormalFormTestCase.test_form_2) ... ok
    test_form_3 (test_normal_forms.NormalFormTestCase.test_form_3) ... ok
    test_form_4 (test_normal_forms.NormalFormTestCase.test_form_4) ... ok
    test_form_5 (test_normal_forms.NormalFormTestCase.test_form_5) ... ok
    test_filter_urls (test_potential_dialects.PotentialDialectTestCase.test_filter_urls) ... ok
    test_get_delimiters (test_potential_dialects.PotentialDialectTestCase.test_get_delimiters) ... ok
    test_get_quotechars (test_potential_dialects.PotentialDialectTestCase.test_get_quotechars) ... ok
    test_masked_by_quotechar (test_potential_dialects.PotentialDialectTestCase.test_masked_by_quotechar) ... ok
    test_no_delim (test_reader.ReaderTestCase.test_no_delim) ... ok
    test_read_bigfield (test_reader.ReaderTestCase.test_read_bigfield) ... ok
    test_read_eof (test_reader.ReaderTestCase.test_read_eof) ... ok
    test_read_eol (test_reader.ReaderTestCase.test_read_eol) ... ok
    test_read_escape (test_reader.ReaderTestCase.test_read_escape) ... ok
    test_read_linenum (test_reader.ReaderTestCase.test_read_linenum) ... ok
    test_read_oddinputs (test_reader.ReaderTestCase.test_read_oddinputs) ... ok
    test_simple (test_reader.ReaderTestCase.test_simple) ... ok
    test_with_gen (test_reader.ReaderTestCase.test_with_gen) ... ok
    test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) ... 
      test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='simple') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:95: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="simple"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
      test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='escaped') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:100: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="escaped"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
      test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='simple_nchar') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:115: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="simple_nchar"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
      test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='simple_encoding') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:120: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='latin1'>
      with self.subTest(name="simple_encoding"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_read_table (test_wrappers.WrappersTestCase.test_read_table) ... 
      test_read_table (test_wrappers.WrappersTestCase.test_read_table) (name='simple') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:126: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="simple"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
      test_read_table (test_wrappers.WrappersTestCase.test_read_table) (name='escaped') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:131: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="escaped"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_stream_table (test_wrappers.WrappersTestCase.test_stream_table) ... 
      test_stream_table (test_wrappers.WrappersTestCase.test_stream_table) (name='simple') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:161: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="simple"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
      test_stream_table (test_wrappers.WrappersTestCase.test_stream_table) (name='escaped') ... ERROR
    /<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py:166: ResourceWarning: unclosed file <_io.TextIOWrapper name=3 mode='w' encoding='UTF-8'>
      with self.subTest(name="escaped"):
    ResourceWarning: Enable tracemalloc to get the object allocation traceback
    test_write_dicts (test_wrappers.WrappersTestCase.test_write_dicts) ... 
      test_write_dicts (test_wrappers.WrappersTestCase.test_write_dicts) (name='dialect') ... ERROR
    test_write_table (test_wrappers.WrappersTestCase.test_write_table) ... 
      test_write_table (test_wrappers.WrappersTestCase.test_write_table) (name='dialect') ... ERROR
      test_write_table (test_wrappers.WrappersTestCase.test_write_table) (name='transposed') ... ERROR
    test_write_arg_valid (test_write.WriterTestCase.test_write_arg_valid) ... ok
    test_write_bigfield (test_write.WriterTestCase.test_write_bigfield) ... ok
    test_write_csv_dialect (test_write.WriterTestCase.test_write_csv_dialect) ... ok
    test_write_quoting (test_write.WriterTestCase.test_write_quoting) ... ok
    test_write_simpledialect (test_write.WriterTestCase.test_write_simpledialect) ... ok
    
    ======================================================================
    ERROR: test_code_1 (test_console.ConsoleTestCase.test_code_1)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 126, in test_code_1
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_code_2 (test_console.ConsoleTestCase.test_code_2)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 166, in test_code_2
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_code_3 (test_console.ConsoleTestCase.test_code_3)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 191, in test_code_3
        tmpfname = self._build_file(table, dialect, encoding=encoding)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_code_4 (test_console.ConsoleTestCase.test_code_4)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 232, in test_code_4
        tmpfname = self._build_file(table, dialect, encoding=encoding)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_code_5 (test_console.ConsoleTestCase.test_code_5)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 273, in test_code_5
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_detect_base (test_console.ConsoleTestCase.test_detect_base) (name='simple')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 51, in test_detect_base
        self._detect_test_wrap(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 34, in _detect_test_wrap
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_detect_base (test_console.ConsoleTestCase.test_detect_base) (name='escaped')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 56, in test_detect_base
        self._detect_test_wrap(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 34, in _detect_test_wrap
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_detect_opts_1 (test_console.ConsoleTestCase.test_detect_opts_1)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 72, in test_detect_opts_1
        tmpfname = self._build_file(table, dialect, encoding=encoding)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_detect_opts_2 (test_console.ConsoleTestCase.test_detect_opts_2)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 89, in test_detect_opts_2
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_detect_opts_3 (test_console.ConsoleTestCase.test_detect_opts_3)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 106, in test_detect_opts_3
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_standardize_1 (test_console.ConsoleTestCase.test_standardize_1)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 314, in test_standardize_1
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_standardize_2 (test_console.ConsoleTestCase.test_standardize_2)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 334, in test_standardize_2
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_standardize_3 (test_console.ConsoleTestCase.test_standardize_3)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 358, in test_standardize_3
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_standardize_in_place (test_console.ConsoleTestCase.test_standardize_in_place)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 379, in test_standardize_in_place
        tmpfname = self._build_file(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_console.py", line 28, in _build_file
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='simple')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 96, in test_read_dataframe
        self._df_test(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 27, in _df_test
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='escaped')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 101, in test_read_dataframe
        self._df_test(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 27, in _df_test
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='simple_nchar')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 116, in test_read_dataframe
        self._df_test(table, dialect, num_char=10)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 27, in _df_test
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_read_dataframe (test_wrappers.WrappersTestCase.test_read_dataframe) (name='simple_encoding')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 121, in test_read_dataframe
        self._df_test(table, dialect, num_char=10, encoding="latin1")
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 27, in _df_test
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_read_table (test_wrappers.WrappersTestCase.test_read_table) (name='simple')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 127, in test_read_table
        self._read_test(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 49, in _read_test
        tmpfname = self._write_tmpfile(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 43, in _write_tmpfile
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_read_table (test_wrappers.WrappersTestCase.test_read_table) (name='escaped')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 132, in test_read_table
        self._read_test(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 49, in _read_test
        tmpfname = self._write_tmpfile(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 43, in _write_tmpfile
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_stream_table (test_wrappers.WrappersTestCase.test_stream_table) (name='simple')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 162, in test_stream_table
        self._stream_test(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 57, in _stream_test
        tmpfname = self._write_tmpfile(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 43, in _write_tmpfile
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_stream_table (test_wrappers.WrappersTestCase.test_stream_table) (name='escaped')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 167, in test_stream_table
        self._stream_test(table, dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 57, in _stream_test
        tmpfname = self._write_tmpfile(table, dialect)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 43, in _write_tmpfile
        w = writer(tmpid, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_write_dicts (test_wrappers.WrappersTestCase.test_write_dicts) (name='dialect')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 258, in test_write_dicts
        self._write_test_dicts(items, exp, dialect=dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 238, in _write_test_dicts
        wrappers.write_dicts(items, tmpfname, **kwargs)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/wrappers.py", line 445, in write_dicts
        w = DictWriter(fp, fieldnames=fieldnames, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/dict_read_write.py", line 105, in __init__
        self.writer = writer(f, dialect, *args, **kwds)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_write_table (test_wrappers.WrappersTestCase.test_write_table) (name='dialect')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 215, in test_write_table
        self._write_test_table(table, exp, dialect=dialect)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 195, in _write_test_table
        wrappers.write_table(table, tmpfname, **kwargs)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/wrappers.py", line 409, in write_table
        w = writer(fp, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ======================================================================
    ERROR: test_write_table (test_wrappers.WrappersTestCase.test_write_table) (name='transposed')
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 219, in test_write_table
        self._write_test_table(table, exp, dialect=dialect, transpose=True)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/tests/test_unit/test_wrappers.py", line 195, in _write_test_table
        wrappers.write_table(table, tmpfname, **kwargs)
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/wrappers.py", line 409, in write_table
        w = writer(fp, dialect=dialect)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/<<PKGBUILDDIR>>/.pybuild/cpython3_3.11/build/clevercsv/write.py", line 32, in __init__
        self._writer = csv.writer(csvfile, dialect=self.dialect)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: "quotechar" must be a 1-character string
    
    ----------------------------------------------------------------------
    Ran 156 tests in 0.057s
    
    FAILED (errors=25)
    

    As you can see, it's the same error that's repeated. I can't promise anything, but I might try to submit a patch later.

  • Bump pypa/cibuildwheel from 2.11.1 to 2.11.2

    Bump pypa/cibuildwheel from 2.11.1 to 2.11.2

    Bumps pypa/cibuildwheel from 2.11.1 to 2.11.2.

    Release notes

    Sourced from pypa/cibuildwheel's releases.

    v2.11.2

    • 🛠 Updates CPython 3.11 to 3.11.0 - final release (#1327)
    • 🛠 Simplify the default macOS repair command (#1322)
    • 🛠 Fix the default MACOSX_DEPLOYMENT_TARGET on arm64 (#1312)
    • 🛠 Hide irrelevant pip warnings on linux (#1311)
    • 🐛 Fix a bug that caused the stdout and stderr of commands in containers to be in the wrong order Previously, stdout could appear after stderr. (#1324)
    • 📚 Added a FAQ entry describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
    • 📚 Other docs improvements
    Changelog

    Sourced from pypa/cibuildwheel's changelog.

    v2.11.2

    26 October 2022

    • 🛠 Updates CPython 3.11 to 3.11.0 - final release (#1327)
    • 🛠 Simplify the default macOS repair command (#1322)
    • 🛠 Fix the default MACOSX_DEPLOYMENT_TARGET on arm64 (#1312)
    • 🛠 Hide irrelevant pip warnings on linux (#1311)
    • 🐛 Fix a bug that caused the stdout and stderr of commands in containers to be in the wrong order Previously, stdout could appear after stderr. (#1324)
    • 📚 Added a FAQ entry describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
    • 📚 Other docs improvements
    Commits
    • a6732b1 Bump version: v2.11.2
    • 36a6101 Merge pull request #1311 from henryiii/henryiii/fix/rootpip2
    • 8672fee Merge pull request #1300 from mayeut/gha-3.11
    • b1b8ab5 Merge pull request #1322 from ankith26/update-delocate-default
    • 89a8cac Merge pull request #1324 from pypa/stderr-interleaving
    • db12084 tests: include check for upgrade notice too
    • dfb3e62 tests: use 3.11 final
    • f259bfd tests: add a check in tests for the pip warning
    • f252274 fix: hide root pip warning on Linux again
    • 1aa841b Merge pull request #1323 from pypa/docs-38
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Invalid abstract representation of the file with repeating newline

    Invalid abstract representation of the file with repeating newline

    I found that the make_abstract method does not correctly construct file abstraction for repeating newline.

    Some examples:

    # +--------------------------------+
    # | \n                             |
    # | \n                             |
    # | word, digit, bool, float\n     |
    # | dolorum,7539,true,88292972.3\n |
    # +--------------------------------+
    >>> make_abstraction(data, dialect).split("R")
    # ['', 'CDCDCDC', 'CDCDCDC']
    

    Another example:

    # +--------------------------------+
    # | Lorem Ipsum\n                  |
    # | Lorem Ipsum\n                  |
    # | \n                             |
    # | word, digit, bool, float\n     |
    # | dolorum,7539,true,88292972.3\n |
    # +--------------------------------+
    >>> make_abstraction(data, dialect).split("R")
    # ['C', 'C', 'CDCDCDC', 'CDCDCDC']
    

    As a workaround to make it work for my use case, during the pre-processing we need to put some character (eg. space) between newline characters, which in the second example works as follows:

    def correct_empty_rows(data):
        def recursive_replace(s, sub, new):
            while sub in s:
                s = s.replace(sub, new)
            return s
    
        escape_sequences = ["\n", "\r\n", "\r"]  # LF, CRLF, CR
        separator = " "
        for seq in escape_sequences:
            data = recursive_replace(data, 2 * seq, seq + separator + seq)
        return data
    
    # +--------------------------------+
    # | Lorem Ipsum\n                  |
    # | Lorem Ipsum\n                  |
    # | <SPACE>\n                      |
    # | word, digit, bool, float\n     |
    # | dolorum,7539,true,88292972.3\n |
    # +--------------------------------+
    >>> make_abstraction(correct_empty_rows(data), dialect).split("R")
    # ['C', 'C', 'C', 'CDCDCDC', 'CDCDCDC']
    

    I guess the method should return row patterns, so I assume that repeating newlines should be reflected in its output as well.

Test app for importing contact information in CSV files.
Test app for importing contact information in CSV files.

Contact Import TestApp Test app for importing contact information in CSV files. Explore the docs » · Report Bug · Request Feature Table of Contents Ab

Feb 6, 2022
Dragon Age: Origins toolset to extract/build .erf files, patch language-specific .dlg files, and view the contents of files in the ERF or GFF format

DAOTools This is a set of tools for Dragon Age: Origins modding. It can patch the text lines of .dlg files, extract and build an .erf file, and view t

Sep 21, 2022
LightCSV - This CSV reader is implemented in just pure Python.

LightCSV Simple light CSV reader This CSV reader is implemented in just pure Python. It allows to specify a separator, a quote char and column titles

Mar 5, 2022
A simple Python code that takes input from a csv file and makes it into a vcf file.

Contacts-Maker A simple Python code that takes input from a csv file and makes it into a vcf file. Imagine a college or a large community where each y

Feb 13, 2022
Python function to stream unzip all the files in a ZIP archive: without loading the entire ZIP file or any of its files into memory at once

Python function to stream unzip all the files in a ZIP archive: without loading the entire ZIP file or any of its files into memory at once

Nov 26, 2022
Transforme rapidamente seu arquivo CSV (de qualquer tamanho) para SQL de forma rápida.

Transformador de CSV para SQL Transforme rapidamente seu arquivo CSV (de qualquer tamanho) para SQL de forma rápida, e com isso insira seus dados usan

Oct 17, 2022
Sheet Data Image/PDF-to-CSV Converter

Sheet Data Image/PDF-to-CSV Converter

Nov 22, 2021
CSV To VCF (Multiples en un archivo)

CSV To VCF Convierte archivo CSV a Tarjeta VCF (varias en una) How to use En main.py debes reemplazar CONTACTOS.csv por tu archivo csv, y debes respet

Jan 12, 2022
Add Ranges and page numbers to IIIF Manifest from a CSV.

Add Ranges and page numbers to IIIF Manifest from CSV specific to a workflow of the Bibliotheca Hertziana.

Apr 28, 2022
CSV-Handler written in Python3

CSVHandler This code allows you to work intelligently with CSV files. A file in CSV syntax is converted into several lists, which are combined in a to

Jan 13, 2022
Nmap XML output to CSV and HTTP/HTTPS URLS.

xml-to-csv-url Convert NMAP's XML output to CSV file and print URL addresses for HTTP/HTTPS ports. NOTE: OS Version Parsing is not working properly ye

Dec 21, 2021
Automatically generates a TypeQL script for doing entity and relationship insertions from a .csv file, so you don't have to mess with writing TypeQL.
Automatically generates a TypeQL script for doing entity and relationship insertions from a .csv file, so you don't have to mess with writing TypeQL.

Automatically generates a TypeQL script for doing entity and relationship insertions from a .csv file, so you don't have to mess with writing TypeQL.

Feb 9, 2022
Various converters to convert value sets from CSV to JSON, etc.

ValueSet Converters Tools for converting value sets in different formats. Such as converting extensional value sets in CSV format to JSON format able

Sep 8, 2022
Generates a clean .txt file of contents of a 3 lined csv file

Generates a clean .txt file of contents of a 3 lined csv file. File contents is the .gml file of some function which stores the contents of the csv as a map.

Jan 9, 2022
Remove [x]_ from StudIP zip Archives and archive_filelist.csv completely

This tool removes the "[x]_" at the beginning of StudIP zip Archives. It also deletes the "archive_filelist.csv" file

Jan 19, 2022
Two scripts help you to convert csv file to md file by template

Two scripts help you to convert csv file to md file by template. One help you generate multiple md files with different filenames from the first colume of csv file. Another can generate one md file with several blocks.

Oct 15, 2022
Python Fstab Generator is a small Python script to write and generate /etc/fstab files based on yaml file on Unix-like systems.

PyFstab Generator PyFstab Generator is a small Python script to write and generate /etc/fstab files based on yaml file on Unix-like systems. NOTE : Th

Nov 9, 2021
pydicom - Read, modify and write DICOM files with python code

pydicom is a pure Python package for working with DICOM files. It lets you read, modify and write DICOM data in an easy "pythonic" way.

Dec 5, 2022
A tool written in python to generate basic repo files from github
A tool written in python to generate basic repo files from github

A tool written in python to generate basic repo files from github

Dec 2, 2021