From 054e33183e4f1caa449191cc9c3c1e6ef59ac573 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Tue, 26 May 2026 15:12:30 -0400 Subject: [PATCH 1/3] first try --- .github/workflows/python-coverage.yml | 22 +- .github/workflows/python-lint.yml | 28 +- .github/workflows/python-test.yml | 28 +- .github/workflows/yamllint.yml | 11 +- Makefile | 19 +- PIPENV_MIGRATION.md | 142 ++++++ Pipfile | 38 ++ Pipfile.lock | 641 ++++++++++++++++++++++++++ README.md | 5 +- 9 files changed, 911 insertions(+), 23 deletions(-) create mode 100644 PIPENV_MIGRATION.md create mode 100644 Pipfile create mode 100644 Pipfile.lock diff --git a/.github/workflows/python-coverage.yml b/.github/workflows/python-coverage.yml index 47449f85..80b9c14e 100644 --- a/.github/workflows/python-coverage.yml +++ b/.github/workflows/python-coverage.yml @@ -15,12 +15,7 @@ env: jobs: coverage: name: "Python CI Coverage" - strategy: - fail-fast: false - matrix: - os: ["ubuntu-24.04"] - python: ["3.14"] - runs-on: ${{ matrix.os }} + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: @@ -30,11 +25,22 @@ jobs: - name: Setup Python uses: actions/setup-python@master with: - python-version: ${{ matrix.python }} + python-version: 3.14 + + - name: Install tooling + run: > + sudo apt install pipenv + + - name: Tooling check + run: | + python3 --version + pipenv --version + make --version - name: Install run: | - pip3 install -r requirements.txt + # Use the lockfile to install deterministic, audited dependencies + pipenv sync --dev - name: Test an coverage collect run: > diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml index c49105f2..f05522c1 100644 --- a/.github/workflows/python-lint.yml +++ b/.github/workflows/python-lint.yml @@ -26,9 +26,35 @@ jobs: with: python-version: ${{ matrix.python }} + - name: Install tooling on Ubuntu + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y pipenv + shell: bash + + - name: Install tooling on macOS + if: runner.os == 'macOS' + run: | + brew install pipenv + shell: bash + + - name: Install tooling on Windows + if: runner.os == 'Windows' + run: | + choco install pipenv -y + shell: pwsh + + - name: Tooling check + run: | + python3 --version + pipenv --version + make --version + - name: Install run: | - pip3 install -r requirements.txt + # Use the lockfile to install deterministic, audited dependencies + pipenv sync --dev - name: Lint (pylint) run: | diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 6fd528a9..39be82d6 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -29,9 +29,35 @@ jobs: with: python-version: ${{ matrix.python }} + - name: Install tooling on Ubuntu + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y pipenv + shell: bash + + - name: Install tooling on macOS + if: runner.os == 'macOS' + run: | + brew install pipenv + shell: bash + + - name: Install tooling on Windows + if: runner.os == 'Windows' + run: | + choco install pipenv -y + shell: pwsh + + - name: Tooling check + run: | + python3 --version + pipenv --version + make --version + - name: Install run: | - pip3 install -r requirements.txt + # Use the lockfile to install deterministic, audited dependencies + pipenv sync --dev - name: Test run: > diff --git a/.github/workflows/yamllint.yml b/.github/workflows/yamllint.yml index 905d70ba..ed34f802 100644 --- a/.github/workflows/yamllint.yml +++ b/.github/workflows/yamllint.yml @@ -17,8 +17,17 @@ jobs: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: 3.14 + + - name: Install pipenv + run: > + sudo apt install pipenv - name: Install yamllint - run: pip install yamllint + run: > + pipenv sync --dev - name: Lint YAML files run: > diff --git a/Makefile b/Makefile index f897de88..93b4c58e 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ BRUTEFORCE :=$(shell echo '${BRUTEFORCE}'| tr '[:lower:]' '[:upper:]'| tr -d '[: .EXPORT_ALL_VARIABLES: # (2) RUNTIME_TOOL=python3 -PACKAGE_TOOL=pip3 +PACKAGE_TOOL=pipenv # DOCKER BUILDKIT_PROGRESS=plain @@ -36,11 +36,10 @@ DOCKER_COMPOSE=docker compose help: list @echo "" @echo "Note: create and activate the environment in your local shell type (example):" - @echo " python3 -m venv ./.venv" - @echo " source .venv/bin/activate" + @echo " pipenv install --dev" + @echo " pipenv shell" @echo "See: " - @echo " https://docs.python.org/3/library/venv.html#creating-virtual-environments" - @echo " https://docs.python.org/3/library/venv.html#how-venvs-work" + @echo " https://pipenv.pypa.io/en/latest/" list: @LC_ALL=C $(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' @@ -65,20 +64,20 @@ dependencies: @echo "################################################################################" @echo "## Dependencies: ###############################################################" @echo "################################################################################" - ${PACKAGE_TOOL} install -r requirements.txt + ${PACKAGE_TOOL} install --dev @echo "################################################################################" outdated: - ${PACKAGE_TOOL} list --outdated + ${PACKAGE_TOOL} update --outdated update: - ${PACKAGE_TOOL} freeze > requirements.txt + ${PACKAGE_TOOL} lock --requirements > requirements.txt upgrade: - ${PACKAGE_TOOL} list --outdated | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip3 install -U + ${PACKAGE_TOOL} update --dev clean: - ${PACKAGE_TOOL} freeze > unins ; ${PACKAGE_TOOL} uninstall -y -r unins ; rm unins + ${PACKAGE_TOOL} --rm || true rm -f .coverage rm -fr .pytest_cache rm -fr htmlcov diff --git a/PIPENV_MIGRATION.md b/PIPENV_MIGRATION.md new file mode 100644 index 00000000..eb988787 --- /dev/null +++ b/PIPENV_MIGRATION.md @@ -0,0 +1,142 @@ +# Migración a Pipenv + +## Resumen + +El proyecto ha sido migrado de usar `requirements.txt` con `pip` a usar `pipenv` para la gestión de dependencias. Esto proporciona: + +- ✅ **Lock-file reproducible**: `Pipfile.lock` asegura versiones exactas y reproducibles +- ✅ **Separación clara**: Dependencias de producción vs desarrollo +- ✅ **Mejor seguridad**: Detección automática de vulnerabilidades +- ✅ **Gestión simplificada**: Un archivo de configuración único + +## Archivos Modificados + +### Nuevos archivos: +- **`Pipfile`** - Definición de dependencias y configuración del proyecto +- **`Pipfile.lock`** - Lock-file con versiones exactas resueltas (DEBE estar en control de versiones) + +### Archivos actualizados: +- **`Makefile`** - Todos los comandos de pip3 han sido reemplazados por pipenv +- **`Dockerfile`** - Instalación de pipenv y uso de Pipfile/Pipfile.lock +- **`.gitignore`** - Sin cambios (ya tenía configuración adecuada para pipenv) + +### Archivo deprecado (pero mantenido para compatibilidad): +- **`requirements.txt`** - Ya no es necesario, pero se mantiene como referencia + +## Instalación + +### Primera vez (local): + +```bash +# Instalar pipenv si no lo tienes +pip3 install pipenv + +# Desde el directorio del proyecto +pipenv install --dev +``` + +### Activar el ambiente virtual: + +```bash +pipenv shell +``` + +O ejecutar comandos dentro del ambiente sin activarlo: + +```bash +pipenv run python3 script.py +``` + +## Comandos Principales + +```bash +# Instalar dependencias (después de cambios en Pipfile) +make install +# o +pipenv install --dev + +# Actualizar todas las dependencias +make upgrade + +# Verificar dependencias obsoletas +make update + +# Limpiar el ambiente +make clean + +# Ejecutar tests +make test + +# Ejecutar linting +make lint + +# Cobertura +make coverage +``` + +## Cambios en el Makefile + +| Comando antiguo | Comando nuevo | +|---|---| +| `pip3 install -r requirements.txt` | `pipenv install --dev` | +| `pip3 list --outdated` | `pipenv check` | +| `pip3 freeze > requirements.txt` | `pipenv update` | +| `python3 -m pytest` | `pipenv run python3 -m pytest` | + +## Docker + +El Dockerfile ha sido actualizado para: +1. Instalar pipenv en la imagen base +2. Usar `Pipfile` y `Pipfile.lock` en lugar de `requirements.txt` +3. Ejecutar `make dependencies` que ahora usa pipenv + +```bash +# Construir imagen +docker compose build + +# Ejecutar tests en contenedor +docker compose run --rm algorithm-exercises-py-test make test +``` + +## Beneficios + +### Reproducibilidad +- El `Pipfile.lock` contiene exactamente las versiones que fueron instaladas +- Cualquiera que clone el proyecto obtendrá exactamente las mismas versiones + +### Seguridad +```bash +pipenv check # Detecta vulnerabilidades conocidas +``` + +### Gestión de dependencias +```bash +pipenv update package_name # Actualizar paquete específico +pipenv graph # Ver árbol de dependencias +pipenv requirements # Generar requirements.txt si es necesario +``` + +### Desarrollo +- Dependencias de desarrollo separadas en `[dev-packages]` +- Fácil colaboración sin instalar herramientas innecesarias + +## Migración desde requirements.txt + +Si necesitas volver a generar `Pipfile` desde un `requirements.txt`: + +```bash +# Borrar Pipfile y Pipfile.lock actuales +rm Pipfile Pipfile.lock + +# Generar nuevos desde requirements.txt +pipenv install --requirements requirements.txt + +# Luego regenerar lock +pipenv lock +``` + +## Referencias + +- [Documentación de Pipenv](https://pipenv.pypa.io/) +- [Guía de instalación](https://pipenv.pypa.io/en/latest/install.html) +- [Workflows comunes](https://pipenv.pypa.io/en/latest/workflows.html) diff --git a/Pipfile b/Pipfile new file mode 100644 index 00000000..58aee3cf --- /dev/null +++ b/Pipfile @@ -0,0 +1,38 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] + +[dev-packages] +yamllint = "==1.32.0" +astroid = "==4.0.3" +attrs = "==26.1.0" +autopep8 = "==2.3.2" +coverage = "==7.13.5" +dill = "==0.4.1" +exceptiongroup = "==1.3.1" +flake8 = "==7.3.0" +iniconfig = "==2.3.0" +isort = "==8.0.1" +lazy-object-proxy = "==1.12.0" +mccabe = "==0.7.0" +nodeenv = "==1.10.0" +packaging = "==26.2" +platformdirs = "==4.9.6" +pluggy = "==1.6.0" +pycodestyle = "==2.14.0" +pyflakes = "==3.4.0" +pylint = "==4.0.5" +pyright = "==1.1.409" +pytest = "==9.0.3" +pytest-cov = "==7.1.0" +tomli = "==2.4.1" +tomlkit = "==0.14.0" +typing-extensions = "==4.15.0" +wrapt = "==2.1.2" +zipp = ">=3.23.1" + +[requires] +python_version = "3.12" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 00000000..4e7291d4 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,641 @@ +{ + "_meta": { + "hash": { + "sha256": "ad89cfef4a3cd3eba0a08db65f71ac1e8ef83291aa9d8a159245534412e5f839" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.12" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": {}, + "develop": { + "astroid": { + "hashes": [ + "sha256:08d1de40d251cc3dc4a7a12726721d475ac189e4e583d596ece7422bc176bda3", + "sha256:864a0a34af1bd70e1049ba1e61cee843a7252c826d97825fcee9b2fcbd9e1b14" + ], + "index": "pypi", + "markers": "python_full_version >= '3.10.0'", + "version": "==4.0.3" + }, + "attrs": { + "hashes": [ + "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", + "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==26.1.0" + }, + "autopep8": { + "hashes": [ + "sha256:89440a4f969197b69a995e4ce0661b031f455a9f776d2c5ba3dbd83466931758", + "sha256:ce8ad498672c845a0c3de2629c15b635ec2b05ef8177a6e7c91c74f3e9b51128" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==2.3.2" + }, + "coverage": { + "extras": [ + "toml" + ], + "hashes": [ + "sha256:012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256", + "sha256:02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b", + "sha256:03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5", + "sha256:0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d", + "sha256:04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a", + "sha256:0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969", + "sha256:0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642", + "sha256:084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87", + "sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740", + "sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215", + "sha256:0cef0cdec915d11254a7f549c1170afecce708d30610c6abdded1f74e581666d", + "sha256:0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422", + "sha256:0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8", + "sha256:0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911", + "sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b", + "sha256:145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587", + "sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8", + "sha256:1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606", + "sha256:258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9", + "sha256:259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf", + "sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633", + "sha256:2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6", + "sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43", + "sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2", + "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", + "sha256:356e76b46783a98c2a2fe81ec79df4883a1e62895ea952968fb253c114e7f930", + "sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc", + "sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247", + "sha256:3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75", + "sha256:3e1bb5f6c78feeb1be3475789b14a0f0a5b47d505bfc7267126ccbd50289999e", + "sha256:3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376", + "sha256:460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01", + "sha256:48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1", + "sha256:4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3", + "sha256:4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743", + "sha256:505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9", + "sha256:52f444e86475992506b32d4e5ca55c24fc88d73bcbda0e9745095b28ef4dc0cf", + "sha256:5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e", + "sha256:5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1", + "sha256:60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd", + "sha256:631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b", + "sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab", + "sha256:66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d", + "sha256:67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a", + "sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0", + "sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510", + "sha256:6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f", + "sha256:7034b5c56a58ae5e85f23949d52c14aca2cfc6848a31764995b7de88f13a1ea0", + "sha256:704de6328e3d612a8f6c07000a878ff38181ec3263d5a11da1db294fa6a9bdf8", + "sha256:7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf", + "sha256:7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209", + "sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9", + "sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3", + "sha256:78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3", + "sha256:79060214983769c7ba3f0cee10b54c97609dca4d478fa1aa32b914480fd5738d", + "sha256:7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd", + "sha256:7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2", + "sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882", + "sha256:843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09", + "sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea", + "sha256:8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c", + "sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562", + "sha256:941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3", + "sha256:972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806", + "sha256:9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e", + "sha256:9b74db26dfea4f4e50d48a4602207cd1e78be33182bc9cbf22da94f332f99878", + "sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e", + "sha256:9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9", + "sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45", + "sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29", + "sha256:a1a6d79a14e1ec1832cabc833898636ad5f3754a678ef8bb4908515208bf84f4", + "sha256:a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c", + "sha256:ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479", + "sha256:ad146744ca4fd09b50c482650e3c1b1f4dfa1d4792e0a04a369c7f23336f0400", + "sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c", + "sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a", + "sha256:bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf", + "sha256:be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686", + "sha256:bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de", + "sha256:bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028", + "sha256:c555b48be1853fe3997c11c4bd521cdd9a9612352de01fa4508f16ec341e6fe0", + "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179", + "sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16", + "sha256:ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85", + "sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a", + "sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0", + "sha256:d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810", + "sha256:d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161", + "sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607", + "sha256:da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26", + "sha256:da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819", + "sha256:dc022073d063b25a402454e5712ef9e007113e3a676b96c5f29b2bda29352f40", + "sha256:e0723d2c96324561b9aa76fb982406e11d93cdb388a7a7da2b16e04719cf7ca5", + "sha256:e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15", + "sha256:e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0", + "sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90", + "sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0", + "sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6", + "sha256:eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a", + "sha256:eb7fdf1ef130660e7415e0253a01a7d5a88c9c4d158bcf75cbbd922fd65a5b58", + "sha256:ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b", + "sha256:ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17", + "sha256:f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5", + "sha256:f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664", + "sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0", + "sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==7.13.5" + }, + "dill": { + "hashes": [ + "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d", + "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==0.4.1" + }, + "exceptiongroup": { + "hashes": [ + "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", + "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.3.1" + }, + "flake8": { + "hashes": [ + "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", + "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==7.3.0" + }, + "iniconfig": { + "hashes": [ + "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", + "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==2.3.0" + }, + "isort": { + "hashes": [ + "sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d", + "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75" + ], + "index": "pypi", + "markers": "python_full_version >= '3.10.0'", + "version": "==8.0.1" + }, + "lazy-object-proxy": { + "hashes": [ + "sha256:029d2b355076710505c9545aef5ab3f750d89779310e26ddf2b7b23f6ea03cd8", + "sha256:08c465fb5cd23527512f9bd7b4c7ba6cec33e28aad36fbbe46bf7b858f9f3f7f", + "sha256:0a83c6f7a6b2bfc11ef3ed67f8cbe99f8ff500b05655d8e7df9aab993a6abc95", + "sha256:1192e8c2f1031a6ff453ee40213afa01ba765b3dc861302cd91dbdb2e2660b00", + "sha256:14e348185adbd03ec17d051e169ec45686dcd840a3779c9d4c10aabe2ca6e1c0", + "sha256:15400b18893f345857b9e18b9bd87bd06aba84af6ed086187add70aeaa3f93f1", + "sha256:1cf69cd1a6c7fe2dbcc3edaa017cf010f4192e53796538cc7d5e1fedbfa4bcff", + "sha256:1f5a462d92fd0cfb82f1fab28b51bfb209fabbe6aabf7f0d51472c0c124c0c61", + "sha256:256262384ebd2a77b023ad02fbcc9326282bcfd16484d5531154b02bc304f4c5", + "sha256:31020c84005d3daa4cc0fa5a310af2066efe6b0d82aeebf9ab199292652ff036", + "sha256:338ab2f132276203e404951205fe80c3fd59429b3a724e7b662b2eb539bb1be9", + "sha256:3605b632e82a1cbc32a1e5034278a64db555b3496e0795723ee697006b980508", + "sha256:3d3964fbd326578bcdfffd017ef101b6fb0484f34e731fe060ba9b8816498c36", + "sha256:424a8ab6695400845c39f13c685050eab69fa0bbac5790b201cd27375e5e41d7", + "sha256:4a79b909aa16bde8ae606f06e6bbc9d3219d2e57fb3e0076e17879072b742c65", + "sha256:4ab2c584e3cc8be0dfca422e05ad30a9abe3555ce63e9ab7a559f62f8dbc6ff9", + "sha256:53c7fd99eb156bbb82cbc5d5188891d8fdd805ba6c1e3b92b90092da2a837073", + "sha256:563d2ec8e4d4b68ee7848c5ab4d6057a6d703cb7963b342968bb8758dda33a23", + "sha256:61d5e3310a4aa5792c2b599a7a78ccf8687292c8eb09cf187cca8f09cf6a7519", + "sha256:6763941dbf97eea6b90f5b06eb4da9418cc088fce0e3883f5816090f9afcde4a", + "sha256:67f07ab742f1adfb3966c40f630baaa7902be4222a17941f3d85fd1dae5565ff", + "sha256:717484c309df78cedf48396e420fa57fc8a2b1f06ea889df7248fdd156e58847", + "sha256:75ba769017b944fcacbf6a80c18b2761a1795b03f8899acdad1f1c39db4409be", + "sha256:7601ec171c7e8584f8ff3f4e440aa2eebf93e854f04639263875b8c2971f819f", + "sha256:7b22c2bbfb155706b928ac4d74c1a63ac8552a55ba7fff4445155523ea4067e1", + "sha256:800f32b00a47c27446a2b767df7538e6c66a3488632c402b4fb2224f9794f3c0", + "sha256:81d1852fb30fab81696f93db1b1e55a5d1ff7940838191062f5f56987d5fcc3e", + "sha256:86fd61cb2ba249b9f436d789d1356deae69ad3231dc3c0f17293ac535162672e", + "sha256:8c40b3c9faee2e32bfce0df4ae63f4e73529766893258eca78548bac801c8f66", + "sha256:8ee0d6027b760a11cc18281e702c0309dd92da458a74b4c15025d7fc490deede", + "sha256:997b1d6e10ecc6fb6fe0f2c959791ae59599f41da61d652f6c903d1ee58b7370", + "sha256:a61095f5d9d1a743e1e20ec6d6db6c2ca511961777257ebd9b288951b23b44fa", + "sha256:a6b7ea5ea1ffe15059eb44bcbcb258f97bcb40e139b88152c40d07b1a1dfc9ac", + "sha256:ae575ad9b674d0029fc077c5231b3bc6b433a3d1a62a8c363df96974b5534728", + "sha256:be5fe974e39ceb0d6c9db0663c0464669cf866b2851c73971409b9566e880eab", + "sha256:be9045646d83f6c2664c1330904b245ae2371b5c57a3195e4028aedc9f999655", + "sha256:c1ca33565f698ac1aece152a10f432415d1a2aa9a42dfe23e5ba2bc255ab91f6", + "sha256:c3b2e0af1f7f77c4263759c4824316ce458fabe0fceadcd24ef8ca08b2d1e402", + "sha256:c4fcbe74fb85df8ba7825fa05eddca764138da752904b378f0ae5ab33a36c308", + "sha256:c9defba70ab943f1df98a656247966d7729da2fe9c2d5d85346464bf320820a3", + "sha256:cc6e3614eca88b1c8a625fc0a47d0d745e7c3255b21dac0e30b3037c5e3deeb8", + "sha256:d01c7819a410f7c255b20799b65d36b414379a30c6f1684c7bd7eb6777338c1b", + "sha256:efff4375a8c52f55a145dc8487a2108c2140f0bec4151ab4e1843e52eb9987ad", + "sha256:fdc70d81235fc586b9e3d1aeef7d1553259b62ecaae9db2167a5d2550dcc391a" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==1.12.0" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "nodeenv": { + "hashes": [ + "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", + "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb" + ], + "index": "pypi", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==1.10.0" + }, + "packaging": { + "hashes": [ + "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", + "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==26.2" + }, + "pathspec": { + "hashes": [ + "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", + "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189" + ], + "markers": "python_version >= '3.9'", + "version": "==1.1.1" + }, + "platformdirs": { + "hashes": [ + "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", + "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==4.9.6" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==1.6.0" + }, + "pycodestyle": { + "hashes": [ + "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", + "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==2.14.0" + }, + "pyflakes": { + "hashes": [ + "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", + "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==3.4.0" + }, + "pygments": { + "hashes": [ + "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", + "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" + ], + "markers": "python_version >= '3.9'", + "version": "==2.20.0" + }, + "pylint": { + "hashes": [ + "sha256:00f51c9b14a3b3ae08cff6b2cdd43f28165c78b165b628692e428fb1f8dc2cf2", + "sha256:8cd6a618df75deb013bd7eb98327a95f02a6fb839205a6bbf5456ef96afb317c" + ], + "index": "pypi", + "markers": "python_full_version >= '3.10.0'", + "version": "==4.0.5" + }, + "pyright": { + "hashes": [ + "sha256:986ee05beca9e077c165758ad123667c679e050059a2546aa02473930394bc93", + "sha256:aa3ea228cab90c845c7a60d28db7a844c04315356392aa09fafcee98c8c22fb3" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.1.409" + }, + "pytest": { + "hashes": [ + "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", + "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==9.0.3" + }, + "pytest-cov": { + "hashes": [ + "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", + "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==7.1.0" + }, + "pyyaml": { + "hashes": [ + "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", + "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", + "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", + "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", + "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", + "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", + "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", + "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", + "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", + "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", + "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", + "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6", + "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", + "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", + "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", + "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", + "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", + "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", + "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295", + "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", + "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", + "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", + "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", + "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", + "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", + "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", + "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", + "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b", + "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", + "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", + "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", + "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", + "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369", + "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", + "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", + "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", + "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", + "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", + "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", + "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", + "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", + "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", + "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", + "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", + "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", + "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", + "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", + "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", + "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", + "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4", + "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", + "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", + "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", + "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", + "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", + "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", + "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", + "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", + "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", + "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", + "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", + "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f", + "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", + "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", + "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", + "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", + "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", + "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", + "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", + "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3", + "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", + "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", + "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.3" + }, + "tomli": { + "hashes": [ + "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", + "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", + "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", + "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", + "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", + "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", + "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", + "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", + "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", + "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", + "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", + "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", + "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", + "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", + "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", + "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", + "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", + "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", + "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", + "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", + "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", + "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", + "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", + "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", + "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", + "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", + "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", + "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", + "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", + "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", + "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", + "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", + "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", + "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", + "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", + "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", + "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", + "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", + "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", + "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", + "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", + "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", + "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", + "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", + "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", + "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", + "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.4.1" + }, + "tomlkit": { + "hashes": [ + "sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680", + "sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==0.14.0" + }, + "typing-extensions": { + "hashes": [ + "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", + "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==4.15.0" + }, + "wrapt": { + "hashes": [ + "sha256:08ffa54146a7559f5b8df4b289b46d963a8e74ed16ba3687f99896101a3990c5", + "sha256:0fc04bc8664a8bc4c8e00b37b5355cffca2535209fba1abb09ae2b7c76ddf82b", + "sha256:1370e516598854e5b4366e09ce81e08bfe94d42b0fd569b88ec46cc56d9164a9", + "sha256:162e4e2ba7542da9027821cb6e7c5e068d64f9a10b5f15512ea28e954893a267", + "sha256:16997dfb9d67addc2e3f41b62a104341e80cac52f91110dece393923c0ebd5ca", + "sha256:1c51c738d7d9faa0b3601708e7e2eda9bf779e1b601dce6c77411f2a1b324a63", + "sha256:1c6cc827c00dc839350155f316f1f8b4b0c370f52b6a19e782e2bda89600c7dc", + "sha256:2b8b28e97a44d21836259739ae76284e180b18abbb4dcfdff07a415cf1016c3e", + "sha256:2d3ff4f0024dd224290c0eabf0240f1bfc1f26363431505fb1b0283d3b08f11d", + "sha256:305d8a1755116bfdad5dda9e771dcb2138990a1d66e9edd81658816edf51aed1", + "sha256:3144b027ff30cbd2fca07c0a87e67011adb717eb5f5bd8496325c17e454257a3", + "sha256:3278c471f4468ad544a691b31bb856374fbdefb7fee1a152153e64019379f015", + "sha256:3756219045f73fb28c5d7662778e4156fbd06cf823c4d2d4b19f97305e52819c", + "sha256:3769a77df8e756d65fbc050333f423c01ae012b4f6731aaf70cf2bef61b34596", + "sha256:3969c56e4563c375861c8df14fa55146e81ac11c8db49ea6fb7f2ba58bc1ff9a", + "sha256:3996a67eecc2c68fd47b4e3c564405a5777367adfd9b8abb58387b63ee83b21e", + "sha256:3b8d15e52e195813efe5db8cec156eebe339aaf84222f4f4f051a6c01f237ed7", + "sha256:3beb22f674550d5634642c645aba4c72a2c66fb185ae1aebe1e955fae5a13baf", + "sha256:3d7b6fd105f8b24e5bd23ccf41cb1d1099796524bcc6f7fbb8fe576c44befbc9", + "sha256:4006c351de6d5007aa33a551f600404ba44228a89e833d2fadc5caa5de8edfbf", + "sha256:45914e8efbe4b9d5102fcf0e8e2e3258b83a5d5fba9f8f7b6d15681e9d29ffe0", + "sha256:467e7c76315390331c67073073d00662015bb730c566820c9ca9b54e4d67fd04", + "sha256:478282ebd3795a089154fb16d3db360e103aa13d3b2ad30f8f6aac0d2207de0e", + "sha256:4b7a86d99a14f76facb269dc148590c01aaf47584071809a70da30555228158c", + "sha256:4bdf26e03e6d0da3f0e9422fd36bcebf7bc0eeb55fdf9c727a09abc6b9fe472e", + "sha256:5681123e60aed0e64c7d44f72bbf8b4ce45f79d81467e2c4c728629f5baf06eb", + "sha256:577dff354e7acd9d411eaf4bfe76b724c89c89c8fc9b7e127ee28c5f7bcb25b6", + "sha256:57d7c0c980abdc5f1d98b11a2aa3bb159790add80258c717fa49a99921456d90", + "sha256:5a0a0a3a882393095573344075189eb2d566e0fd205a2b6414e9997b1b800a8b", + "sha256:5c35b5d82b16a3bc6e0a04349b606a0582bc29f573786aebe98e0c159bc48db6", + "sha256:5e0fa9cc32300daf9eb09a1f5bdc6deb9a79defd70d5356ba453bcd50aef3742", + "sha256:62503ffbc2d3a69891cf29beeaccdb4d5e0a126e2b6a851688d4777e01428dbb", + "sha256:6433ea84e1cfacf32021d2a4ee909554ade7fd392caa6f7c13f1f4bf7b8e8748", + "sha256:64a07a71d2730ba56f11d1a4b91f7817dc79bc134c11516b75d1921a7c6fcda1", + "sha256:6de1a3851c27e0bd6a04ca993ea6f80fc53e6c742ee1601f486c08e9f9b900a9", + "sha256:6f2c5390460de57fa9582bc8a1b7a6c86e1a41dfad74c5225fc07044c15cc8d1", + "sha256:6f8dbdd3719e534860d6a78526aafc220e0241f981367018c2875178cf83a413", + "sha256:6f97edc9842cf215312b75fe737ee7c8adda75a89979f8e11558dfff6343cc4b", + "sha256:710f6e5dfaf6a5d5c397d2d6758a78fecd9649deb21f1b645f5b57a328d63050", + "sha256:72aaa9d0d8e4ed0e2e98019cea47a21f823c9dd4b43c7b77bba6679ffcca6a00", + "sha256:76405518ca4e1b76fbb1b9f686cff93aebae03920cc55ceeec48ff9f719c5f67", + "sha256:767c0dbbe76cae2a60dd2b235ac0c87c9cccf4898aef8062e57bead46b5f6894", + "sha256:776867878e83130c7a04237010463372e877c1c994d449ca6aaafeab6aab2586", + "sha256:787fd6f4d67befa6fe2abdffcbd3de2d82dfc6fb8a6d850407c53332709d030b", + "sha256:79847b83eb38e70d93dc392c7c5b587efe65b3e7afcc167aa8abd5d60e8761c8", + "sha256:7dfa9f2cf65d027b951d05c662cc99ee3bd01f6e4691ed39848a7a5fffc902b2", + "sha256:84ce8f1c2104d2f6daa912b1b5b039f331febfeee74f8042ad4e04992bd95c8f", + "sha256:866abdbf4612e0b34764922ef8b1c5668867610a718d3053d59e24a5e5fcfc15", + "sha256:96159a0ee2b0277d44201c3b5be479a9979cf154e8c82fa5df49586a8e7679bb", + "sha256:970d57ed83fa040d8b20c52fe74a6ae7e3775ae8cff5efd6a81e06b19078484c", + "sha256:98ba61833a77b747901e9012072f038795de7fc77849f1faa965464f3f87ff2d", + "sha256:9c691a6bc752c0cc4711cc0c00896fcd0f116abc253609ef64ef930032821842", + "sha256:a5d516e22aedb7c9c1d47cba1c63160b1a6f61ec2f3948d127cd38d5cfbb556f", + "sha256:a76d61a2e851996150ba0f80582dd92a870643fa481f3b3846f229de88caf044", + "sha256:a819e39017f95bf7aede768f75915635aa8f671f2993c036991b8d3bfe8dbb6f", + "sha256:a8914c754d3134a3032601c6984db1c576e6abaf3fc68094bb8ab1379d75ff92", + "sha256:a9372fc3639a878c8e7d87e1556fa209091b0a66e912c611e3f833e2c4202be2", + "sha256:a93cd767e37faeddbe07d8fc4212d5cba660af59bdb0f6372c93faaa13e6e679", + "sha256:a9b9d50c9af998875a1482a038eb05755dfd6fe303a313f6a940bb53a83c3f18", + "sha256:a9dd9813825f7ecb018c17fd147a01845eb330254dff86d3b5816f20f4d6aaf8", + "sha256:b89f095fe98bc12107f82a9f7d570dc83a0870291aeb6b1d7a7d35575f55d98a", + "sha256:b8aefb4dbb18d904b96827435a763fa42fc1f08ea096a391710407a60983ced8", + "sha256:b8fd6fa2b2c4e7621808f8c62e8317f4aae56e59721ad933bac5239d913cf0e8", + "sha256:bbac24d879aa22998e87f6b3f481a5216311e7d53c7db87f189a7a0266dafffb", + "sha256:c0be8b5a74c5824e9359b53e7e58bef71a729bacc82e16587db1c4ebc91f7c5a", + "sha256:c20b757c268d30d6215916a5fa8461048d023865d888e437fab451139cad6c8e", + "sha256:c7e6cd120ef837d5b6f860a6ea3745f8763805c418bb2f12eeb1fa6e25f22d22", + "sha256:c87cf3f0c85e27b3ac7d9ad95da166bf8739ca215a8b171e8404a2d739897a45", + "sha256:c8e46ae8e4032792eb2f677dbd0d557170a8e5524d22acc55199f43efedd39bf", + "sha256:cef91c95a50596fcdc31397eb6955476f82ae8a3f5a8eabdc13611b60ee380ba", + "sha256:d1c5fea4f9fe3762e2b905fdd67df51e4be7a73b7674957af2d2ade71a5c075d", + "sha256:d307aa6888d5efab2c1cde09843d48c843990be13069003184b67d426d145394", + "sha256:d8f7740e1af13dff2684e4d56fe604a7e04d6c94e737a60568d8d4238b9a0c71", + "sha256:da1f00a557c66225d53b095a97eace0fc5349e3bfda28fa34ffae238978ee575", + "sha256:dad63212b168de8569b1c512f4eac4b57f2c6934b30df32d6ee9534a79f1493f", + "sha256:de9f1a2bbc5ac7f6012ec24525bdd444765a2ff64b5985ac6e0692144838542e", + "sha256:e3d3b35eedcf5f7d022291ecd7533321c4775f7b9cd0050a31a68499ba45757c", + "sha256:e5aeab8fe15c3dff75cfee94260dcd9cded012d4ff06add036c28fae7718593b", + "sha256:e6ed62c82ddf58d001096ae84ce7f833db97ae2263bff31c9b336ba8cfe3f508", + "sha256:eba8155747eb2cae4a0b913d9ebd12a1db4d860fc4c829d7578c7b989bd3f2f0", + "sha256:f01277d9a5fc1862f26f7626da9cf443bebc0abd2f303f41c5e995b15887dabd", + "sha256:f069e113743a21a3defac6677f000068ebb931639f789b5b226598e247a4c89e", + "sha256:f0d8fc30a43b5fe191cf2b1a0c82bab2571dadd38e7c0062ee87d6df858dd06e", + "sha256:f29c827a8d9936ac320746747a016c4bc66ef639f5cd0d32df24f5eacbf9c69f", + "sha256:f3b7d73012ea75aee5844de58c88f44cf62d0d62711e39da5a82824a7c4626a8", + "sha256:f8bc1c264d8d1cf5b3560a87bbdd31131573eb25f9f9447bb6252b8d4c44a3a1", + "sha256:f8fba1bae256186a83d1875b2b1f4e2d1242e8fac0f58ec0d7e41b26967b965c", + "sha256:fab036efe5464ec3291411fabb80a7a39e2dd80bae9bcbeeca5087fdfa891e19", + "sha256:ff2aad9c4cda28a8f0653fc2d487596458c2a3f475e56ba02909e950a9efa6a9", + "sha256:ff95d4264e55839be37bafe1536db2ab2de19da6b65f9244f01f332b5286cfbf" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==2.1.2" + }, + "yamllint": { + "hashes": [ + "sha256:d01dde008c65de5b235188ab3110bebc59d18e5c65fc8a58267cd211cd9df34a", + "sha256:d97a66e48da820829d96077d76b8dfbe6c6140f106e558dae87e81ac4e6b30b7" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.32.0" + }, + "zipp": { + "hashes": [ + "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", + "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==4.1.0" + } + } +} diff --git a/README.md b/README.md index 05a0b814..8db76446 100644 --- a/README.md +++ b/README.md @@ -93,17 +93,18 @@ require docker-compose and make installed. ### Install and Run directly Using a Python 3.x runtime in your SO. +[Pipenv](https://pipenv.pypa.io/en/latest/) is required. First, load virtual env environment: ```bash -source .venv/bin/activate +pipenv shell ``` You must install dependencies: ```bash -pip3 install -r requirements.txt +pipenv install ``` Every problem is a function with unit test. From 25df52dc7020a5b2e5f069c57dbe8579e8258b98 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Fri, 29 May 2026 19:03:45 -0400 Subject: [PATCH 2/3] [BUGFIX] sonarcloud: Omitting "--only-binary :all:" can lead to the execution of setup scripts. Make sure it is safe here. --- .github/workflows/python-coverage.yml | 8 +- .github/workflows/python-lint.yml | 12 +-- .github/workflows/python-test.yml | 6 +- Dockerfile | 8 +- Makefile | 22 ++-- PIPENV_MIGRATION.md | 142 -------------------------- Pipfile | 2 +- Pipfile.lock | 4 +- 8 files changed, 33 insertions(+), 171 deletions(-) delete mode 100644 PIPENV_MIGRATION.md diff --git a/.github/workflows/python-coverage.yml b/.github/workflows/python-coverage.yml index 80b9c14e..4528e5ab 100644 --- a/.github/workflows/python-coverage.yml +++ b/.github/workflows/python-coverage.yml @@ -44,22 +44,22 @@ jobs: - name: Test an coverage collect run: > - python3 -m coverage run -m pytest --verbose + pipenv run coverage run -m pytest --verbose -o log_cli=true --log-cli-level=INFO src/ - name: Coverage Report run: | - python3 -m coverage report + pipenv run coverage report - name: Coverage lcov (codecov) run: | - python3 -m coverage lcov -o coverage/lcov.info + pipenv run coverage lcov -o coverage/lcov.info - name: Coverage xml (sonarcloud) run: | - python3 -m coverage xml -o coverage/coverage.xml + pipenv run coverage xml -o coverage/coverage.xml - name: Upload coverage artifact uses: actions/upload-artifact@v7 diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml index f05522c1..872fc27c 100644 --- a/.github/workflows/python-lint.yml +++ b/.github/workflows/python-lint.yml @@ -42,7 +42,7 @@ jobs: - name: Install tooling on Windows if: runner.os == 'Windows' run: | - choco install pipenv -y + python -m pip install --user pipenv==2026.6.1 shell: pwsh - name: Tooling check @@ -58,20 +58,20 @@ jobs: - name: Lint (pylint) run: | - pylint --verbose --recursive yes src/ + pipenv run pylint --verbose --recursive yes src/ - name: Lint (flake8) run: | - python3 -m flake8 --verbose src/ + pipenv run flake8 --verbose src/ - name: Lint (pyright) static type checker run: | - python3 -m pyright --verbose src/ + pipenv run pyright --verbose src/ - name: Styling (pycodestyle) run: | - python3 -m pycodestyle --statistics src/ + pipenv run pycodestyle --statistics src/ - name: Styling (autopep8) run: | - python3 -m autopep8 --diff --recursive --exit-code --verbose . + pipenv run autopep8 --diff --recursive --exit-code --verbose . diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 39be82d6..183d505c 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -45,7 +45,7 @@ jobs: - name: Install tooling on Windows if: runner.os == 'Windows' run: | - choco install pipenv -y + python -m pip install --user pipenv==2026.6.1 shell: pwsh - name: Tooling check @@ -61,11 +61,11 @@ jobs: - name: Test run: > - coverage run -m pytest --verbose + pipenv run coverage run -m pytest --verbose -o log_cli=true --log-cli-level=INFO src/ - name: Coverage run: | - coverage report + pipenv run coverage report diff --git a/Dockerfile b/Dockerfile index c3a86693..a586f5b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,11 +13,15 @@ RUN apk add --update --no-cache make \ FROM init AS base ENV WORKDIR=/app +ENV LANG=C.UTF-8 WORKDIR ${WORKDIR} COPY ./Makefile ${WORKDIR}/ -COPY ./requirements.txt ${WORKDIR}/ -RUN make dependencies +COPY Pipfile ${WORKDIR}/ +COPY Pipfile.lock ${WORKDIR}/ + +RUN python -m pip install --no-cache-dir --root-user-action=ignore pipenv==2026.6.1 +RUN pipenv sync --dev --python=$(which python) ############################################################################### FROM base AS lint diff --git a/Makefile b/Makefile index 93b4c58e..a1e7f661 100644 --- a/Makefile +++ b/Makefile @@ -112,37 +112,37 @@ format/json: prettier --write ./src/**/*.json format/sources: - ${RUNTIME_TOOL} -m autopep8 --in-place --recursive --aggressive --aggressive --verbose src/ + ${PACKAGE_TOOL} run autopep8 --in-place --recursive --aggressive --aggressive --verbose src/ format: format/sources format/json ## Static code analysis test/static: dependencies - ${RUNTIME_TOOL} -m pylint --verbose --recursive yes src/ - ${RUNTIME_TOOL} -m flake8 --verbose src/ - ${RUNTIME_TOOL} -m pyright --verbose src/ + ${PACKAGE_TOOL} run pylint --verbose --recursive yes src/ + ${PACKAGE_TOOL} run flake8 --verbose src/ + ${PACKAGE_TOOL} run pyright --verbose src/ test/styling: dependencies - ${RUNTIME_TOOL} -m pycodestyle --statistics src/ - ${RUNTIME_TOOL} -m autopep8 --diff --recursive --exit-code --verbose . + ${PACKAGE_TOOL} run pycodestyle --statistics src/ + ${PACKAGE_TOOL} run autopep8 --diff --recursive --exit-code --verbose . ## Unit tests and coverage test: env dependencies - ${RUNTIME_TOOL} -m coverage run -m \ + ${PACKAGE_TOOL} run coverage run -m \ pytest --verbose \ -o log_cli=true \ --log-cli-level=${LOG_LEVEL} \ --full-trace src/ - ${RUNTIME_TOOL} -m coverage report + ${PACKAGE_TOOL} run coverage report coverage: test - ${RUNTIME_TOOL} -m coverage lcov -o coverage/lcov.info + ${PACKAGE_TOOL} run coverage lcov -o coverage/lcov.info coverage/xml: test - ${RUNTIME_TOOL} -m coverage xml -o coverage/coverage.xml + ${PACKAGE_TOOL} run coverage xml -o coverage/coverage.xml coverage/html: test - ${RUNTIME_TOOL} -m coverage html + ${PACKAGE_TOOL} run coverage html open htmlcov/index.html ## Docker Compose commands diff --git a/PIPENV_MIGRATION.md b/PIPENV_MIGRATION.md deleted file mode 100644 index eb988787..00000000 --- a/PIPENV_MIGRATION.md +++ /dev/null @@ -1,142 +0,0 @@ -# Migración a Pipenv - -## Resumen - -El proyecto ha sido migrado de usar `requirements.txt` con `pip` a usar `pipenv` para la gestión de dependencias. Esto proporciona: - -- ✅ **Lock-file reproducible**: `Pipfile.lock` asegura versiones exactas y reproducibles -- ✅ **Separación clara**: Dependencias de producción vs desarrollo -- ✅ **Mejor seguridad**: Detección automática de vulnerabilidades -- ✅ **Gestión simplificada**: Un archivo de configuración único - -## Archivos Modificados - -### Nuevos archivos: -- **`Pipfile`** - Definición de dependencias y configuración del proyecto -- **`Pipfile.lock`** - Lock-file con versiones exactas resueltas (DEBE estar en control de versiones) - -### Archivos actualizados: -- **`Makefile`** - Todos los comandos de pip3 han sido reemplazados por pipenv -- **`Dockerfile`** - Instalación de pipenv y uso de Pipfile/Pipfile.lock -- **`.gitignore`** - Sin cambios (ya tenía configuración adecuada para pipenv) - -### Archivo deprecado (pero mantenido para compatibilidad): -- **`requirements.txt`** - Ya no es necesario, pero se mantiene como referencia - -## Instalación - -### Primera vez (local): - -```bash -# Instalar pipenv si no lo tienes -pip3 install pipenv - -# Desde el directorio del proyecto -pipenv install --dev -``` - -### Activar el ambiente virtual: - -```bash -pipenv shell -``` - -O ejecutar comandos dentro del ambiente sin activarlo: - -```bash -pipenv run python3 script.py -``` - -## Comandos Principales - -```bash -# Instalar dependencias (después de cambios en Pipfile) -make install -# o -pipenv install --dev - -# Actualizar todas las dependencias -make upgrade - -# Verificar dependencias obsoletas -make update - -# Limpiar el ambiente -make clean - -# Ejecutar tests -make test - -# Ejecutar linting -make lint - -# Cobertura -make coverage -``` - -## Cambios en el Makefile - -| Comando antiguo | Comando nuevo | -|---|---| -| `pip3 install -r requirements.txt` | `pipenv install --dev` | -| `pip3 list --outdated` | `pipenv check` | -| `pip3 freeze > requirements.txt` | `pipenv update` | -| `python3 -m pytest` | `pipenv run python3 -m pytest` | - -## Docker - -El Dockerfile ha sido actualizado para: -1. Instalar pipenv en la imagen base -2. Usar `Pipfile` y `Pipfile.lock` en lugar de `requirements.txt` -3. Ejecutar `make dependencies` que ahora usa pipenv - -```bash -# Construir imagen -docker compose build - -# Ejecutar tests en contenedor -docker compose run --rm algorithm-exercises-py-test make test -``` - -## Beneficios - -### Reproducibilidad -- El `Pipfile.lock` contiene exactamente las versiones que fueron instaladas -- Cualquiera que clone el proyecto obtendrá exactamente las mismas versiones - -### Seguridad -```bash -pipenv check # Detecta vulnerabilidades conocidas -``` - -### Gestión de dependencias -```bash -pipenv update package_name # Actualizar paquete específico -pipenv graph # Ver árbol de dependencias -pipenv requirements # Generar requirements.txt si es necesario -``` - -### Desarrollo -- Dependencias de desarrollo separadas en `[dev-packages]` -- Fácil colaboración sin instalar herramientas innecesarias - -## Migración desde requirements.txt - -Si necesitas volver a generar `Pipfile` desde un `requirements.txt`: - -```bash -# Borrar Pipfile y Pipfile.lock actuales -rm Pipfile Pipfile.lock - -# Generar nuevos desde requirements.txt -pipenv install --requirements requirements.txt - -# Luego regenerar lock -pipenv lock -``` - -## Referencias - -- [Documentación de Pipenv](https://pipenv.pypa.io/) -- [Guía de instalación](https://pipenv.pypa.io/en/latest/install.html) -- [Workflows comunes](https://pipenv.pypa.io/en/latest/workflows.html) diff --git a/Pipfile b/Pipfile index 58aee3cf..4c3378a9 100644 --- a/Pipfile +++ b/Pipfile @@ -35,4 +35,4 @@ wrapt = "==2.1.2" zipp = ">=3.23.1" [requires] -python_version = "3.12" +python_version = "3" diff --git a/Pipfile.lock b/Pipfile.lock index 4e7291d4..0b8dc46c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "ad89cfef4a3cd3eba0a08db65f71ac1e8ef83291aa9d8a159245534412e5f839" + "sha256": "502c7bba76e2b3aa5bc1fa483b867f5556482dd21b599f7a7cba08f422a8b1ee" }, "pipfile-spec": 6, "requires": { - "python_version": "3.12" + "python_version": "3" }, "sources": [ { From b5456d7a56d717f8133c106f2c1dccab01fe01c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 02:03:34 +0000 Subject: [PATCH 3/3] Update dependency yamllint to v1.38.0 --- Pipfile | 2 +- Pipfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Pipfile b/Pipfile index 4c3378a9..156120fe 100644 --- a/Pipfile +++ b/Pipfile @@ -6,7 +6,7 @@ name = "pypi" [packages] [dev-packages] -yamllint = "==1.32.0" +yamllint = "==1.38.0" astroid = "==4.0.3" attrs = "==26.1.0" autopep8 = "==2.3.2" diff --git a/Pipfile.lock b/Pipfile.lock index 0b8dc46c..7f556891 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "502c7bba76e2b3aa5bc1fa483b867f5556482dd21b599f7a7cba08f422a8b1ee" + "sha256": "50dd6f325fd4608ba8e4c866896fbc0ecdfa1d5a40c15c115d345baecab3e442" }, "pipfile-spec": 6, "requires": { @@ -621,12 +621,12 @@ }, "yamllint": { "hashes": [ - "sha256:d01dde008c65de5b235188ab3110bebc59d18e5c65fc8a58267cd211cd9df34a", - "sha256:d97a66e48da820829d96077d76b8dfbe6c6140f106e558dae87e81ac4e6b30b7" + "sha256:09e5f29531daab93366bb061e76019d5e91691ef0a40328f04c927387d1d364d", + "sha256:fc394a5b3be980a4062607b8fdddc0843f4fa394152b6da21722f5d59013c220" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==1.32.0" + "markers": "python_version >= '3.10'", + "version": "==1.38.0" }, "zipp": { "hashes": [