python-cath 0.2.5__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_cath/__init__.py +2 -6
- python_cath/__main__.py +9 -11
- python_cath/concat.py +44 -2
- {python_cath-0.2.5.dist-info → python_cath-0.3.0.dist-info}/METADATA +13 -10
- python_cath-0.3.0.dist-info/RECORD +10 -0
- {python_cath-0.2.5.dist-info → python_cath-0.3.0.dist-info}/WHEEL +1 -1
- python_cath-0.2.5.dist-info/RECORD +0 -10
- {python_cath-0.2.5.dist-info → python_cath-0.3.0.dist-info}/entry_points.txt +0 -0
- {python_cath-0.2.5.dist-info → python_cath-0.3.0.dist-info/licenses}/LICENSE +0 -0
python_cath/__init__.py
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mypy: disable-error-code="attr-defined"
|
|
2
2
|
"""Cat files w/ headers"""
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from importlib.metadata import version, PackageNotFoundError
|
|
6
|
-
except ImportError: # pragma: no cover
|
|
7
|
-
from importlib_metadata import version, PackageNotFoundError
|
|
8
|
-
|
|
4
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
9
5
|
|
|
10
6
|
try:
|
|
11
7
|
__version__ = version(__name__)
|
python_cath/__main__.py
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# mypy: disable-error-code="attr-defined"
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
from enum import Enum
|
|
5
|
-
from typing import List, Optional
|
|
3
|
+
from typing import List
|
|
6
4
|
|
|
7
5
|
import typer
|
|
8
|
-
from rich.console import Console
|
|
9
|
-
|
|
10
6
|
from python_cath import __version__
|
|
11
7
|
from python_cath.concat import concat
|
|
12
|
-
from
|
|
8
|
+
from rich.console import Console
|
|
13
9
|
|
|
14
10
|
app = typer.Typer(
|
|
15
|
-
name="python-cath",
|
|
11
|
+
name="python-cath",
|
|
12
|
+
help="Cat files w/ headers",
|
|
13
|
+
add_completion=False,
|
|
16
14
|
)
|
|
17
15
|
console = Console()
|
|
18
16
|
|
|
19
17
|
|
|
20
|
-
def version_callback(value: bool):
|
|
18
|
+
def version_callback(value: bool) -> None:
|
|
21
19
|
"""Prints the version of the package."""
|
|
22
20
|
if value:
|
|
23
21
|
console.print(
|
|
@@ -30,6 +28,6 @@ def version_callback(value: bool):
|
|
|
30
28
|
def main(
|
|
31
29
|
file_list: List[str] = typer.Argument(...),
|
|
32
30
|
output_file: str = typer.Argument(...),
|
|
33
|
-
):
|
|
34
|
-
"""
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Concatenate CSV files with a shared header into output_file."""
|
|
35
33
|
concat(file_list, output_file)
|
python_cath/concat.py
CHANGED
|
@@ -1,7 +1,49 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import shutil
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def concat(file_list, output_file):
|
|
5
|
-
|
|
6
|
+
"""Concatenate CSV files that share the same header.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
file_list: Paths to input files.
|
|
10
|
+
output_file: Path to write the concatenated output.
|
|
11
|
+
|
|
12
|
+
Raises:
|
|
13
|
+
ValueError: If no input files are provided, any file has an empty
|
|
14
|
+
header, an input file path collides with the output file, or
|
|
15
|
+
file headers differ.
|
|
16
|
+
"""
|
|
17
|
+
file_list = list(file_list)
|
|
18
|
+
if not file_list:
|
|
19
|
+
raise ValueError("file_list must not be empty")
|
|
20
|
+
|
|
21
|
+
real_output = os.path.realpath(output_file)
|
|
6
22
|
for afile in file_list:
|
|
7
|
-
os.
|
|
23
|
+
if os.path.realpath(afile) == real_output:
|
|
24
|
+
raise ValueError(
|
|
25
|
+
f"Input file {afile!r} is the same path as the output file"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# First pass: read and validate headers one file at a time
|
|
29
|
+
file_headers = {}
|
|
30
|
+
for afile in file_list:
|
|
31
|
+
with open(afile, encoding="utf-8") as fh:
|
|
32
|
+
header = fh.readline().rstrip("\n")
|
|
33
|
+
if not header:
|
|
34
|
+
raise ValueError(f"File {afile!r} has an empty or missing header")
|
|
35
|
+
file_headers[afile] = header
|
|
36
|
+
|
|
37
|
+
unique_headers = set(file_headers.values())
|
|
38
|
+
if len(unique_headers) > 1:
|
|
39
|
+
detail = ", ".join(f"{f!r}: {h!r}" for f, h in file_headers.items())
|
|
40
|
+
raise ValueError(f"Headers do not match: {detail}")
|
|
41
|
+
|
|
42
|
+
# Second pass: write output one file at a time
|
|
43
|
+
shared_header = next(iter(unique_headers))
|
|
44
|
+
with open(output_file, "w", encoding="utf-8") as out:
|
|
45
|
+
out.write(shared_header + "\n")
|
|
46
|
+
for afile in file_list:
|
|
47
|
+
with open(afile, encoding="utf-8") as fh:
|
|
48
|
+
fh.readline() # skip header
|
|
49
|
+
shutil.copyfileobj(fh, out)
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: python-cath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Cat files w/ headers
|
|
5
|
-
Home-page: https://github.com/samesense/python-cath
|
|
6
5
|
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
7
|
Author: samesense
|
|
8
8
|
Author-email: candptea@gmail.com
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
10
|
Classifier: Development Status :: 3 - Alpha
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
|
|
21
|
+
Requires-Dist: pre-commit (>=3.0.0,<4.0.0)
|
|
22
|
+
Requires-Dist: rich (>=10.0.0)
|
|
23
|
+
Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
|
|
24
|
+
Project-URL: Homepage, https://github.com/samesense/python-cath
|
|
22
25
|
Project-URL: Repository, https://github.com/samesense/python-cath
|
|
23
26
|
Description-Content-Type: text/markdown
|
|
24
27
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
python_cath/__init__.py,sha256=jWtDUGUgV39IeDqwlQ9ziOy9ceofcf1hsppd2C_t9Yw,250
|
|
2
|
+
python_cath/__main__.py,sha256=t3LBYcsZ4lcNo4SUc828O6DoeCZmKlAPazDNfd1n9K8,788
|
|
3
|
+
python_cath/concat.py,sha256=RYSWSePSbdWI9JlzFlIVtoa7rH1-LmiruorjDc9jKZY,1731
|
|
4
|
+
python_cath/example.py,sha256=LGLU6ShWSJtu2zPbGXmQJw5ktJkNlGnRhFjY8OTlePM,366
|
|
5
|
+
python_cath/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
python_cath-0.3.0.dist-info/METADATA,sha256=CwdIGPs5Gmh6nwDtwfLr_VXqGRyYeJ4f7RpXV9XpmJ4,7674
|
|
7
|
+
python_cath-0.3.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
|
|
8
|
+
python_cath-0.3.0.dist-info/entry_points.txt,sha256=CKAIA5eO7sx0McMvZxxXm01CYasNWeOfB3MWbkNcP7I,56
|
|
9
|
+
python_cath-0.3.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
python_cath-0.3.0.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
python_cath/__init__.py,sha256=HIJeYPnh_ZqTjg5-1pf6_VFBPCMeva5APJJkOfYH2wc,352
|
|
2
|
-
python_cath/__main__.py,sha256=NxUhgsLFy8DOpNs7Kq0DJS3lTyIfqqdMH9FgWSNAzRk,812
|
|
3
|
-
python_cath/concat.py,sha256=ytMyX5tBezA4b604dk4DQrMEGMKwLcYPAIJwSwFNO9k,191
|
|
4
|
-
python_cath/example.py,sha256=LGLU6ShWSJtu2zPbGXmQJw5ktJkNlGnRhFjY8OTlePM,366
|
|
5
|
-
python_cath/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
python_cath-0.2.5.dist-info/entry_points.txt,sha256=CKAIA5eO7sx0McMvZxxXm01CYasNWeOfB3MWbkNcP7I,56
|
|
7
|
-
python_cath-0.2.5.dist-info/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
python_cath-0.2.5.dist-info/WHEEL,sha256=Q99itqWYDhV793oHzqzi24q7L7Kdiz6cb55YDfTXphE,84
|
|
9
|
-
python_cath-0.2.5.dist-info/METADATA,sha256=pdUUy0Njms0Lt1otIoT0ZrxK4KKsjgkDGBNgx8yUpp0,7564
|
|
10
|
-
python_cath-0.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|