From 0204a9c8d27cfad6fd7954a03ee2ef1224113b58 Mon Sep 17 00:00:00 2001 From: Lina Date: Fri, 6 Feb 2026 14:03:28 +0100 Subject: [PATCH 1/9] fix: dto --- pythonQEPest/dto/QEPestOutput.py | 3 ++- pythonQEPest/dto/__init__.py | 10 +++++++++- tests/core/test_qepest.py | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pythonQEPest/dto/QEPestOutput.py b/pythonQEPest/dto/QEPestOutput.py index cabcfb3..c37538a 100644 --- a/pythonQEPest/dto/QEPestOutput.py +++ b/pythonQEPest/dto/QEPestOutput.py @@ -1,3 +1,4 @@ +from typing import Optional from pydantic import BaseModel from .QEPestData import QEPestData @@ -5,7 +6,7 @@ class QEPestOutput(BaseModel): data: QEPestData - name: str = "" + name: Optional[str] = "" def to_array(self) -> list: return [ diff --git a/pythonQEPest/dto/__init__.py b/pythonQEPest/dto/__init__.py index 363a87c..e62fc25 100644 --- a/pythonQEPest/dto/__init__.py +++ b/pythonQEPest/dto/__init__.py @@ -1 +1,9 @@ -from . import QEPestData, QEPestInput, QEPestOutput +from .QEPestOutput import QEPestOutput +from .QEPestData import QEPestData +from .QEPestInput import QEPestInput + +__all__ = [ + "QEPestOutput", + "QEPestData", + "QEPestInput", +] diff --git a/tests/core/test_qepest.py b/tests/core/test_qepest.py index 6eef0c2..9ec2dac 100644 --- a/tests/core/test_qepest.py +++ b/tests/core/test_qepest.py @@ -4,7 +4,7 @@ from pydantic import ValidationError from pythonQEPest.core.qepest import QEPest -from pythonQEPest.dto.QEPestInput import QEPestInput +from pythonQEPest.dto import QEPestInput class TestQEPest: From babd789c50293dac70dbcf9d14f9f6977883ec09 Mon Sep 17 00:00:00 2001 From: Lina Date: Fri, 6 Feb 2026 14:06:43 +0100 Subject: [PATCH 2/9] fix: .gitignore --- .gitignore | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..64d49ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,216 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[codz] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py.cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +# Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +# poetry.lock +# poetry.toml + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python. +# https://pdm-project.org/en/latest/usage/project/#working-with-version-control +# pdm.lock +# pdm.toml +.pdm-python +.pdm-build/ + +# pixi +# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control. +# pixi.lock +# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one +# in the .venv directory. It is recommended not to include this directory in version control. +.pixi + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# Redis +*.rdb +*.aof +*.pid + +# RabbitMQ +mnesia/ +rabbitmq/ +rabbitmq-data/ + +# ActiveMQ +activemq-data/ + +# SageMath parsed files +*.sage.py + +# Environments +.env +.envrc +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +# .idea/ + +# Abstra +# Abstra is an AI-powered process automation framework. +# Ignore directories containing user credentials, local state, and settings. +# Learn more at https://abstra.io/docs +.abstra/ + +# Visual Studio Code +# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore +# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore +# and can be added to the global gitignore or merged into this file. However, if you prefer, +# you could uncomment the following to ignore the entire vscode folder +# .vscode/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Marimo +marimo/_static/ +marimo/_lsp/ +__marimo__/ + +# Streamlit +.streamlit/secrets.toml \ No newline at end of file From 03f58405ca566ac23d327b8cad6ac7af81e9f2e7 Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 18:31:40 +0100 Subject: [PATCH 3/9] feat: logger + env --- pythonQEPest/.env.example | 4 +++ pythonQEPest/cli/cli.py | 17 +++++++------ pythonQEPest/logger.py | 51 +++++++++++++++++++++++++++++++++++++++ pythonQEPest/main.py | 9 +++++++ 4 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 pythonQEPest/.env.example create mode 100644 pythonQEPest/logger.py diff --git a/pythonQEPest/.env.example b/pythonQEPest/.env.example new file mode 100644 index 0000000..cb65876 --- /dev/null +++ b/pythonQEPest/.env.example @@ -0,0 +1,4 @@ +LOG_LEVEL = "INFO" +LOG_FILE_LOCATION = "logs/app.log" + +APP_DEBUG_ENABLE = "false" \ No newline at end of file diff --git a/pythonQEPest/cli/cli.py b/pythonQEPest/cli/cli.py index eb98d32..5c5e912 100644 --- a/pythonQEPest/cli/cli.py +++ b/pythonQEPest/cli/cli.py @@ -1,6 +1,10 @@ from pythonQEPest.core.qepest_meta import QEPestMeta from pythonQEPest.helpers.get_num_of_cols import get_num_of_cols from pythonQEPest.helpers.get_values_from_line import get_values_from_line +import logging + + +logger = logging.getLogger(__name__) class CLI: @@ -19,7 +23,7 @@ def read_file_and_compute_params(self): if index == 0: if get_num_of_cols(line) != self.qepest.col_number: er = f"Error: Line {index} does not have seven elements." - print(er) + logger.error(er) self.qepest.noError = False break wr.write("Name QEH QEI QEF\n") @@ -30,18 +34,17 @@ def read_file_and_compute_params(self): splitted_line = line.split('\t')[0] wr.write( f"{splitted_line} {self.qepest.qex.qe_h} {self.qepest.qex.qe_i} {self.qepest.qex.qe_f}{chr(10)}" - # chr(10) = \n ) else: er = f"Error: Line {index} does not have seven elements." - print(er) + logger.error(er) self.qepest.noError = False if self.qepest.noError: - print("Computation completed") + logger.info("Computation completed") else: - print("Finished with errors") + logger.warning("Finished with errors") except FileNotFoundError as e: self.qepest.noError = False - print(f"Error: can't find : {input}") - print(e) + logger.error("Error: can't find : %s", input) + logger.exception(e) diff --git a/pythonQEPest/logger.py b/pythonQEPest/logger.py new file mode 100644 index 0000000..7dc3854 --- /dev/null +++ b/pythonQEPest/logger.py @@ -0,0 +1,51 @@ +import logging +from logging.handlers import RotatingFileHandler +import os +from pathlib import Path + + +def init_logger() -> None: + root_logger = logging.getLogger("pythonQEPest") + + log_file: str = os.getenv("LOG_FILE_LOCATION", "logs/app.log") + level = os.getenv("LOG_LEVEL", "INFO").upper() + + match level: + case "DEBUG": + level = logging.DEBUG + case "INFO": + level = logging.INFO + case "WARNING": + level = logging.WARNING + case "ERROR": + level = logging.ERROR + case _: + level = logging.INFO + + if root_logger.handlers: + return + + log_path = Path(log_file) + log_path.parent.mkdir(parents=True, exist_ok=True) + + formatter = logging.Formatter( + fmt="%(asctime)s %(levelname)s %(name)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + ) + + file_handler = RotatingFileHandler( + log_path, + maxBytes=1_000_000, + backupCount=3, + encoding="utf-8", + ) + file_handler.setLevel(level) + file_handler.setFormatter(formatter) + + console_handler = logging.StreamHandler() + console_handler.setLevel(level) + console_handler.setFormatter(formatter) + + root_logger.setLevel(level) + root_logger.addHandler(file_handler) + root_logger.addHandler(console_handler) diff --git a/pythonQEPest/main.py b/pythonQEPest/main.py index e0940f5..0cb52d2 100644 --- a/pythonQEPest/main.py +++ b/pythonQEPest/main.py @@ -1,5 +1,14 @@ +import os from pythonQEPest.cli.cli import CLI from pythonQEPest.core.qepest import QEPest +from pythonQEPest.logger import init_logger +from dotenv import load_dotenv + if __name__ == "__main__": + load_dotenv() + + if os.getenv("APP_DEBUG_ENABLE", "false").lower() == "true": + init_logger() + cli = CLI(qepest=QEPest()).read_file_and_compute_params() From 938cb9c91468459a4961466c1c627f9893aa176e Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 18:34:12 +0100 Subject: [PATCH 4/9] fix: forgot to update pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 2648f80..3872d34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ packages = [ [tool.poetry.dependencies] python = ">=3.9,<3.13" pydantic = "2.11.9" +python-dotenv = "^1.2.1" [tool.poetry.group.dev.dependencies] pytest = "^8.4.2" From ee5cc37477c09faedb0c0e1ebb08dbcc9acc089f Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 20:07:46 +0100 Subject: [PATCH 5/9] fix: APP_DEBUG_ENABLE inside logger init function --- pythonQEPest/logger.py | 4 ++++ pythonQEPest/main.py | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pythonQEPest/logger.py b/pythonQEPest/logger.py index 7dc3854..4480151 100644 --- a/pythonQEPest/logger.py +++ b/pythonQEPest/logger.py @@ -5,6 +5,10 @@ def init_logger() -> None: + # If debug mode is enabled, we want to log everything, otherwise we can skip logging + if os.getenv("APP_DEBUG_ENABLE", "true").lower() == "false": + return + root_logger = logging.getLogger("pythonQEPest") log_file: str = os.getenv("LOG_FILE_LOCATION", "logs/app.log") diff --git a/pythonQEPest/main.py b/pythonQEPest/main.py index 0cb52d2..64eb64b 100644 --- a/pythonQEPest/main.py +++ b/pythonQEPest/main.py @@ -1,4 +1,3 @@ -import os from pythonQEPest.cli.cli import CLI from pythonQEPest.core.qepest import QEPest from pythonQEPest.logger import init_logger @@ -8,7 +7,6 @@ if __name__ == "__main__": load_dotenv() - if os.getenv("APP_DEBUG_ENABLE", "false").lower() == "true": - init_logger() + init_logger() cli = CLI(qepest=QEPest()).read_file_and_compute_params() From fc8a77bb84b33e5f03297e6f70cfa10069dc158f Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 20:08:09 +0100 Subject: [PATCH 6/9] feat(tests): Logging --- tests/logger/__init__.py | 0 tests/logger/test_logging.py | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 tests/logger/__init__.py create mode 100644 tests/logger/test_logging.py diff --git a/tests/logger/__init__.py b/tests/logger/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/logger/test_logging.py b/tests/logger/test_logging.py new file mode 100644 index 0000000..84fa598 --- /dev/null +++ b/tests/logger/test_logging.py @@ -0,0 +1,105 @@ +import logging +from pythonQEPest.logger import init_logger + + +def _reset_logger(): + logger = logging.getLogger("pythonQEPest") + for h in list(logger.handlers): + logger.removeHandler(h) + h.close() + logger.setLevel(logging.NOTSET) + return logger + + +def test_logger_initialization(): + _reset_logger() + try: + init_logger() + assert True # If no exception is raised, the test passes + except Exception as e: + assert False, f"Logger initialization failed with exception: {e}" + +def test_default_configuration(monkeypatch): + _reset_logger() + monkeypatch.delenv("LOG_FILE_LOCATION", raising=False) + monkeypatch.delenv("LOG_LEVEL", raising=False) + monkeypatch.delenv("APP_DEBUG_ENABLE", raising=False) + + init_logger() + + logger = logging.getLogger("pythonQEPest") + assert logger.level == logging.INFO + file_handlers = [h for h in logger.handlers if isinstance(h, logging.FileHandler)] + assert file_handlers, "File handler should be configured" + assert file_handlers[0].baseFilename.endswith( + "\\logs\\app.log" + ), "Default LOG_FILE_LOCATION should be logs/app.log" + +def _logger_levels(monkeypatch, level: str, assert_level): + _reset_logger() + + monkeypatch.setenv("LOG_LEVEL", level) + init_logger() + + logger = logging.getLogger("pythonQEPest") + assert logger.level == assert_level + + +def test_logger_levels(monkeypatch): + """ Logger levels testing""" + _logger_levels(monkeypatch, level="DEBUG", assert_level=logging.DEBUG) + _logger_levels(monkeypatch, level="INFO", assert_level=logging.INFO) + _logger_levels(monkeypatch, level="WARNING", assert_level=logging.WARNING) + _logger_levels(monkeypatch, level="ERROR", assert_level=logging.ERROR) + _logger_levels(monkeypatch, level="", assert_level=logging.INFO) + + +def test_file_location(monkeypatch): + """ LOG_FILE_LOCATION testing""" + + # Test with custom LOG_FILE_LOCATION + _reset_logger() + monkeypatch.setenv("LOG_FILE_LOCATION", "test_logs/app.log") + + init_logger() + + logger = logging.getLogger("pythonQEPest") + file_handlers = [h for h in logger.handlers if isinstance(h, logging.FileHandler)] + + assert file_handlers, "File handler should be configured" + assert file_handlers[0].baseFilename.endswith( + "\\test_logs\\app.log" + ), "File handler should use LOG_FILE_LOCATION" + + # Test with default LOG_FILE_LOCATION + _reset_logger() + monkeypatch.delenv("LOG_FILE_LOCATION", raising=False) + + init_logger() + + logger = logging.getLogger("pythonQEPest") + file_handlers = [h for h in logger.handlers if isinstance(h, logging.FileHandler)] + + assert file_handlers, "File handler should be configured" + assert file_handlers[0].baseFilename.endswith( + "\\logs\\app.log" + ), "File handler should use LOG_FILE_LOCATION" + + +def test_debug_option(monkeypatch): + """ Debug switch testing""" + _reset_logger() + monkeypatch.setenv("APP_DEBUG_ENABLE", "false") + + init_logger() + + logger = logging.getLogger("pythonQEPest") + assert len(logger.handlers) == 0 + + _reset_logger() + monkeypatch.setenv("APP_DEBUG_ENABLE", "true") + + init_logger() + + logger = logging.getLogger("pythonQEPest") + assert len(logger.handlers) != 0 From 0987b8533485911326c649b3b12fb77c3f278036 Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 20:21:35 +0100 Subject: [PATCH 7/9] feat(packaging): __init__.py core --- pythonQEPest/core/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pythonQEPest/core/__init__.py b/pythonQEPest/core/__init__.py index e69de29..a64de0e 100644 --- a/pythonQEPest/core/__init__.py +++ b/pythonQEPest/core/__init__.py @@ -0,0 +1,7 @@ +from .qepest_meta import QEPestMeta +from .qepest import QEPest + +__all__ = [ + "QEPestMeta", + "QEPest", +] From 0d10b948e1778f458382f44f11bb2137d4e240fd Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 20:31:26 +0100 Subject: [PATCH 8/9] fix[poetry]: dependencies --- poetry.lock | 21 ++++++++++++++++++--- pyproject.toml | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 749fd67..201f9a2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. [[package]] name = "altgraph" @@ -1370,6 +1370,21 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] +[[package]] +name = "python-dotenv" +version = "1.2.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61"}, + {file = "python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -2004,9 +2019,9 @@ files = [ ] [package.extras] -cffi = ["cffi (>=1.17,<2.0) ; platform_python_implementation != \"PyPy\" and python_version < \"3.14\"", "cffi (>=2.0.0b) ; platform_python_implementation != \"PyPy\" and python_version >= \"3.14\""] +cffi = ["cffi (>=1.17,<2.0) ; platform_python_implementation != \"PyPy\" and python_version < \"3.14\"", "cffi (>=2.0.0b0) ; platform_python_implementation != \"PyPy\" and python_version >= \"3.14\""] [metadata] lock-version = "2.1" python-versions = ">=3.9,<3.13" -content-hash = "335adb004b4285685031c9d72b18b4b5376fd4284fbfbe5bf363d6db3601ef06" +content-hash = "fead3db6dcca9577ee9b0fd6a2b78acb900df406198e0d73f7c4a412290f6d92" diff --git a/pyproject.toml b/pyproject.toml index 2c66552..8623e52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,9 +7,9 @@ readme = "README.md" packages = [ { include = "pythonQEPest" } ] + [tool.poetry.dependencies] python = ">=3.9,<3.13" - pydantic = "2.12.5" python-dotenv = "^1.2.1" From bc06a1d25ec99b46ecb70ca6d46cbddac1589c00 Mon Sep 17 00:00:00 2001 From: Lina Date: Sun, 8 Feb 2026 20:43:26 +0100 Subject: [PATCH 9/9] feat[poetry]: python version upgrade --- .github/workflows/python-package.yml | 2 +- poetry.lock | 11 ++++------- pyproject.toml | 4 ++-- tests/logger/test_logging.py | 14 ++++++++------ 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 7d3a80b..a2d9da4 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 diff --git a/poetry.lock b/poetry.lock index 201f9a2..c30d171 100644 --- a/poetry.lock +++ b/poetry.lock @@ -480,7 +480,7 @@ description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["dev"] -markers = "python_version < \"3.11\"" +markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, @@ -1036,7 +1036,6 @@ cleo = ">=2.1.0,<3.0.0" dulwich = ">=0.24.0,<0.25.0" fastjsonschema = ">=2.18.0,<3.0.0" findpython = ">=0.6.2,<0.8.0" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} installer = ">=0.7.0,<0.8.0" keyring = ">=25.1.0,<26.0.0" packaging = ">=24.2" @@ -1293,7 +1292,6 @@ files = [ [package.dependencies] altgraph = "*" -importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} packaging = ">=22.0" pefile = {version = ">=2022.5.30", markers = "sys_platform == \"win32\""} @@ -1318,7 +1316,6 @@ files = [ ] [package.dependencies] -importlib_metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} packaging = ">=22.0" setuptools = ">=42.0.0" @@ -1674,7 +1671,7 @@ description = "A lil' TOML parser" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version < \"3.11\"" +markers = "python_version == \"3.10\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -2023,5 +2020,5 @@ cffi = ["cffi (>=1.17,<2.0) ; platform_python_implementation != \"PyPy\" and pyt [metadata] lock-version = "2.1" -python-versions = ">=3.9,<3.13" -content-hash = "fead3db6dcca9577ee9b0fd6a2b78acb900df406198e0d73f7c4a412290f6d92" +python-versions = ">=3.10,<3.13" +content-hash = "b5af51fdaeed8f912b48741fe67abc3f5f5d0ea4740e84d55f778abbe746e0df" diff --git a/pyproject.toml b/pyproject.toml index 8623e52..657007d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pythonQEPest" -version = "1.1.0" +version = "1.1.1" description = "" authors = ["Lina "] readme = "README.md" @@ -9,7 +9,7 @@ packages = [ ] [tool.poetry.dependencies] -python = ">=3.9,<3.13" +python = ">=3.10,<3.13" pydantic = "2.12.5" python-dotenv = "^1.2.1" diff --git a/tests/logger/test_logging.py b/tests/logger/test_logging.py index 84fa598..d397e4e 100644 --- a/tests/logger/test_logging.py +++ b/tests/logger/test_logging.py @@ -1,4 +1,6 @@ import logging +from pathlib import Path + from pythonQEPest.logger import init_logger @@ -31,8 +33,8 @@ def test_default_configuration(monkeypatch): assert logger.level == logging.INFO file_handlers = [h for h in logger.handlers if isinstance(h, logging.FileHandler)] assert file_handlers, "File handler should be configured" - assert file_handlers[0].baseFilename.endswith( - "\\logs\\app.log" + assert Path(file_handlers[0].baseFilename).as_posix().endswith( + "/logs/app.log" ), "Default LOG_FILE_LOCATION should be logs/app.log" def _logger_levels(monkeypatch, level: str, assert_level): @@ -67,8 +69,8 @@ def test_file_location(monkeypatch): file_handlers = [h for h in logger.handlers if isinstance(h, logging.FileHandler)] assert file_handlers, "File handler should be configured" - assert file_handlers[0].baseFilename.endswith( - "\\test_logs\\app.log" + assert Path(file_handlers[0].baseFilename).as_posix().endswith( + "/test_logs/app.log" ), "File handler should use LOG_FILE_LOCATION" # Test with default LOG_FILE_LOCATION @@ -81,8 +83,8 @@ def test_file_location(monkeypatch): file_handlers = [h for h in logger.handlers if isinstance(h, logging.FileHandler)] assert file_handlers, "File handler should be configured" - assert file_handlers[0].baseFilename.endswith( - "\\logs\\app.log" + assert Path(file_handlers[0].baseFilename).as_posix().endswith( + "/logs/app.log" ), "File handler should use LOG_FILE_LOCATION"