From 477ffbd65a28be57fa19256d5cbaead6ca71ba06 Mon Sep 17 00:00:00 2001 From: demetry pascal Date: Wed, 24 Apr 2024 22:45:42 +0300 Subject: [PATCH] union_2_data_dicts: update to support dictionaries with the key "version" --- tests/input/test_3/dcr.toml | 73 +++++++++++++++ tests/input/test_3/dml.toml | 135 +++++++++++++++++++++++++++ tests/input/test_3/dweb.toml | 94 +++++++++++++++++++ tests/output/test_3/test3.toml | 164 +++++++++++++++++++++++++++++++++ tests/test_main.py | 21 +++++ toml_union/toml_union.py | 43 +++++++-- 6 files changed, 521 insertions(+), 9 deletions(-) create mode 100644 tests/input/test_3/dcr.toml create mode 100644 tests/input/test_3/dml.toml create mode 100644 tests/input/test_3/dweb.toml create mode 100644 tests/output/test_3/test3.toml diff --git a/tests/input/test_3/dcr.toml b/tests/input/test_3/dcr.toml new file mode 100644 index 0000000..a43d2a0 --- /dev/null +++ b/tests/input/test_3/dcr.toml @@ -0,0 +1,73 @@ +[tool.poetry] +name = "dcr" +version = "1.8.1" +description = "DCR" + + +[tool.poetry.dependencies] +"pdfminer.six" = "^20220524" +biopython = "^1.81" +chardet = "^4.0.0" +cmake = "^3.21.1" +cython = "0.29.37" +Django = "~3.1" +django-allauth = "^0.51" +django-bootstrap4 = "^22.1" +django-cors-headers = "^3.2.1" +django-extensions = "^3.1.0" +django-rosetta = "^0.9.5" +env2dict = "^0.0.3" +fast_deskew = "1.0" +filelock = "^3.4.2" +google-cloud-documentai = "^1.1.0" +gunicorn = "^21.2" +matplotlib = "^3.4.3" +nbdime = "^3.1.0" +nltk = "^3.6.5" +numpy = "~1.23" +ocrmypdf = "^13.0.0" +onnxruntime = "^1.12.1" +opencv-python = "4.5.4.60" +ordered-rectangles = { extras = ["extra"], version = ">=0.0.6" } +orjson = "<=3.9.10" +pdf2image = "^1.16.0" +pikepdf = "^8" +Pillow = "^10.1" +psutil = "^5.8.0" +pyclipper = "1.3.0.post5" +pyctcdecode = "0.5.0" +PyMuPDF = "^1.21.1" +pypdf = "^3.17.2" +PyPDF2 = "^1.26.0" +pypdfium2= "^4.24.0" +pytesseract = "^0.3.10" +pytest = "^6.2.2" +python = ">=3.8.2,<3.10" +python-Levenshtein = "~0.12.2" +python-poppler = "^0.4.1" +PyYAML = "^6.0" +pyzbar = "^0.1.8" +reportlab = "^3.6.11" +scikit-image = "^0.18.3" +scikit-learn = ">= 1.1, < 1.3" +sentry-sdk = "^1.14.0" +shapely = "^2.0.1" +spyne = "^2.14.0" +tifftools = "^1.3.6" +tqdm = "^4.62" +urllib3 = "~1.26" +varsubst = "^2.0.0" +wheel = ">=0.37" + +[tool.poetry.group.dev.dependencies] +autopep8 = "^1.5" +black = "^23" +ipython = "^8.0" +jupyter = "^1.0" +jupyter-server = "^1.0" +mypy = "^0.790" +notebook = "^6.5.6" +pylint = "^2.6" +pylint-django = "~2.3" +pytest-django = "^4.5.2" + diff --git a/tests/input/test_3/dml.toml b/tests/input/test_3/dml.toml new file mode 100644 index 0000000..ec58f4d --- /dev/null +++ b/tests/input/test_3/dml.toml @@ -0,0 +1,135 @@ +[tool.poetry] +name = "dml" +version = "1.7.2" +description = "DML" + +[tool.poetry.dependencies] +"pdfminer.six" = "^20220524" +ansi2html = "^1.7" +bayoo-docx = "^0.2.20" +beautifulsoup4 = "^4.10" +boto3 = "^1.16.56" +chardet = "^4.0.0" +cmake = "^3.21.1" +commonregex = "1.5.3" +compress_fasttext = "^0.0.6" +conllu = "^4.4" +coreapi = "^2.3.3" +corus = "^0.7.0" +cython = "0.29.37" +Django = "~3.1" +django-allauth = "^0.51" +django-bootstrap4 = "^22.1" +django-cors-headers = "^3.2.1" +django-extensions = "^3.1.0" +django-rosetta = "^0.9.5" +djangorestframework = "^3.13" +djangorestframework-simplejwt = "^4.5" +djangorestframework-xml = "^2.0.0" +drf-yasg = "^1.20.0" +editdistance = ">=0.6.2" +env2dict = "^0.0.3" +fast_deskew = "1.0" +filelock = "^3.4.2" +filetype = "^1.2.0" +flashtext = "^2.7" +fuzzysearch = "^0.7.3" +fuzzywuzzy = "^0.18.0" +google-cloud-documentai = "^1.1.0" +protobuf = "^3.20" +gunicorn = "^21.2" +httpx = {extras = ["socks", "brotli", "http2"], version = "^0.26"} +hvac = "^1.1.1" +ImageHash = "^4.2.1" +imbalanced-learn = "^0.11.0" +ipymarkup = "^0.9.0" +jsonfield = "^3.1.0" +langchain = "^0.0.325" +matplotlib = "^3.4.3" +minio= ">=7.1.17" +murmurhash = "^1.0.3" +natasha = "~1.3" +navec = "^0.10.0" +nbdime = "^3.1.0" +nerus = "^1.7.0" +nltk = "^3.6.5" +numpy = "~1.23" +onnxruntime = "^1.12.1" +openai = "^1.3.5" +opencv-python = "4.5.4.60" +orjson = "<=3.9.10" +pandas = "~1.5" +patiencediff = "^0.2.14" +patool = "^1.12" +pdf2image = "^1.16.0" +phonenumbers = "^8.12.15" +pika = "^1.2.0" +pikepdf = "^8" +Pillow = "^10.1" +psutil = "^5.8.0" +psycopg2-binary = "^2.9.1" +py7zr = "^0.20.1" +pyaescrypt = ">=0.4.3" +pyap = "^0.3.1" +pycel = "^1.0b30" +pyctcdecode = "0.5.0" +pyexcel = "^0.6.1" +pyexcel-xls = "^0.5.8" +pyexcel-xlsx = "^0.5.8" +PyJWT = "^2.4.0" +pymorphy2 = { extras = ["speedups"], version = "^0.9.1" } +PyMuPDF = "^1.21.1" +pymystem3 = "~0.2.0" +pyOpenSSL = ">=23.0" +PyPDF2 = "^1.26.0" +pypdfium2= "^4.24.0" +pyrfc6266 = "^1.0.2" +pyrsistent = "0.16" +pyrus-api = "^2.12.0" +pytesseract = "^0.3.10" +pytest = "^6.2.2" +python = ">=3.8.2,<3.10" +python-Levenshtein = "~0.12.2" +python-poppler = "^0.4.1" +pyunpack = "^0.3" +PyYAML = "^6.0" +pyzbar = "^0.1.8" +rabbitmq = "^0.2.0" +razdel = "~0.5" +reportlab = "^3.6.11" +scikit-image = "^0.18.3" +scikit-learn = ">= 1.1, < 1.3" +sentencepiece = "^0.1.99" +sentry-sdk = "^1.14.0" +spacy = "~2.3" +spyne = "^2.14.0" +tensorboard = "^2.4.1" +termcolor = "^1.1.0" +tifftools = "^1.3.6" +tiktoken = "^0.4.0" +tqdm = "^4.62" +unidecode = "^1.1.1" +unrar = "^0.4" +urllib3 = "~1.26" +varsubst = "^2.0.0" +wand = ">=0.5.8" +weasyprint = "^52.5" +wheel = ">=0.37" +xlrd = "^2.0" +xlsx2html = "^0.4.4" +XlsxWriter = "^3.0.3" +zeep = "^4.1.0" + +[tool.poetry.group.dev.dependencies] +autopep8 = "^1.5" +black = "^23" +ipython = "^8.0" +jupyter = "^1.0" +jupyter-server = "^1.0" +mypy = "^0.790" +notebook = "^6.5.6" +pre-commit = "^3.5.0" +pylint = "^2.6" +pylint-django = "~2.3" +pytest-django = "^4.5.2" + diff --git a/tests/input/test_3/dweb.toml b/tests/input/test_3/dweb.toml new file mode 100644 index 0000000..12b6e24 --- /dev/null +++ b/tests/input/test_3/dweb.toml @@ -0,0 +1,94 @@ +[tool.poetry] +name = "d" +version = "1.8.1" +description = "D" + +[tool.poetry.dependencies] +"pdfminer.six" = "^20220524" +aiofiles = "^23.2.1" +ansi2html = "^1.7" +asgi-lifespan = "^2.1.0" +bayoo-docx = "^0.2.20" +beautifulsoup4 = "^4.10" +boto3 = "^1.16.56" +chardet = "^4.0.0" +coreapi = "^2.3.3" +datapunt-keycloak-oidc = "^0.5.1" +Django = "~3.1" +django-allauth = "^0.51" +django-auth-ldap = "^4.1" +django-bootstrap4 = "^22.1" +django-cors-headers = "^3.2.1" +django-extensions = "^3.1.0" +django-rosetta = "^0.9.5" +djangorestframework = "^3.13" +djangorestframework-simplejwt = "^4.5" +djangorestframework-xml = "^2.0.0" +drf-yasg = "^1.20.0" +env2dict = "^0.0.3" +fastapi = {extras = ["uvicorn"], version = "^0.110.0"} +filelock = "^3.4.2" +filetype = "^1.2.0" +flashtext = "^2.7" +fuzzysearch = "^0.7.3" +gunicorn = "^21.2" +httpx = "^0.27.0" +hvac = "^1.1.1" +ImageHash = "^4.2.1" +jsonfield = "^3.1.0" +matplotlib = "^3.4.3" +murmurhash = "^1.0.3" +natasha = "~1.3" +numpy = "~1.23" +opencv-python = "4.5.4.60" +openpyxl = "^3.1.2" +orjson = "<=3.9.10" +pandas = "~1.5" +patiencediff = "^0.2.14" +pdf2image = "^1.16.0" +phonenumbers = "^8.12.15" +pika = "^1.2.0" +pikepdf = "^8" +Pillow = "^10.1" +psutil = "^5.8.0" +psycopg2-binary = "^2.9.1" +pycel = "^1.0b30" +pydantic-settings = "^2.2.1" +PyJWT = "^2.4.0" +pymorphy2 = ">=0.9" +PyMuPDF = "^1.21.1" +PyPDF2 = "^1.26.0" +pyrfc6266 = "^1.0.2" +pyrus-api = "^2.12.0" +python = ">=3.8.2,<3.10" +python-multipart = "^0.0.9" +python-ldap = "^3.4.3" +python-Levenshtein = "~0.12.2" +PyYAML = "^6.0" +rabbitmq = "^0.2.0" +reportlab = "^3.6.11" +rich = "^13.6.0" +scikit-image = "^0.18.3" +sentry-sdk = "^1.14.0" +tqdm = "^4.62" +unidecode = "^1.1.1" +urllib3 = "~1.26" +uvicorn = "^0.29.0" +varsubst = "^2.0.0" +wheel = ">=0.37" +xlsx2html = "^0.4.4" +XlsxWriter = "^3.0.3" +zeep = "^4.1.0" + +[tool.poetry.group.dev.dependencies] +autopep8 = "^1.5" +black = "^23" +ipython = "^8.0" +jupyter = "^1.0" +jupyter-server = "^1.0" +mypy = "^0.790" +notebook = "^6.5.6" +pylint = "^2.6" +pylint-django = "~2.3" +pytest-asyncio = "^0.23.6" +pytest-django = "^4.5.2" diff --git a/tests/output/test_3/test3.toml b/tests/output/test_3/test3.toml new file mode 100644 index 0000000..db985d6 --- /dev/null +++ b/tests/output/test_3/test3.toml @@ -0,0 +1,164 @@ +[tool.poetry] +description = [ "DCR", "DML", "D",] +name = [ "dcr", "dml", "d",] +version = [ "1.8.1", "1.7.2",] + +[tool.poetry.dependencies] +"pdfminer.six" = "^20220524" +aiofiles = "^23.2.1" +ansi2html = "^1.7" +asgi-lifespan = "^2.1.0" +bayoo-docx = "^0.2.20" +beautifulsoup4 = "^4.10" +biopython = "^1.81" +boto3 = "^1.16.56" +chardet = "^4.0.0" +cmake = "^3.21.1" +commonregex = "1.5.3" +compress_fasttext = "^0.0.6" +conllu = "^4.4" +coreapi = "^2.3.3" +corus = "^0.7.0" +cython = "0.29.37" +datapunt-keycloak-oidc = "^0.5.1" +Django = "~3.1" +django-allauth = "^0.51" +django-auth-ldap = "^4.1" +django-bootstrap4 = "^22.1" +django-cors-headers = "^3.2.1" +django-extensions = "^3.1.0" +django-rosetta = "^0.9.5" +djangorestframework = "^3.13" +djangorestframework-simplejwt = "^4.5" +djangorestframework-xml = "^2.0.0" +drf-yasg = "^1.20.0" +editdistance = ">=0.6.2" +env2dict = "^0.0.3" +fast_deskew = "1.0" +filelock = "^3.4.2" +filetype = "^1.2.0" +flashtext = "^2.7" +fuzzysearch = "^0.7.3" +fuzzywuzzy = "^0.18.0" +google-cloud-documentai = "^1.1.0" +gunicorn = "^21.2" +hvac = "^1.1.1" +ImageHash = "^4.2.1" +imbalanced-learn = "^0.11.0" +ipymarkup = "^0.9.0" +jsonfield = "^3.1.0" +langchain = "^0.0.325" +matplotlib = "^3.4.3" +minio = ">=7.1.17" +murmurhash = "^1.0.3" +natasha = "~1.3" +navec = "^0.10.0" +nbdime = "^3.1.0" +nerus = "^1.7.0" +nltk = "^3.6.5" +numpy = "~1.23" +ocrmypdf = "^13.0.0" +onnxruntime = "^1.12.1" +openai = "^1.3.5" +opencv-python = "4.5.4.60" +openpyxl = "^3.1.2" +orjson = "<=3.9.10" +pandas = "~1.5" +patiencediff = "^0.2.14" +patool = "^1.12" +pdf2image = "^1.16.0" +phonenumbers = "^8.12.15" +pika = "^1.2.0" +pikepdf = "^8" +Pillow = "^10.1" +protobuf = "^3.20" +psutil = "^5.8.0" +psycopg2-binary = "^2.9.1" +py7zr = "^0.20.1" +pyaescrypt = ">=0.4.3" +pyap = "^0.3.1" +pycel = "^1.0b30" +pyclipper = "1.3.0.post5" +pyctcdecode = "0.5.0" +pydantic-settings = "^2.2.1" +pyexcel = "^0.6.1" +pyexcel-xls = "^0.5.8" +pyexcel-xlsx = "^0.5.8" +PyJWT = "^2.4.0" +PyMuPDF = "^1.21.1" +pymystem3 = "~0.2.0" +pyOpenSSL = ">=23.0" +pypdf = "^3.17.2" +PyPDF2 = "^1.26.0" +pypdfium2 = "^4.24.0" +pyrfc6266 = "^1.0.2" +pyrsistent = "0.16" +pyrus-api = "^2.12.0" +pytesseract = "^0.3.10" +pytest = "^6.2.2" +python = ">=3.8.2,<3.10" +python-ldap = "^3.4.3" +python-Levenshtein = "~0.12.2" +python-multipart = "^0.0.9" +python-poppler = "^0.4.1" +pyunpack = "^0.3" +PyYAML = "^6.0" +pyzbar = "^0.1.8" +rabbitmq = "^0.2.0" +razdel = "~0.5" +reportlab = "^3.6.11" +rich = "^13.6.0" +scikit-image = "^0.18.3" +scikit-learn = ">= 1.1, < 1.3" +sentencepiece = "^0.1.99" +sentry-sdk = "^1.14.0" +shapely = "^2.0.1" +spacy = "~2.3" +spyne = "^2.14.0" +tensorboard = "^2.4.1" +termcolor = "^1.1.0" +tifftools = "^1.3.6" +tiktoken = "^0.4.0" +tqdm = "^4.62" +unidecode = "^1.1.1" +unrar = "^0.4" +urllib3 = "~1.26" +uvicorn = "^0.29.0" +varsubst = "^2.0.0" +wand = ">=0.5.8" +weasyprint = "^52.5" +wheel = ">=0.37" +xlrd = "^2.0" +xlsx2html = "^0.4.4" +XlsxWriter = "^3.0.3" +zeep = "^4.1.0" + +[tool.poetry.dependencies.fastapi] +extras = [ "uvicorn",] +version = "^0.110.0" + +[tool.poetry.dependencies.httpx] +extras = [ "socks", "brotli", "http2",] +version = [ "^0.26", "^0.27.0",] + +[tool.poetry.dependencies.ordered-rectangles] +extras = [ "extra",] +version = ">=0.0.6" + +[tool.poetry.dependencies.pymorphy2] +extras = [ "speedups",] +version = [ "^0.9.1", ">=0.9",] + +[tool.poetry.group.dev.dependencies] +autopep8 = "^1.5" +black = "^23" +ipython = "^8.0" +jupyter = "^1.0" +jupyter-server = "^1.0" +mypy = "^0.790" +notebook = "^6.5.6" +pre-commit = "^3.5.0" +pylint = "^2.6" +pylint-django = "~2.3" +pytest-asyncio = "^0.23.6" +pytest-django = "^4.5.2" diff --git a/tests/test_main.py b/tests/test_main.py index 80b5c3c..03fc2e4 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -46,3 +46,24 @@ def test_2(): assert d1 == d2 + +def test_3(): + result = os.path.join(PROJECT_DIR, 'tmp', 'test3.toml') + + toml_union_process( + files=[ + os.path.join(CUR_DIR, 'input', 'test_3') + ], + outfile=result, + ) + + d1 = read_toml(result) + d2 = read_toml(os.path.join(CUR_DIR, 'output', 'test_3', 'test3.toml')) + + assert d1 == d2 + + +if __name__ == '__main__': + test_3() + + diff --git a/toml_union/toml_union.py b/toml_union/toml_union.py index f8eadf7..060ac8e 100644 --- a/toml_union/toml_union.py +++ b/toml_union/toml_union.py @@ -383,15 +383,40 @@ def union_2_data_dicts(d1: DATA_DICT, d2: DATA_DICT) -> DATA_DICT: for key, v2 in d2.items(): if key in d1: v1 = d1[key] - assert type(v1) is type(v2), f"{key}: incompatible types\n{pprint.pformat(v1)}\n\tand\n{pprint.pformat(v2)}" - - if isinstance(v1, list): - d1[key] = TomlValue.union_list(v1 + v2) - elif isinstance(v1, dict): - d1[key] = union_2_data_dicts(v1, v2) - else: - assert isinstance(v1, TomlValue) - d1[key].update(v2) + if type(v1) is type(v2): + + if isinstance(v1, list): + d1[key] = TomlValue.union_list(v1 + v2) + elif isinstance(v1, dict): + d1[key] = union_2_data_dicts(v1, v2) + else: + assert isinstance(v1, TomlValue) + v1.update(v2) + + continue + + # special versions case like + # httpx = {extras = ["socks", "brotli", "http2"], version = "^0.26"} + # vs + # httpx = "^0.27.0" + if isinstance(v1, (dict, TomlValue)) and isinstance(v2, (dict, TomlValue)): + # here -- on object is dict and other is TomlValue + if isinstance(v1, dict) and 'version' in v1: + version = v1['version'] + if isinstance(version, TomlValue): + version.update(v2) + continue + + if isinstance(v2, dict) and 'version' in v2: + version = v2['version'] + if isinstance(version, TomlValue): + version.update(v1) # update version object + d1[key] = v2 # assign v2 object to v1 dictionary + continue + + raise ValueError( + f"{key}: incompatible types\n{pprint.pformat(v1)}\n\tand\n{pprint.pformat(v2)}" + ) else: d1[key] = v2