Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-aiocsv for openSUSE:Factory 
checked in at 2025-08-11 13:53:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-aiocsv (Old)
 and      /work/SRC/openSUSE:Factory/.python-aiocsv.new.1085 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-aiocsv"

Mon Aug 11 13:53:45 2025 rev:3 rq:1298705 version:1.3.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-aiocsv/python-aiocsv.changes      
2024-10-11 17:07:24.935485002 +0200
+++ /work/SRC/openSUSE:Factory/.python-aiocsv.new.1085/python-aiocsv.changes    
2025-08-11 13:54:04.277014622 +0200
@@ -1,0 +2,7 @@
+Mon Aug 11 05:06:04 UTC 2025 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Add BuildRequires on pytest-asyncio due to pytest 8.4.1.
+- Switch to github tarball for test files.
+- Skip a test broken by cPython changes.
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-aiocsv.spec ++++++
--- /var/tmp/diff_new_pack.86k4oz/_old  2025-08-11 13:54:05.965084263 +0200
+++ /var/tmp/diff_new_pack.86k4oz/_new  2025-08-11 13:54:05.969084428 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-aiocsv
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -15,6 +15,7 @@
 # Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
+
 %{?sle15_python_module_pythons}
 Name:           python-aiocsv
 Version:        1.3.2
@@ -22,10 +23,11 @@
 Summary:        Asynchronous CSV reading/writing in Python
 License:        MIT
 URL:            https://github.com/MKuranowski/aiocsv
-Source:         
https://files.pythonhosted.org/packages/source/a/aiocsv/aiocsv-%{version}.tar.gz
+Source:         
https://github.com/MKuranowski/aiocsv/archive/refs/tags/v%{version}.tar.gz#/aiocsv-%{version}.tar.gz
 BuildRequires:  %{python_module aiofiles}
 BuildRequires:  %{python_module devel >= 3.8}
 BuildRequires:  %{python_module pip}
+BuildRequires:  %{python_module pytest-asyncio}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module setuptools >= 61.0}
 BuildRequires:  %{python_module typing_extensions}
@@ -66,7 +68,8 @@
 }
 
 %check
-%pytest_arch
+# https://github.com/MKuranowski/aiocsv/issues/33
+%pytest_arch -k 'not test_parsing_weird_quotes_nonnumeric'
 
 %files %{python_files}
 %doc readme.md

++++++ aiocsv-1.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/.clang-format 
new/aiocsv-1.3.2/.clang-format
--- old/aiocsv-1.3.2/.clang-format      1970-01-01 01:00:00.000000000 +0100
+++ new/aiocsv-1.3.2/.clang-format      2024-04-28 12:29:50.000000000 +0200
@@ -0,0 +1,6 @@
+BasedOnStyle: Google
+ColumnLimit: 99
+IndentWidth: 4
+DerivePointerAlignment: false
+PointerAlignment: Left
+QualifierAlignment: Right
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/.github/workflows/deploy.yml 
new/aiocsv-1.3.2/.github/workflows/deploy.yml
--- old/aiocsv-1.3.2/.github/workflows/deploy.yml       1970-01-01 
01:00:00.000000000 +0100
+++ new/aiocsv-1.3.2/.github/workflows/deploy.yml       2024-04-28 
12:29:50.000000000 +0200
@@ -0,0 +1,44 @@
+name: Build and upload to PyPI
+
+on:
+  push:
+    tags:
+      - v*
+  workflow_dispatch:
+
+jobs:
+  build_wheels:
+    name: Build wheels on ${{ matrix.os }}
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os: [ubuntu-latest, windows-latest, macos-13]
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Build wheels
+        uses: pypa/cibuildwheel@v2.16.5
+        env:
+          CIBW_ARCHS: auto64
+          CIBW_BUILD: cp3*-*
+
+      - uses: actions/upload-artifact@v4
+        with:
+          name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
+          path: ./wheelhouse/*.whl
+
+  upload_pypi:
+    needs: [build_wheels]
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/download-artifact@v4
+        with:
+          pattern: cibw-wheels-*
+          merge-multiple: true
+          path: dist
+
+      - uses: pypa/gh-action-pypi-publish@release/v1
+        with:
+          user: __token__
+          password: ${{ secrets.pypi_password }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/.github/workflows/test.yml 
new/aiocsv-1.3.2/.github/workflows/test.yml
--- old/aiocsv-1.3.2/.github/workflows/test.yml 1970-01-01 01:00:00.000000000 
+0100
+++ new/aiocsv-1.3.2/.github/workflows/test.yml 2024-04-28 12:29:50.000000000 
+0200
@@ -0,0 +1,40 @@
+name: Automatic tests
+on: [push, pull_request, workflow_dispatch]
+jobs:
+  tests:
+    name: Run tests
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+    steps:
+    - uses: actions/checkout@v4
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v5
+      with:
+        python-version: ${{ matrix.python-version }}
+    - name: Install dependencies
+      run: pip install -Ur requirements.dev.txt
+    - name: Install the library
+      run: pip install -e .
+    - name: Run tests
+      run: pytest
+  lint:
+    name: Lint code
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v4
+    - name: Set up Python 3.8
+      uses: actions/setup-python@v5
+      with:
+        python-version: "3.8"
+    - name: Install dependencies
+      run: pip install -Ur requirements.dev.txt
+    - name: Check code formatting
+      run: black --check .
+    - name: Check imports order
+      run: isort --check .
+    - name: Install the library
+      run: pip install -e .
+    - name: Run typechecking
+      run: pyright
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/.gitignore new/aiocsv-1.3.2/.gitignore
--- old/aiocsv-1.3.2/.gitignore 1970-01-01 01:00:00.000000000 +0100
+++ new/aiocsv-1.3.2/.gitignore 2024-04-28 12:29:50.000000000 +0200
@@ -0,0 +1,10 @@
+__pycache__
+.vscode
+.venv
+.pytest_cache
+*.egg-info
+build
+dist
+ignore_*
+*.so
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/PKG-INFO new/aiocsv-1.3.2/PKG-INFO
--- old/aiocsv-1.3.2/PKG-INFO   2024-04-28 12:30:03.973903700 +0200
+++ new/aiocsv-1.3.2/PKG-INFO   1970-01-01 01:00:00.000000000 +0100
@@ -1,356 +0,0 @@
-Metadata-Version: 2.1
-Name: aiocsv
-Version: 1.3.2
-Author-email: Mikołaj Kuranowski <mkuranowski+pypacka...@gmail.com>
-Project-URL: Homepage, https://github.com/MKuranowski/aiocsv
-Keywords: async,asynchronous,csv,tsv
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Framework :: AsyncIO
-Classifier: Programming Language :: Python :: 3 :: Only
-Requires-Python: >=3.8
-Description-Content-Type: text/markdown
-License-File: LICENSE
-Requires-Dist: typing_extensions
-
-# aiocsv
-
-Asynchronous CSV reading and writing.
-
-
-## Installation
-
-`pip install aiocsv`. Python 3.8+ is required.
-
-This module contains an extension written in C. Pre-build binaries
-may not be available for your configuration. You might need a C compiler
-and Python headers to install aiocsv.
-
-
-## Usage
-
-AsyncReader & AsyncDictReader accept any object that has a `read(size: int)` 
coroutine,
-which should return a string.
-
-AsyncWriter & AsyncDictWriter accept any object that has a `write(b: str)` 
coroutine.
-
-Reading is implemented using a custom CSV parser, which should behave exactly 
like the CPython parser.
-
-Writing is implemented using the synchronous csv.writer and csv.DictWriter 
objects -
-the serializers write data to a StringIO, and that buffer is then rewritten to 
the underlying
-asynchronous file.
-
-
-## Example
-
-Example usage with [aiofiles](https://pypi.org/project/aiofiles/).
-
-```python
-import asyncio
-import csv
-
-import aiofiles
-from aiocsv import AsyncReader, AsyncDictReader, AsyncWriter, AsyncDictWriter
-
-async def main():
-    # simple reading
-    async with aiofiles.open("some_file.csv", mode="r", encoding="utf-8", 
newline="") as afp:
-        async for row in AsyncReader(afp):
-            print(row)  # row is a list
-
-    # dict reading, tab-separated
-    async with aiofiles.open("some_other_file.tsv", mode="r", 
encoding="utf-8", newline="") as afp:
-        async for row in AsyncDictReader(afp, delimiter="\t"):
-            print(row)  # row is a dict
-
-    # simple writing, "unix"-dialect
-    async with aiofiles.open("new_file.csv", mode="w", encoding="utf-8", 
newline="") as afp:
-        writer = AsyncWriter(afp, dialect="unix")
-        await writer.writerow(["name", "age"])
-        await writer.writerows([
-            ["John", 26], ["Sasha", 42], ["Hana", 37]
-        ])
-
-    # dict writing, all quoted, "NULL" for missing fields
-    async with aiofiles.open("new_file2.csv", mode="w", encoding="utf-8", 
newline="") as afp:
-        writer = AsyncDictWriter(afp, ["name", "age"], restval="NULL", 
quoting=csv.QUOTE_ALL)
-        await writer.writeheader()
-        await writer.writerow({"name": "John", "age": 26})
-        await writer.writerows([
-            {"name": "Sasha", "age": 42},
-            {"name": "Hana"}
-        ])
-
-asyncio.run(main())
-```
-
-## Differences with `csv`
-
-`aiocsv` strives to be a drop-in replacement for Python's builtin
-[csv module](https://docs.python.org/3/library/csv.html). However, there are 3 
notable differences:
-
-- Readers accept objects with async `read` methods, instead of an 
AsyncIterable over lines
-    from a file.
-- `AsyncDictReader.fieldnames` can be `None` - use `await 
AsyncDictReader.get_fieldnames()` instead.
-- Changes to `csv.field_size_limit` are not picked up by existing Reader 
instances.
-    The field size limit is cached on Reader instantiation to avoid expensive 
function calls
-    on each character of the input.
-
-Other, minor, differences include:
-- `AsyncReader.line_num`, `AsyncDictReader.line_num` and 
`AsyncDictReader.dialect` are not settable,
-- `AsyncDictReader.reader` is of `AsyncReader` type,
-- `AsyncDictWriter.writer` is of `AsyncWriter` type,
-- `AsyncDictWriter` provides an extra, read-only `dialect` property.
-
-
-## Reference
-
-
-### aiocsv.AsyncReader
-
-```
-AsyncReader(
-    asyncfile: aiocsv.protocols.WithAsyncRead,
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that iterates over records in the given asynchronous CSV file.
-Additional keyword arguments are understood as dialect parameters.
-
-Iterating over this object returns parsed CSV rows (`List[str]`).
-
-*Methods*:
-- `__aiter__(self) -> self`
-- `async __anext__(self) -> List[str]`
-
-*Read-only properties*:
-- `dialect`: The csv.Dialect used when parsing
-- `line_num`: The number of lines read from the source file. This coincides 
with a 1-based index
-    of the line number of the last line of the recently parsed record.
-
-
-### aiocsv.AsyncDictReader
-
-```
-AsyncDictReader(
-    asyncfile: aiocsv.protocols.WithAsyncRead,
-    fieldnames: Optional[Sequence[str]] = None,
-    restkey: Optional[str] = None,
-    restval: Optional[str] = None,
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that iterates over records in the given asynchronous CSV file.
-All arguments work exactly the same was as in csv.DictReader.
-
-Iterating over this object returns parsed CSV rows (`Dict[str, str]`).
-
-*Methods*:
-- `__aiter__(self) -> self`
-- `async __anext__(self) -> Dict[str, str]`
-- `async get_fieldnames(self) -> List[str]`
-
-
-*Properties*:
-- `fieldnames`: field names used when converting rows to dictionaries  
-    **⚠️** Unlike csv.DictReader, this property can't read the fieldnames if 
they are missing -
-    it's not possible to `await` on the header row in a property getter.
-    **Use `await reader.get_fieldnames()`**.
-    ```py
-    reader = csv.DictReader(some_file)
-    reader.fieldnames  # ["cells", "from", "the", "header"]
-
-    areader = aiofiles.AsyncDictReader(same_file_but_async)
-    areader.fieldnames   # ⚠️ None
-    await areader.get_fieldnames()  # ["cells", "from", "the", "header"]
-    ```
-- `restkey`: If a row has more cells then the header, all remaining cells are 
stored under
-    this key in the returned dictionary. Defaults to `None`.
-- `restval`: If a row has less cells then the header, then missing keys will 
use this
-    value. Defaults to `None`.
-- `reader`: Underlying `aiofiles.AsyncReader` instance
-
-*Read-only properties*:
-- `dialect`: Link to `self.reader.dialect` - the current csv.Dialect
-- `line_num`: The number of lines read from the source file. This coincides 
with a 1-based index
-    of the line number of the last line of the recently parsed record.
-
-
-### aiocsv.AsyncWriter
-
-```
-AsyncWriter(
-    asyncfile: aiocsv.protocols.WithAsyncWrite,
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that writes csv rows to the given asynchronous file.
-In this object "row" is a sequence of values.
-
-Additional keyword arguments are passed to the underlying csv.writer instance.
-
-*Methods*:
-- `async writerow(self, row: Iterable[Any]) -> None`:
-    Writes one row to the specified file.
-- `async writerows(self, rows: Iterable[Iterable[Any]]) -> None`:
-    Writes multiple rows to the specified file.
-
-*Readonly properties*:
-- `dialect`: Link to underlying's csv.writer's `dialect` attribute
-
-
-### aiocsv.AsyncDictWriter
-
-```
-AsyncDictWriter(
-    asyncfile: aiocsv.protocols.WithAsyncWrite,
-    fieldnames: Sequence[str],
-    restval: Any = "",
-    extrasaction: Literal["raise", "ignore"] = "raise",
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that writes csv rows to the given asynchronous file.
-In this object "row" is a mapping from fieldnames to values.
-
-Additional keyword arguments are passed to the underlying csv.DictWriter 
instance.
-
-*Methods*:
-- `async writeheader(self) -> None`: Writes header row to the specified file.
-- `async writerow(self, row: Mapping[str, Any]) -> None`:
-    Writes one row to the specified file.
-- `async writerows(self, rows: Iterable[Mapping[str, Any]]) -> None`:
-    Writes multiple rows to the specified file.
-
-*Properties*:
-- `fieldnames`: Sequence of keys to identify the order of values when writing 
rows
-    to the underlying file
-- `restval`: Placeholder value used when a key from fieldnames is missing in a 
row,
-    defaults to `""`
-- `extrasaction`: Action to take when there are keys in a row, which are not 
present in
-    fieldnames, defaults to `"raise"` which causes ValueError to be raised on 
extra keys,
-    may be also set to `"ignore"` to ignore any extra keys
-- `writer`: Link to the underlying `AsyncWriter`
-
-*Readonly properties*:
-- `dialect`: Link to underlying's csv.reader's `dialect` attribute
-
-
-### aiocsv.protocols.WithAsyncRead
-A `typing.Protocol` describing an asynchronous file, which can be read.
-
-
-### aiocsv.protocols.WithAsyncWrite
-A `typing.Protocol` describing an asynchronous file, which can be written to.
-
-
-### aiocsv.protocols.CsvDialectArg
-Type of the `dialect` argument, as used in the `csv` module.
-
-
-### aiocsv.protocols.CsvDialectKwargs
-Keyword arguments used by `csv` module to override the dialect settings during 
reader/writer
-instantiation.
-
-## Development
-
-Contributions are welcome, however please open an issue beforehand. `aiocsv` 
is meant as
-a replacement for the built-in `csv`, any features not present in the latter 
will be rejected.
-
-### Building from source
-
-To create a wheel (and a source tarball), run `python -m build`.
-
-For local development, use a [virtual 
environment](https://docs.python.org/3/library/venv.html).
-`pip install --editable .` will build the C extension and make it available 
for the current
-venv. This is required for running the tests. However, [due to the mess of 
Python packaging](https://docs.python.org/3/library/venv.html)
-this will force an optimized build without debugging symbols. If you need to 
debug the C part
-of aiocsv and build the library with e.g. debugging symbols, the only sane way 
is to
-run `python setup.py build --debug` and manually copy the shared object/DLL 
from `build/lib*/aiocsv`
-to `aiocsv`.
-
-### Tests
-
-This project uses [pytest](https://docs.pytest.org/en/latest/contents.html) 
with
-[pytest-asyncio](https://pypi.org/project/pytest-asyncio/) for testing. Run 
`pytest`
-after installing the library in the manner explained above.
-
-### Linting & other tools
-
-This library uses [black](https://pypi.org/project/black/) and 
[isort](https://pypi.org/project/isort/)
-for formatting and [pyright](https://github.com/microsoft/pyright) in strict 
mode for type checking.
-
-For the C part of library, please use 
[clang-format](https://clang.llvm.org/docs/ClangFormat.html)
-for formatting and [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) 
linting,
-however this are not yet integrated in the CI.
-
-### Installing required tools
-
-`pip install -r requirements.dev.txt` will pull all of the development tools 
mentioned above,
-however this might not be necessary depending on your setup. For example, if 
you use VS Code
-with the Python extension, pyright is already bundled and doesn't need to be 
installed again. 
-
-### Recommended VS Code settings
-
-Use 
[Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python),
-[Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance)
-(should be installed automatically alongside Python extension),
-[black](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter)
 and
-[isort](https://marketplace.visualstudio.com/items?itemName=ms-python.isort) 
Python extensions.
-
-You will need to install all dev dependencies from `requirements.dev.txt`, 
except for `pyright`.
-Recommended `.vscode/settings.json`:
-
-```json
-{
-    "C_Cpp.codeAnalysis.clangTidy.enabled": true,
-    "python.testing.pytestArgs": [
-        "."
-    ],
-    "python.testing.unittestEnabled": false,
-    "python.testing.pytestEnabled": true,
-    "[python]": {
-        "editor.formatOnSave": true,
-        "editor.codeActionsOnSave": {
-            "source.organizeImports": "always"
-        }
-    },
-    "[c]": {
-        "editor.formatOnSave": true
-    }
-}
-```
-
-For the C part of the library, [C/C++ 
extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
 is sufficient.
-Ensure that your system has Python headers installed. Usually a separate 
package like python3-dev
-needs to be installed, consult with your system repositories on that. 
`.vscode/c_cpp_properties.json`
-needs to manually include Python headers under `includePath`. On my particular 
system this
-config file looks like this:
-
-```json
-{
-    "configurations": [
-        {
-            "name": "Linux",
-            "includePath": [
-                "${workspaceFolder}/**",
-                "/usr/include/python3.11"
-            ],
-            "defines": [],
-            "compilerPath": "/usr/bin/clang",
-            "cStandard": "c17",
-            "cppStandard": "c++17",
-            "intelliSenseMode": "linux-clang-x64"
-        }
-    ],
-    "version": 4
-}
-```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/aiocsv.egg-info/PKG-INFO 
new/aiocsv-1.3.2/aiocsv.egg-info/PKG-INFO
--- old/aiocsv-1.3.2/aiocsv.egg-info/PKG-INFO   2024-04-28 12:30:03.000000000 
+0200
+++ new/aiocsv-1.3.2/aiocsv.egg-info/PKG-INFO   1970-01-01 01:00:00.000000000 
+0100
@@ -1,356 +0,0 @@
-Metadata-Version: 2.1
-Name: aiocsv
-Version: 1.3.2
-Author-email: Mikołaj Kuranowski <mkuranowski+pypacka...@gmail.com>
-Project-URL: Homepage, https://github.com/MKuranowski/aiocsv
-Keywords: async,asynchronous,csv,tsv
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Framework :: AsyncIO
-Classifier: Programming Language :: Python :: 3 :: Only
-Requires-Python: >=3.8
-Description-Content-Type: text/markdown
-License-File: LICENSE
-Requires-Dist: typing_extensions
-
-# aiocsv
-
-Asynchronous CSV reading and writing.
-
-
-## Installation
-
-`pip install aiocsv`. Python 3.8+ is required.
-
-This module contains an extension written in C. Pre-build binaries
-may not be available for your configuration. You might need a C compiler
-and Python headers to install aiocsv.
-
-
-## Usage
-
-AsyncReader & AsyncDictReader accept any object that has a `read(size: int)` 
coroutine,
-which should return a string.
-
-AsyncWriter & AsyncDictWriter accept any object that has a `write(b: str)` 
coroutine.
-
-Reading is implemented using a custom CSV parser, which should behave exactly 
like the CPython parser.
-
-Writing is implemented using the synchronous csv.writer and csv.DictWriter 
objects -
-the serializers write data to a StringIO, and that buffer is then rewritten to 
the underlying
-asynchronous file.
-
-
-## Example
-
-Example usage with [aiofiles](https://pypi.org/project/aiofiles/).
-
-```python
-import asyncio
-import csv
-
-import aiofiles
-from aiocsv import AsyncReader, AsyncDictReader, AsyncWriter, AsyncDictWriter
-
-async def main():
-    # simple reading
-    async with aiofiles.open("some_file.csv", mode="r", encoding="utf-8", 
newline="") as afp:
-        async for row in AsyncReader(afp):
-            print(row)  # row is a list
-
-    # dict reading, tab-separated
-    async with aiofiles.open("some_other_file.tsv", mode="r", 
encoding="utf-8", newline="") as afp:
-        async for row in AsyncDictReader(afp, delimiter="\t"):
-            print(row)  # row is a dict
-
-    # simple writing, "unix"-dialect
-    async with aiofiles.open("new_file.csv", mode="w", encoding="utf-8", 
newline="") as afp:
-        writer = AsyncWriter(afp, dialect="unix")
-        await writer.writerow(["name", "age"])
-        await writer.writerows([
-            ["John", 26], ["Sasha", 42], ["Hana", 37]
-        ])
-
-    # dict writing, all quoted, "NULL" for missing fields
-    async with aiofiles.open("new_file2.csv", mode="w", encoding="utf-8", 
newline="") as afp:
-        writer = AsyncDictWriter(afp, ["name", "age"], restval="NULL", 
quoting=csv.QUOTE_ALL)
-        await writer.writeheader()
-        await writer.writerow({"name": "John", "age": 26})
-        await writer.writerows([
-            {"name": "Sasha", "age": 42},
-            {"name": "Hana"}
-        ])
-
-asyncio.run(main())
-```
-
-## Differences with `csv`
-
-`aiocsv` strives to be a drop-in replacement for Python's builtin
-[csv module](https://docs.python.org/3/library/csv.html). However, there are 3 
notable differences:
-
-- Readers accept objects with async `read` methods, instead of an 
AsyncIterable over lines
-    from a file.
-- `AsyncDictReader.fieldnames` can be `None` - use `await 
AsyncDictReader.get_fieldnames()` instead.
-- Changes to `csv.field_size_limit` are not picked up by existing Reader 
instances.
-    The field size limit is cached on Reader instantiation to avoid expensive 
function calls
-    on each character of the input.
-
-Other, minor, differences include:
-- `AsyncReader.line_num`, `AsyncDictReader.line_num` and 
`AsyncDictReader.dialect` are not settable,
-- `AsyncDictReader.reader` is of `AsyncReader` type,
-- `AsyncDictWriter.writer` is of `AsyncWriter` type,
-- `AsyncDictWriter` provides an extra, read-only `dialect` property.
-
-
-## Reference
-
-
-### aiocsv.AsyncReader
-
-```
-AsyncReader(
-    asyncfile: aiocsv.protocols.WithAsyncRead,
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that iterates over records in the given asynchronous CSV file.
-Additional keyword arguments are understood as dialect parameters.
-
-Iterating over this object returns parsed CSV rows (`List[str]`).
-
-*Methods*:
-- `__aiter__(self) -> self`
-- `async __anext__(self) -> List[str]`
-
-*Read-only properties*:
-- `dialect`: The csv.Dialect used when parsing
-- `line_num`: The number of lines read from the source file. This coincides 
with a 1-based index
-    of the line number of the last line of the recently parsed record.
-
-
-### aiocsv.AsyncDictReader
-
-```
-AsyncDictReader(
-    asyncfile: aiocsv.protocols.WithAsyncRead,
-    fieldnames: Optional[Sequence[str]] = None,
-    restkey: Optional[str] = None,
-    restval: Optional[str] = None,
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that iterates over records in the given asynchronous CSV file.
-All arguments work exactly the same was as in csv.DictReader.
-
-Iterating over this object returns parsed CSV rows (`Dict[str, str]`).
-
-*Methods*:
-- `__aiter__(self) -> self`
-- `async __anext__(self) -> Dict[str, str]`
-- `async get_fieldnames(self) -> List[str]`
-
-
-*Properties*:
-- `fieldnames`: field names used when converting rows to dictionaries  
-    **⚠️** Unlike csv.DictReader, this property can't read the fieldnames if 
they are missing -
-    it's not possible to `await` on the header row in a property getter.
-    **Use `await reader.get_fieldnames()`**.
-    ```py
-    reader = csv.DictReader(some_file)
-    reader.fieldnames  # ["cells", "from", "the", "header"]
-
-    areader = aiofiles.AsyncDictReader(same_file_but_async)
-    areader.fieldnames   # ⚠️ None
-    await areader.get_fieldnames()  # ["cells", "from", "the", "header"]
-    ```
-- `restkey`: If a row has more cells then the header, all remaining cells are 
stored under
-    this key in the returned dictionary. Defaults to `None`.
-- `restval`: If a row has less cells then the header, then missing keys will 
use this
-    value. Defaults to `None`.
-- `reader`: Underlying `aiofiles.AsyncReader` instance
-
-*Read-only properties*:
-- `dialect`: Link to `self.reader.dialect` - the current csv.Dialect
-- `line_num`: The number of lines read from the source file. This coincides 
with a 1-based index
-    of the line number of the last line of the recently parsed record.
-
-
-### aiocsv.AsyncWriter
-
-```
-AsyncWriter(
-    asyncfile: aiocsv.protocols.WithAsyncWrite,
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that writes csv rows to the given asynchronous file.
-In this object "row" is a sequence of values.
-
-Additional keyword arguments are passed to the underlying csv.writer instance.
-
-*Methods*:
-- `async writerow(self, row: Iterable[Any]) -> None`:
-    Writes one row to the specified file.
-- `async writerows(self, rows: Iterable[Iterable[Any]]) -> None`:
-    Writes multiple rows to the specified file.
-
-*Readonly properties*:
-- `dialect`: Link to underlying's csv.writer's `dialect` attribute
-
-
-### aiocsv.AsyncDictWriter
-
-```
-AsyncDictWriter(
-    asyncfile: aiocsv.protocols.WithAsyncWrite,
-    fieldnames: Sequence[str],
-    restval: Any = "",
-    extrasaction: Literal["raise", "ignore"] = "raise",
-    dialect: str | csv.Dialect | Type[csv.Dialect] = "excel",
-    **csv_dialect_kwargs: Unpack[aiocsv.protocols.CsvDialectKwargs],
-)
-```
-
-An object that writes csv rows to the given asynchronous file.
-In this object "row" is a mapping from fieldnames to values.
-
-Additional keyword arguments are passed to the underlying csv.DictWriter 
instance.
-
-*Methods*:
-- `async writeheader(self) -> None`: Writes header row to the specified file.
-- `async writerow(self, row: Mapping[str, Any]) -> None`:
-    Writes one row to the specified file.
-- `async writerows(self, rows: Iterable[Mapping[str, Any]]) -> None`:
-    Writes multiple rows to the specified file.
-
-*Properties*:
-- `fieldnames`: Sequence of keys to identify the order of values when writing 
rows
-    to the underlying file
-- `restval`: Placeholder value used when a key from fieldnames is missing in a 
row,
-    defaults to `""`
-- `extrasaction`: Action to take when there are keys in a row, which are not 
present in
-    fieldnames, defaults to `"raise"` which causes ValueError to be raised on 
extra keys,
-    may be also set to `"ignore"` to ignore any extra keys
-- `writer`: Link to the underlying `AsyncWriter`
-
-*Readonly properties*:
-- `dialect`: Link to underlying's csv.reader's `dialect` attribute
-
-
-### aiocsv.protocols.WithAsyncRead
-A `typing.Protocol` describing an asynchronous file, which can be read.
-
-
-### aiocsv.protocols.WithAsyncWrite
-A `typing.Protocol` describing an asynchronous file, which can be written to.
-
-
-### aiocsv.protocols.CsvDialectArg
-Type of the `dialect` argument, as used in the `csv` module.
-
-
-### aiocsv.protocols.CsvDialectKwargs
-Keyword arguments used by `csv` module to override the dialect settings during 
reader/writer
-instantiation.
-
-## Development
-
-Contributions are welcome, however please open an issue beforehand. `aiocsv` 
is meant as
-a replacement for the built-in `csv`, any features not present in the latter 
will be rejected.
-
-### Building from source
-
-To create a wheel (and a source tarball), run `python -m build`.
-
-For local development, use a [virtual 
environment](https://docs.python.org/3/library/venv.html).
-`pip install --editable .` will build the C extension and make it available 
for the current
-venv. This is required for running the tests. However, [due to the mess of 
Python packaging](https://docs.python.org/3/library/venv.html)
-this will force an optimized build without debugging symbols. If you need to 
debug the C part
-of aiocsv and build the library with e.g. debugging symbols, the only sane way 
is to
-run `python setup.py build --debug` and manually copy the shared object/DLL 
from `build/lib*/aiocsv`
-to `aiocsv`.
-
-### Tests
-
-This project uses [pytest](https://docs.pytest.org/en/latest/contents.html) 
with
-[pytest-asyncio](https://pypi.org/project/pytest-asyncio/) for testing. Run 
`pytest`
-after installing the library in the manner explained above.
-
-### Linting & other tools
-
-This library uses [black](https://pypi.org/project/black/) and 
[isort](https://pypi.org/project/isort/)
-for formatting and [pyright](https://github.com/microsoft/pyright) in strict 
mode for type checking.
-
-For the C part of library, please use 
[clang-format](https://clang.llvm.org/docs/ClangFormat.html)
-for formatting and [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) 
linting,
-however this are not yet integrated in the CI.
-
-### Installing required tools
-
-`pip install -r requirements.dev.txt` will pull all of the development tools 
mentioned above,
-however this might not be necessary depending on your setup. For example, if 
you use VS Code
-with the Python extension, pyright is already bundled and doesn't need to be 
installed again. 
-
-### Recommended VS Code settings
-
-Use 
[Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python),
-[Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance)
-(should be installed automatically alongside Python extension),
-[black](https://marketplace.visualstudio.com/items?itemName=ms-python.black-formatter)
 and
-[isort](https://marketplace.visualstudio.com/items?itemName=ms-python.isort) 
Python extensions.
-
-You will need to install all dev dependencies from `requirements.dev.txt`, 
except for `pyright`.
-Recommended `.vscode/settings.json`:
-
-```json
-{
-    "C_Cpp.codeAnalysis.clangTidy.enabled": true,
-    "python.testing.pytestArgs": [
-        "."
-    ],
-    "python.testing.unittestEnabled": false,
-    "python.testing.pytestEnabled": true,
-    "[python]": {
-        "editor.formatOnSave": true,
-        "editor.codeActionsOnSave": {
-            "source.organizeImports": "always"
-        }
-    },
-    "[c]": {
-        "editor.formatOnSave": true
-    }
-}
-```
-
-For the C part of the library, [C/C++ 
extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
 is sufficient.
-Ensure that your system has Python headers installed. Usually a separate 
package like python3-dev
-needs to be installed, consult with your system repositories on that. 
`.vscode/c_cpp_properties.json`
-needs to manually include Python headers under `includePath`. On my particular 
system this
-config file looks like this:
-
-```json
-{
-    "configurations": [
-        {
-            "name": "Linux",
-            "includePath": [
-                "${workspaceFolder}/**",
-                "/usr/include/python3.11"
-            ],
-            "defines": [],
-            "compilerPath": "/usr/bin/clang",
-            "cStandard": "c17",
-            "cppStandard": "c++17",
-            "intelliSenseMode": "linux-clang-x64"
-        }
-    ],
-    "version": 4
-}
-```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/aiocsv.egg-info/SOURCES.txt 
new/aiocsv-1.3.2/aiocsv.egg-info/SOURCES.txt
--- old/aiocsv-1.3.2/aiocsv.egg-info/SOURCES.txt        2024-04-28 
12:30:03.000000000 +0200
+++ new/aiocsv-1.3.2/aiocsv.egg-info/SOURCES.txt        1970-01-01 
01:00:00.000000000 +0100
@@ -1,23 +0,0 @@
-LICENSE
-pyproject.toml
-readme.md
-setup.py
-aiocsv/__init__.py
-aiocsv/_parser.c
-aiocsv/_parser.pyi
-aiocsv/parser.py
-aiocsv/protocols.py
-aiocsv/py.typed
-aiocsv/readers.py
-aiocsv/writers.py
-aiocsv.egg-info/PKG-INFO
-aiocsv.egg-info/SOURCES.txt
-aiocsv.egg-info/dependency_links.txt
-aiocsv.egg-info/not-zip-safe
-aiocsv.egg-info/requires.txt
-aiocsv.egg-info/top_level.txt
-tests/test_dialects.py
-tests/test_dict.py
-tests/test_newlines.py
-tests/test_parser.py
-tests/test_simple.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/aiocsv.egg-info/dependency_links.txt 
new/aiocsv-1.3.2/aiocsv.egg-info/dependency_links.txt
--- old/aiocsv-1.3.2/aiocsv.egg-info/dependency_links.txt       2024-04-28 
12:30:03.000000000 +0200
+++ new/aiocsv-1.3.2/aiocsv.egg-info/dependency_links.txt       1970-01-01 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/aiocsv.egg-info/not-zip-safe 
new/aiocsv-1.3.2/aiocsv.egg-info/not-zip-safe
--- old/aiocsv-1.3.2/aiocsv.egg-info/not-zip-safe       2024-02-21 
18:56:51.000000000 +0100
+++ new/aiocsv-1.3.2/aiocsv.egg-info/not-zip-safe       1970-01-01 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/aiocsv.egg-info/requires.txt 
new/aiocsv-1.3.2/aiocsv.egg-info/requires.txt
--- old/aiocsv-1.3.2/aiocsv.egg-info/requires.txt       2024-04-28 
12:30:03.000000000 +0200
+++ new/aiocsv-1.3.2/aiocsv.egg-info/requires.txt       1970-01-01 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-typing_extensions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/aiocsv.egg-info/top_level.txt 
new/aiocsv-1.3.2/aiocsv.egg-info/top_level.txt
--- old/aiocsv-1.3.2/aiocsv.egg-info/top_level.txt      2024-04-28 
12:30:03.000000000 +0200
+++ new/aiocsv-1.3.2/aiocsv.egg-info/top_level.txt      1970-01-01 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-aiocsv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/requirements.dev.txt 
new/aiocsv-1.3.2/requirements.dev.txt
--- old/aiocsv-1.3.2/requirements.dev.txt       1970-01-01 01:00:00.000000000 
+0100
+++ new/aiocsv-1.3.2/requirements.dev.txt       2024-04-28 12:29:50.000000000 
+0200
@@ -0,0 +1,9 @@
+-r requirements.txt
+aiofiles
+pytest
+pytest-asyncio
+setuptools
+wheel
+isort
+black
+pyright
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/requirements.txt 
new/aiocsv-1.3.2/requirements.txt
--- old/aiocsv-1.3.2/requirements.txt   1970-01-01 01:00:00.000000000 +0100
+++ new/aiocsv-1.3.2/requirements.txt   2024-04-28 12:29:50.000000000 +0200
@@ -0,0 +1 @@
+typing_extensions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/setup.cfg new/aiocsv-1.3.2/setup.cfg
--- old/aiocsv-1.3.2/setup.cfg  2024-04-28 12:30:03.977237000 +0200
+++ new/aiocsv-1.3.2/setup.cfg  1970-01-01 01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-[egg_info]
-tag_build = 
-tag_date = 0
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/tests/eu_cities_unix.csv 
new/aiocsv-1.3.2/tests/eu_cities_unix.csv
--- old/aiocsv-1.3.2/tests/eu_cities_unix.csv   1970-01-01 01:00:00.000000000 
+0100
+++ new/aiocsv-1.3.2/tests/eu_cities_unix.csv   2024-04-28 12:29:50.000000000 
+0200
@@ -0,0 +1,5 @@
+"Berlin","Germany"
+"Madrid","Spain"
+"Rome","Italy"
+"Bucharest","Romania"
+"Paris","France"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/tests/math_constants.csv 
new/aiocsv-1.3.2/tests/math_constants.csv
--- old/aiocsv-1.3.2/tests/math_constants.csv   1970-01-01 01:00:00.000000000 
+0100
+++ new/aiocsv-1.3.2/tests/math_constants.csv   2024-04-28 12:29:50.000000000 
+0200
@@ -0,0 +1,4 @@
+pi,3.1416
+sqrt2,1.4142
+phi,1.618
+e,2.7183
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/tests/metro_systems.tsv 
new/aiocsv-1.3.2/tests/metro_systems.tsv
--- old/aiocsv-1.3.2/tests/metro_systems.tsv    1970-01-01 01:00:00.000000000 
+0100
+++ new/aiocsv-1.3.2/tests/metro_systems.tsv    2024-04-28 12:29:50.000000000 
+0200
@@ -0,0 +1,7 @@
+'City' 'Stations'      'System Length'
+'New York'     '424'   '380'
+'Shanghai'     '345'   '676'
+'Seoul'        '331'   '353'
+'Beijing'      '326'   '690'
+'Paris'        '302'   '214'
+'London'       '270'   '402'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aiocsv-1.3.2/tests/newlines.csv 
new/aiocsv-1.3.2/tests/newlines.csv
--- old/aiocsv-1.3.2/tests/newlines.csv 1970-01-01 01:00:00.000000000 +0100
+++ new/aiocsv-1.3.2/tests/newlines.csv 2024-04-28 12:29:50.000000000 +0200
@@ -0,0 +1,7 @@
+field1,field2,field3
+"hello","is it $"me""","you're
+looking for"
+this is going to be,another$
+broken row,"this time with escapechar"
+"and now it's both quoted$
+and",with,"escape char"

Reply via email to