Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-python-dotenv for openSUSE:Factory checked in at 2025-04-15 16:45:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-dotenv (Old) and /work/SRC/openSUSE:Factory/.python-python-dotenv.new.1907 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-dotenv" Tue Apr 15 16:45:15 2025 rev:15 rq:1269223 version:1.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-dotenv/python-python-dotenv.changes 2024-02-09 23:52:09.578617390 +0100 +++ /work/SRC/openSUSE:Factory/.python-python-dotenv.new.1907/python-python-dotenv.changes 2025-04-15 16:48:22.701315529 +0200 @@ -1,0 +2,13 @@ +Wed Apr 9 17:26:29 UTC 2025 - Richard Rahl <rra...@opensuse.org> + +- update to 1.1.0: + * Add a security policy + * Enhance dotenv run: Switch to execvpe for better resource management and + signal handling + * Add Python 3.13 trove classifier + * Add support for python 3.13 and drop 3.8 + * docs: Update README.md + * Some more s/Python-dotenv/python-dotenv/ + * add _is_debugger so load_dotenv will work in pdb + +------------------------------------------------------------------- Old: ---- python-dotenv-1.0.1.tar.gz New: ---- python-dotenv-1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-dotenv.spec ++++++ --- /var/tmp/diff_new_pack.Lu8Drv/_old 2025-04-15 16:48:23.229337639 +0200 +++ /var/tmp/diff_new_pack.Lu8Drv/_new 2025-04-15 16:48:23.229337639 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-python-dotenv # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %define skip_python2 1 %{?sle15_python_module_pythons} Name: python-python-dotenv -Version: 1.0.1 +Version: 1.1.0 Release: 0 Summary: Python library for .env support License: BSD-3-Clause ++++++ python-dotenv-1.0.1.tar.gz -> python-dotenv-1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/.github/SECURITY.md new/python-dotenv-1.1.0/.github/SECURITY.md --- old/python-dotenv-1.0.1/.github/SECURITY.md 1970-01-01 01:00:00.000000000 +0100 +++ new/python-dotenv-1.1.0/.github/SECURITY.md 2025-03-25 11:53:46.000000000 +0100 @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| --------- | ------------------ | +| latest | :white_check_mark: | +| 0.x | :x: | + +## Reporting a Vulnerability + +If you believe you have identified a security issue with python-dotenv, please email +python-dot...@saurabh-kumar.com. A maintainer will contact you acknowledging the report +and how to continue. + +Be sure to include as much detail as necessary in your report. As with reporting normal +issues, a minimal reproducible example will help the maintainers address the issue faster. +If you are able, you may also include a fix for the issue generated with `git format-patch`. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/.github/dependabot.yml new/python-dotenv-1.1.0/.github/dependabot.yml --- old/python-dotenv-1.0.1/.github/dependabot.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-dotenv-1.1.0/.github/dependabot.yml 2025-03-25 11:53:46.000000000 +0100 @@ -0,0 +1,13 @@ +# Keep GitHub Actions up to date with GitHub's Dependabot... +# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + groups: + github-actions: + patterns: + - "*" # Group all Actions updates into a single larger pull request + schedule: + interval: weekly diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/.github/workflows/release.yml new/python-dotenv-1.1.0/.github/workflows/release.yml --- old/python-dotenv-1.0.1/.github/workflows/release.yml 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/.github/workflows/release.yml 2025-03-25 11:53:46.000000000 +0100 @@ -8,9 +8,9 @@ deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/.github/workflows/test.yml new/python-dotenv-1.1.0/.github/workflows/test.yml --- old/python-dotenv-1.0.1/.github/workflows/test.yml 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/.github/workflows/test.yml 2025-03-25 11:53:46.000000000 +0100 @@ -7,24 +7,28 @@ runs-on: ${{ matrix.os }} strategy: + fail-fast: false max-parallel: 8 matrix: os: - ubuntu-latest - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", pypy3.9, pypy3.10] + python-version: + ["3.9", "3.10", "3.11", "3.12", "3.13", pypy3.9, pypy3.10] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - name: Install dependencies - run: - python -m pip install --upgrade pip - pip install tox tox-gh-actions + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + allow-prereleases: true - - name: Test with tox - run: tox + - name: Upgrade pip + run: python -m pip install --upgrade pip + + - name: Install dependencies + run: pip install tox tox-gh-actions + + - name: Test with tox + run: tox diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/CHANGELOG.md new/python-dotenv-1.1.0/CHANGELOG.md --- old/python-dotenv-1.0.1/CHANGELOG.md 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/CHANGELOG.md 2025-03-25 11:53:46.000000000 +0100 @@ -5,12 +5,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.1.0] - 2025-03-25 + +**Feature** +- Add support for python 3.13 +- Enhance `dotenv run`, switch to `execvpe` for better resource management and signal handling ([#523]) by [@eekstunt] + +**Fixed** +- `find_dotenv` and `load_dotenv` now correctly looks up at the current directory when running in debugger or pdb ([#553] by [@randomseed42]) + +**Misc** +- Drop support for Python 3.8 + ## [1.0.1] - 2024-01-23 **Fixed** * Gracefully handle code which has been imported from a zipfile ([#456] by [@samwyma]) -* Allow modules using load_dotenv to be reloaded when launched in a separate thread ([#497] by [@freddyaboulton]) +* Allow modules using `load_dotenv` to be reloaded when launched in a separate thread ([#497] by [@freddyaboulton]) * Fix file not closed after deletion, handle error in the rewrite function ([#469] by [@Qwerty-133]) **Misc** @@ -317,7 +330,7 @@ ## 0.5.1 -- Fix find\_dotenv - it now start search from the file where this +- Fix `find_dotenv` - it now start search from the file where this function is called from. ## 0.5.0 @@ -346,6 +359,8 @@ [#466]: https://github.com/theskumar/python-dotenv/issues/466 [#454]: https://github.com/theskumar/python-dotenv/issues/454 [#474]: https://github.com/theskumar/python-dotenv/issues/474 +[#523]: https://github.com/theskumar/python-dotenv/issues/523 +[#553]: https://github.com/theskumar/python-dotenv/issues/553 [@alanjds]: https://github.com/alanjds [@altendky]: https://github.com/altendky @@ -356,6 +371,7 @@ [@cjauvin]: https://github.com/cjauvin [@eaf]: https://github.com/eaf [@earlbread]: https://github.com/earlbread +[@eekstunt]: https://github.com/eekstunt [@eggplants]: https://github.com/@eggplants [@ekohl]: https://github.com/ekohl [@elbehery95]: https://github.com/elbehery95 @@ -389,7 +405,7 @@ [@x-yuri]: https://github.com/x-yuri [@yannham]: https://github.com/yannham [@zueve]: https://github.com/zueve - +[@randomseed42]: https://github.com/zueve [Unreleased]: https://github.com/theskumar/python-dotenv/compare/v1.0.1...HEAD [1.0.1]: https://github.com/theskumar/python-dotenv/compare/v1.0.0...v1.0.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/README.md new/python-dotenv-1.1.0/README.md --- old/python-dotenv-1.0.1/README.md 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/README.md 2025-03-25 11:53:46.000000000 +0100 @@ -3,7 +3,7 @@ [![Build Status][build_status_badge]][build_status_link] [![PyPI version][pypi_badge]][pypi_link] -Python-dotenv reads key-value pairs from a `.env` file and can set them as environment +python-dotenv reads key-value pairs from a `.env` file and can set them as environment variables. It helps in the development of applications following the [12-factor](https://12factor.net/) principles. @@ -29,20 +29,20 @@ application, launching it in development is not very practical because you have to set those environment variables yourself. -To help you with that, you can add Python-dotenv to your application to make it load the +To help you with that, you can add python-dotenv to your application to make it load the configuration from a `.env` file when it is present (e.g. in development) while remaining configurable via the environment: ```python from dotenv import load_dotenv -load_dotenv() # take environment variables from .env. +load_dotenv() # take environment variables # Code of your application, which uses environment variables (e.g. from `os.environ` or # `os.getenv`) as if they came from the actual environment. ``` -By default, `load_dotenv` doesn't override existing environment variables. +By default, `load_dotenv` doesn't override existing environment variables and looks for a `.env` file in same directory as python script or searches for it incrementally higher up. To configure the development environment, add a `.env` in the root directory of your project: @@ -201,7 +201,7 @@ ### Variable expansion -Python-dotenv can interpolate variables using POSIX variable expansion. +python-dotenv can interpolate variables using POSIX variable expansion. With `load_dotenv(override=True)` or `dotenv_values()`, the value of a variable is the first of the values defined in the following list: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/mkdocs.yml new/python-dotenv-1.1.0/mkdocs.yml --- old/python-dotenv-1.0.1/mkdocs.yml 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/mkdocs.yml 2025-03-25 11:53:46.000000000 +0100 @@ -13,13 +13,7 @@ - mdx_truly_sane_lists plugins: - - mkdocstrings: - handlers: - python: - rendering: - show_root_heading: yes - show_submodules: no - separate_signature: yes + - mkdocstrings - search nav: - Home: index.md diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/setup.cfg new/python-dotenv-1.1.0/setup.cfg --- old/python-dotenv-1.0.1/setup.cfg 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/setup.cfg 2025-03-25 11:53:46.000000000 +0100 @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.0.0 +current_version = 1.1.0 commit = True tag = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/setup.py new/python-dotenv-1.1.0/setup.py --- old/python-dotenv-1.0.1/setup.py 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/setup.py 2025-03-25 11:53:46.000000000 +0100 @@ -4,59 +4,68 @@ def read_files(files): data = [] for file in files: - with open(file, encoding='utf-8') as f: + with open(file, encoding="utf-8") as f: data.append(f.read()) return "\n".join(data) -long_description = read_files(['README.md', 'CHANGELOG.md']) +long_description = read_files(["README.md", "CHANGELOG.md"]) meta = {} -with open('./src/dotenv/version.py', encoding='utf-8') as f: +with open("./src/dotenv/version.py", encoding="utf-8") as f: exec(f.read(), meta) setup( name="python-dotenv", description="Read key-value pairs from a .env file and set them as environment variables", long_description=long_description, - long_description_content_type='text/markdown', - version=meta['__version__'], + long_description_content_type="text/markdown", + version=meta["__version__"], author="Saurabh Kumar", author_email="me+git...@saurabh-kumar.com", url="https://github.com/theskumar/python-dotenv", - keywords=['environment variables', 'deployments', 'settings', 'env', 'dotenv', - 'configurations', 'python'], - packages=['dotenv'], - package_dir={'': 'src'}, + keywords=[ + "environment variables", + "deployments", + "settings", + "env", + "dotenv", + "configurations", + "python", + ], + packages=["dotenv"], + package_dir={"": "src"}, package_data={ - 'dotenv': ['py.typed'], + "dotenv": ["py.typed"], }, - python_requires=">=3.8", + python_requires=">=3.9", extras_require={ - 'cli': ['click>=5.0', ], + "cli": [ + "click>=5.0", + ], }, entry_points={ "console_scripts": [ "dotenv=dotenv.__main__:cli", ], }, - license='BSD-3-Clause', + license="BSD-3-Clause", classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: Implementation :: PyPy', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Topic :: System :: Systems Administration', - 'Topic :: Utilities', - 'Environment :: Web Environment', - ] + "Development Status :: 5 - Production/Stable", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Implementation :: PyPy", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Topic :: System :: Systems Administration", + "Topic :: Utilities", + "Environment :: Web Environment", + ], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/src/dotenv/cli.py new/python-dotenv-1.1.0/src/dotenv/cli.py --- old/python-dotenv-1.0.1/src/dotenv/cli.py 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/src/dotenv/cli.py 2025-03-25 11:53:46.000000000 +0100 @@ -3,8 +3,7 @@ import shlex import sys from contextlib import contextmanager -from subprocess import Popen -from typing import Any, Dict, IO, Iterator, List +from typing import Any, Dict, IO, Iterator, List, Optional try: import click @@ -17,7 +16,7 @@ from .version import __version__ -def enumerate_env(): +def enumerate_env() -> Optional[str]: """ Return a path for the ${pwd}/.env file. @@ -161,14 +160,13 @@ if not commandline: click.echo('No command given.') exit(1) - ret = run_command(commandline, dotenv_as_dict) - exit(ret) + run_command(commandline, dotenv_as_dict) -def run_command(command: List[str], env: Dict[str, str]) -> int: - """Run command in sub process. +def run_command(command: List[str], env: Dict[str, str]) -> None: + """Replace the current process with the specified command. - Runs the command in a sub process with the variables from `env` + Replaces the current process with the specified command and the variables from `env` added in the current environment variables. Parameters @@ -180,8 +178,8 @@ Returns ------- - int - The return code of the command + None + This function does not return any value. It replaces the current process with the new one. """ # copy the current environment variables and add the vales from @@ -189,11 +187,4 @@ cmd_env = os.environ.copy() cmd_env.update(env) - p = Popen(command, - universal_newlines=True, - bufsize=0, - shell=False, - env=cmd_env) - _, _ = p.communicate() - - return p.returncode + os.execvpe(command[0], args=command, env=cmd_env) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/src/dotenv/main.py new/python-dotenv-1.1.0/src/dotenv/main.py --- old/python-dotenv-1.0.1/src/dotenv/main.py 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/src/dotenv/main.py 2025-03-25 11:53:46.000000000 +0100 @@ -7,8 +7,7 @@ import tempfile from collections import OrderedDict from contextlib import contextmanager -from typing import (IO, Dict, Iterable, Iterator, Mapping, Optional, Tuple, - Union) +from typing import IO, Dict, Iterable, Iterator, Mapping, Optional, Tuple, Union from .parser import Binding, parse_stream from .variables import parse_variables @@ -17,7 +16,7 @@ # These paths may flow to `open()` and `shutil.move()`; `shutil.move()` # only accepts string paths, not byte paths or file descriptors. See # https://github.com/python/typeshed/pull/6832. -StrPath = Union[str, 'os.PathLike[str]'] +StrPath = Union[str, "os.PathLike[str]"] logger = logging.getLogger(__name__) @@ -26,7 +25,7 @@ for mapping in mappings: if mapping.error: logger.warning( - "Python-dotenv could not parse statement starting at line %s", + "python-dotenv could not parse statement starting at line %s", mapping.original.line, ) yield mapping @@ -60,10 +59,10 @@ else: if self.verbose: logger.info( - "Python-dotenv could not find configuration file %s.", - self.dotenv_path or '.env', + "python-dotenv could not find configuration file %s.", + self.dotenv_path or ".env", ) - yield io.StringIO('') + yield io.StringIO("") def dict(self) -> Dict[str, Optional[str]]: """Return dotenv as dict""" @@ -73,7 +72,9 @@ raw_values = self.parse() if self.interpolate: - self._dict = OrderedDict(resolve_variables(raw_values, override=self.override)) + self._dict = OrderedDict( + resolve_variables(raw_values, override=self.override) + ) else: self._dict = OrderedDict(raw_values) @@ -101,8 +102,7 @@ return True def get(self, key: str) -> Optional[str]: - """ - """ + """ """ data = self.dict() if key in data: @@ -166,9 +166,8 @@ if quote_mode not in ("always", "auto", "never"): raise ValueError(f"Unknown quote_mode: {quote_mode}") - quote = ( - quote_mode == "always" - or (quote_mode == "auto" and not value_to_set.isalnum()) + quote = quote_mode == "always" or ( + quote_mode == "auto" and not value_to_set.isalnum() ) if quote: @@ -176,7 +175,7 @@ else: value_out = value_to_set if export: - line_out = f'export {key_to_set}={value_out}\n' + line_out = f"export {key_to_set}={value_out}\n" else: line_out = f"{key_to_set}={value_out}\n" @@ -223,7 +222,9 @@ dest.write(mapping.original.string) if not removed: - logger.warning("Key %s not removed from %s - key doesn't exist.", key_to_unset, dotenv_path) + logger.warning( + "Key %s not removed from %s - key doesn't exist.", key_to_unset, dotenv_path + ) return None, key_to_unset return removed, key_to_unset @@ -235,7 +236,7 @@ ) -> Mapping[str, Optional[str]]: new_values: Dict[str, Optional[str]] = {} - for (name, value) in values: + for name, value in values: if value is None: result = None else: @@ -259,7 +260,7 @@ Yield directories starting from the given directory up to the root """ if not os.path.exists(path): - raise IOError('Starting path not found') + raise IOError("Starting path not found") if os.path.isfile(path): path = os.path.dirname(path) @@ -273,7 +274,7 @@ def find_dotenv( - filename: str = '.env', + filename: str = ".env", raise_error_if_not_found: bool = False, usecwd: bool = False, ) -> str: @@ -284,14 +285,17 @@ """ def _is_interactive(): - """ Decide whether this is running in a REPL or IPython notebook """ + """Decide whether this is running in a REPL or IPython notebook""" try: - main = __import__('__main__', None, None, fromlist=['__file__']) + main = __import__("__main__", None, None, fromlist=["__file__"]) except ModuleNotFoundError: return False - return not hasattr(main, '__file__') + return not hasattr(main, "__file__") + + def _is_debugger(): + return sys.gettrace() is not None - if usecwd or _is_interactive() or getattr(sys, 'frozen', False): + if usecwd or _is_interactive() or _is_debugger() or getattr(sys, "frozen", False): # Should work without __file__, e.g. in REPL or IPython notebook. path = os.getcwd() else: @@ -313,9 +317,9 @@ return check_path if raise_error_if_not_found: - raise IOError('File not found') + raise IOError("File not found") - return '' + return "" def load_dotenv( @@ -340,7 +344,9 @@ Bool: True if at least one environment variable is set else False If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the - .env file. + .env file with it's default parameters. If you need to change the default parameters + of `find_dotenv()`, you can explicitly call `find_dotenv()` and pass the result + to this function as `dotenv_path`. """ if dotenv_path is None and stream is None: dotenv_path = find_dotenv() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/src/dotenv/version.py new/python-dotenv-1.1.0/src/dotenv/version.py --- old/python-dotenv-1.0.1/src/dotenv/version.py 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/src/dotenv/version.py 2025-03-25 11:53:46.000000000 +0100 @@ -1 +1 @@ -__version__ = "1.0.1" +__version__ = "1.1.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/tests/test_main.py new/python-dotenv-1.1.0/tests/test_main.py --- old/python-dotenv-1.0.1/tests/test_main.py 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/tests/test_main.py 2025-03-25 11:53:46.000000000 +0100 @@ -28,9 +28,9 @@ ("", "a", "", (True, "a", ""), "a=''\n"), ("", "a", "b", (True, "a", "b"), "a='b'\n"), ("", "a", "'b'", (True, "a", "'b'"), "a='\\'b\\''\n"), - ("", "a", "\"b\"", (True, "a", '"b"'), "a='\"b\"'\n"), + ("", "a", '"b"', (True, "a", '"b"'), "a='\"b\"'\n"), ("", "a", "b'c", (True, "a", "b'c"), "a='b\\'c'\n"), - ("", "a", "b\"c", (True, "a", "b\"c"), "a='b\"c'\n"), + ("", "a", 'b"c', (True, "a", 'b"c'), "a='b\"c'\n"), ("a=b", "a", "c", (True, "a", "c"), "a='c'\n"), ("a=b\n", "a", "c", (True, "a", "c"), "a='c'\n"), ("a=b\n\n", "a", "c", (True, "a", "c"), "a='c'\n\n"), @@ -75,20 +75,20 @@ nx_path = tmp_path / "nx" logger = logging.getLogger("dotenv.main") - with mock.patch.object(logger, "info") as mock_info, \ - mock.patch.object(logger, "warning") as mock_warning: + with ( + mock.patch.object(logger, "info") as mock_info, + mock.patch.object(logger, "warning") as mock_warning, + ): result = dotenv.get_key(nx_path, "foo") assert result is None mock_info.assert_has_calls( calls=[ - mock.call("Python-dotenv could not find configuration file %s.", nx_path) + mock.call("python-dotenv could not find configuration file %s.", nx_path) ], ) mock_warning.assert_has_calls( - calls=[ - mock.call("Key %s not found in %s.", "foo", nx_path) - ], + calls=[mock.call("Key %s not found in %s.", "foo", nx_path)], ) @@ -249,10 +249,12 @@ logger = logging.getLogger("dotenv.main") with mock.patch.object(logger, "info") as mock_info: - result = dotenv.load_dotenv('.does_not_exist', verbose=True) + result = dotenv.load_dotenv(".does_not_exist", verbose=True) assert result is False - mock_info.assert_called_once_with("Python-dotenv could not find configuration file %s.", ".does_not_exist") + mock_info.assert_called_once_with( + "python-dotenv could not find configuration file %s.", ".does_not_exist" + ) @mock.patch.dict(os.environ, {"a": "c"}, clear=True) @@ -317,21 +319,23 @@ def test_load_dotenv_in_current_dir(tmp_path): - dotenv_path = tmp_path / '.env' - dotenv_path.write_bytes(b'a=b') - code_path = tmp_path / 'code.py' - code_path.write_text(textwrap.dedent(""" + dotenv_path = tmp_path / ".env" + dotenv_path.write_bytes(b"a=b") + code_path = tmp_path / "code.py" + code_path.write_text( + textwrap.dedent(""" import dotenv import os dotenv.load_dotenv(verbose=True) print(os.environ['a']) - """)) + """) + ) os.chdir(tmp_path) result = sh.Command(sys.executable)(code_path) - assert result == 'b\n' + assert result == "b\n" def test_dotenv_values_file(dotenv_path): @@ -352,30 +356,23 @@ ({"b": "c"}, "a=${b}", True, {"a": "c"}), ({"b": "c"}, "a=${b:-d}", False, {"a": "${b:-d}"}), ({"b": "c"}, "a=${b:-d}", True, {"a": "c"}), - # Defined in file ({}, "b=c\na=${b}", True, {"a": "c", "b": "c"}), - # Undefined ({}, "a=${b}", True, {"a": ""}), ({}, "a=${b:-d}", True, {"a": "d"}), - # With quotes ({"b": "c"}, 'a="${b}"', True, {"a": "c"}), ({"b": "c"}, "a='${b}'", True, {"a": "c"}), - # With surrounding text ({"b": "c"}, "a=x${b}y", True, {"a": "xcy"}), - # Self-referential ({"a": "b"}, "a=${a}", True, {"a": "b"}), ({}, "a=${a}", True, {"a": ""}), ({"a": "b"}, "a=${a:-c}", True, {"a": "b"}), ({}, "a=${a:-c}", True, {"a": "c"}), - # Reused ({"b": "c"}, "a=${b}${b}", True, {"a": "cc"}), - # Re-defined and used in file ({"b": "c"}, "b=d\na=${b}", True, {"a": "d", "b": "d"}), ({}, "a=b\na=c\nd=${a}", True, {"a": "c", "d": "c"}), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-dotenv-1.0.1/tox.ini new/python-dotenv-1.1.0/tox.ini --- old/python-dotenv-1.0.1/tox.ini 2024-01-23 07:30:54.000000000 +0100 +++ new/python-dotenv-1.1.0/tox.ini 2025-03-25 11:53:46.000000000 +0100 @@ -1,39 +1,39 @@ [tox] -envlist = lint,py{38,39,310,311,312-dev},pypy3,manifest,coverage-report +envlist = lint,py{39,310,311,312,313},pypy3,manifest,coverage-report [gh-actions] python = - 3.8: py38 3.9: py39 3.10: py310 - 3.11: py311, lint, manifest - 3.12-dev: py312-dev + 3.11: py311 + 3.12: py312 + 3.13: py313, lint, manifest pypy-3.9: pypy3 [testenv] deps = - pytest - pytest-cov - sh >= 2.0.2, <3 - click - py{38,39,310,311,py312-dev,pypy3}: ipython + pytest + pytest-cov + sh >= 2.0.2, <3 + click + py{39,310,311,312,313,pypy3}: ipython commands = pytest --cov --cov-report=term-missing --cov-config setup.cfg {posargs} depends = - py{38,39,310,311,312-dev},pypy3: coverage-clean - coverage-report: py{38,39,310,311,312-dev},pypy3 + py{39,310,311,312,313},pypy3: coverage-clean + coverage-report: py{39,310,311,312,313},pypy3 [testenv:lint] skip_install = true deps = - flake8 - mypy + flake8 + mypy commands = - flake8 src tests - mypy --python-version=3.12 src tests - mypy --python-version=3.11 src tests - mypy --python-version=3.10 src tests - mypy --python-version=3.9 src tests - mypy --python-version=3.8 src tests + flake8 src tests + mypy --python-version=3.13 src tests + mypy --python-version=3.12 src tests + mypy --python-version=3.11 src tests + mypy --python-version=3.10 src tests + mypy --python-version=3.9 src tests [testenv:manifest] deps = check-manifest @@ -49,4 +49,4 @@ deps = coverage skip_install = true commands = - coverage report + coverage report