diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bdb051c09..a19aaf170 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,7 +27,7 @@ repos: hooks: - id: black args: [--line-length=79] - - repo: https://gitlab.com/pycqa/flake8 + - repo: https://github.com/pycqa/flake8 rev: 3.9.2 hooks: - id: flake8 diff --git a/dynaconf/cli.py b/dynaconf/cli.py index 1490f3787..8b8ab5d53 100644 --- a/dynaconf/cli.py +++ b/dynaconf/cli.py @@ -29,7 +29,11 @@ os.environ["PYTHONIOENCODING"] = "utf-8" -CWD = Path.cwd() +CWD = None +try: + CWD = Path.cwd() +except FileNotFoundError: + pass EXTS = ["ini", "toml", "yaml", "json", "py", "env"] WRITERS = ["ini", "toml", "yaml", "json", "py", "redis", "vault", "env"] @@ -116,6 +120,8 @@ def import_settings(dotted_path): module = importlib.import_module(module) except ImportError as e: raise click.UsageError(e) + except FileNotFoundError: + return try: return getattr(module, name) except AttributeError as e: diff --git a/dynaconf/loaders/env_loader.py b/dynaconf/loaders/env_loader.py index 04050e4a5..779e9a4f6 100644 --- a/dynaconf/loaders/env_loader.py +++ b/dynaconf/loaders/env_loader.py @@ -5,7 +5,16 @@ from dynaconf.utils import missing from dynaconf.utils import upperfy from dynaconf.utils.parse_conf import parse_conf_data -from dynaconf.vendor.dotenv import cli as dotenv_cli + +DOTENV_IMPORTED = False +try: + from dynaconf.vendor.dotenv import cli as dotenv_cli + + DOTENV_IMPORTED = True +except ImportError: + pass +except FileNotFoundError: + pass IDENTIFIER = "env" @@ -84,6 +93,8 @@ def load_from_env( def write(settings_path, settings_data, **kwargs): """Write data to .env file""" + if not DOTENV_IMPORTED: + return for key, value in settings_data.items(): quote_mode = ( isinstance(value, str) diff --git a/dynaconf/utils/files.py b/dynaconf/utils/files.py index 135880ac9..ec6fbd851 100644 --- a/dynaconf/utils/files.py +++ b/dynaconf/utils/files.py @@ -47,7 +47,10 @@ def find_file(filename=".env", project_root=None, skip_files=None, **kwargs): additional `./config` folder. """ search_tree = [] - work_dir = os.getcwd() + try: + work_dir = os.getcwd() + except FileNotFoundError: + return "" skip_files = skip_files or [] # If filename is an absolute path and exists, just return it diff --git a/tests_functional/missing_pwd/test.sh b/tests_functional/missing_pwd/test.sh new file mode 100755 index 000000000..457d1da71 --- /dev/null +++ b/tests_functional/missing_pwd/test.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +rm -rf /tmp/foobar +mkdir -p /tmp/foobar +cd /tmp/foobar +rm -rf /tmp/foobar + +dynaconf -i config.settings list +RC=$? +exit $RC diff --git a/tests_functional/runtests.py b/tests_functional/runtests.py index 29449cfc0..9b22da802 100755 --- a/tests_functional/runtests.py +++ b/tests_functional/runtests.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from __future__ import annotations +import argparse import os import subprocess import sys @@ -65,22 +66,34 @@ def execute_tests(path): return False -def run_tests(): +def run_tests(show_list=False, test_filter=None): + def filter_allowed(testpath): + if not test_filter: + return True + for keyword in test_filter: + if keyword in testpath.name: + return True + return False + passed = 0 root_directory = Path(__file__).parent print("Workdir:", root_directory.absolute()) functional_tests = sorted(list(root_directory.iterdir())) print("Collected functional tests:", len(functional_tests)) sleep(1) + for path in functional_tests: if path.is_dir(): if path.name in [".", "__pycache__"]: continue - if execute_tests(path): - passed += 1 - print(f"Passed {path}") - continue + if show_list: + print(path) + else: + if filter_allowed(path) and execute_tests(path): + passed += 1 + print(f"Passed {path}") + continue # Now Subdirectories one level subdirs = sorted(list(path.iterdir())) @@ -89,10 +102,13 @@ def run_tests(): if subdir.name in [".", "__pycache__"]: continue - if execute_tests(subdir): - passed += 1 - print(f"Passed {subdir}") - continue + if show_list: + print(subdir) + else: + if filter_allowed(subdir) and execute_tests(subdir): + passed += 1 + print(f"Passed {subdir}") + continue if not subdirs: exit( @@ -100,10 +116,25 @@ def run_tests(): "Makefile, test.sh, app.py, test.py, program.py" ) - print("-" * 40) - print(f"{passed} functional tests passed") - print("-" * 40) + if not show_list: + print("-" * 40) + print(f"{passed} functional tests passed") + print("-" * 40) if __name__ == "__main__": - run_tests() + parser = argparse.ArgumentParser() + parser.add_argument( + "--list", + dest="show_list", + action="store_true", + help="List all available tests (do not execute)", + ) + parser.add_argument( + "--filter", + dest="test_filter", + action="append", + help="limt tests to those that contain a substring", + ) + args = parser.parse_args() + run_tests(show_list=args.show_list, test_filter=args.test_filter) diff --git a/tests_functional/skipfile.toml b/tests_functional/skipfile.toml index 113a76a2b..ca55430aa 100644 --- a/tests_functional/skipfile.toml +++ b/tests_functional/skipfile.toml @@ -18,4 +18,5 @@ nt = [ "449_django_lazy_path", "685_disable_dotted_lookup", "741_envvars_ignored", + "missing_pwd", ]