plain 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,113 +0,0 @@
1
- """
2
- Sets up the terminal color scheme.
3
- """
4
-
5
- import functools
6
- import os
7
- import sys
8
-
9
- from plain.utils import termcolors
10
-
11
- try:
12
- import colorama
13
-
14
- colorama.init()
15
- except (ImportError, OSError):
16
- HAS_COLORAMA = False
17
- else:
18
- HAS_COLORAMA = True
19
-
20
-
21
- def supports_color():
22
- """
23
- Return True if the running system's terminal supports color,
24
- and False otherwise.
25
- """
26
-
27
- def vt_codes_enabled_in_windows_registry():
28
- """
29
- Check the Windows Registry to see if VT code handling has been enabled
30
- by default, see https://superuser.com/a/1300251/447564.
31
- """
32
- try:
33
- # winreg is only available on Windows.
34
- import winreg
35
- except ImportError:
36
- return False
37
- else:
38
- try:
39
- reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, "Console")
40
- reg_key_value, _ = winreg.QueryValueEx(reg_key, "VirtualTerminalLevel")
41
- except FileNotFoundError:
42
- return False
43
- else:
44
- return reg_key_value == 1
45
-
46
- # isatty is not always implemented, #6223.
47
- is_a_tty = hasattr(sys.stdout, "isatty") and sys.stdout.isatty()
48
-
49
- return is_a_tty and (
50
- sys.platform != "win32"
51
- or HAS_COLORAMA
52
- or "ANSICON" in os.environ
53
- or
54
- # Windows Terminal supports VT codes.
55
- "WT_SESSION" in os.environ
56
- or
57
- # Microsoft Visual Studio Code's built-in terminal supports colors.
58
- os.environ.get("TERM_PROGRAM") == "vscode"
59
- or vt_codes_enabled_in_windows_registry()
60
- )
61
-
62
-
63
- class Style:
64
- pass
65
-
66
-
67
- def make_style(config_string=""):
68
- """
69
- Create a Style object from the given config_string.
70
-
71
- If config_string is empty plain.utils.termcolors.DEFAULT_PALETTE is used.
72
- """
73
-
74
- style = Style()
75
-
76
- color_settings = termcolors.parse_color_setting(config_string)
77
-
78
- # The nocolor palette has all available roles.
79
- # Use that palette as the basis for populating
80
- # the palette as defined in the environment.
81
- for role in termcolors.PALETTES[termcolors.NOCOLOR_PALETTE]:
82
- if color_settings:
83
- format = color_settings.get(role, {})
84
- style_func = termcolors.make_style(**format)
85
- else:
86
-
87
- def style_func(x):
88
- return x
89
-
90
- setattr(style, role, style_func)
91
-
92
- # For backwards compatibility,
93
- # set style for ERROR_OUTPUT == ERROR
94
- style.ERROR_OUTPUT = style.ERROR
95
-
96
- return style
97
-
98
-
99
- @functools.cache
100
- def no_style():
101
- """
102
- Return a Style object with no color scheme.
103
- """
104
- return make_style("nocolor")
105
-
106
-
107
- def color_style(force_color=False):
108
- """
109
- Return a Style object from the Plain color scheme.
110
- """
111
- if not force_color and not supports_color():
112
- return no_style()
113
- return make_style(os.environ.get("DJANGO_COLORS", ""))
@@ -1,67 +0,0 @@
1
- import sys
2
-
3
- from plain.packages import packages
4
-
5
-
6
- def sql_flush(style, connection, reset_sequences=True, allow_cascade=False):
7
- """
8
- Return a list of the SQL statements used to flush the database.
9
- """
10
- tables = connection.introspection.plain_table_names(
11
- only_existing=True, include_views=False
12
- )
13
- return connection.ops.sql_flush(
14
- style,
15
- tables,
16
- reset_sequences=reset_sequences,
17
- allow_cascade=allow_cascade,
18
- )
19
-
20
-
21
- def emit_pre_migrate_signal(verbosity, interactive, db, **kwargs):
22
- # Emit the pre_migrate signal for every application.
23
- for package_config in packages.get_package_configs():
24
- if package_config.models_module is None:
25
- continue
26
- if verbosity >= 2:
27
- stdout = kwargs.get("stdout", sys.stdout)
28
- stdout.write(
29
- "Running pre-migrate handlers for application %s" % package_config.label
30
- )
31
- try:
32
- from plain import models
33
- except ImportError:
34
- continue
35
- models.signals.pre_migrate.send(
36
- sender=package_config,
37
- package_config=package_config,
38
- verbosity=verbosity,
39
- interactive=interactive,
40
- using=db,
41
- **kwargs,
42
- )
43
-
44
-
45
- def emit_post_migrate_signal(verbosity, interactive, db, **kwargs):
46
- # Emit the post_migrate signal for every application.
47
- for package_config in packages.get_package_configs():
48
- if package_config.models_module is None:
49
- continue
50
- if verbosity >= 2:
51
- stdout = kwargs.get("stdout", sys.stdout)
52
- stdout.write(
53
- "Running post-migrate handlers for application %s"
54
- % package_config.label
55
- )
56
- try:
57
- from plain import models
58
- except ImportError:
59
- continue
60
- models.signals.post_migrate.send(
61
- sender=package_config,
62
- package_config=package_config,
63
- verbosity=verbosity,
64
- interactive=interactive,
65
- using=db,
66
- **kwargs,
67
- )
@@ -1,175 +0,0 @@
1
- import fnmatch
2
- import os
3
- import shutil
4
- import subprocess
5
- from pathlib import Path
6
- from subprocess import run
7
-
8
- from plain.packages import packages as installed_packages
9
- from plain.utils.crypto import get_random_string
10
- from plain.utils.encoding import DEFAULT_LOCALE_ENCODING
11
-
12
- from .base import CommandError, CommandParser
13
-
14
-
15
- def popen_wrapper(args, stdout_encoding="utf-8"):
16
- """
17
- Friendly wrapper around Popen.
18
-
19
- Return stdout output, stderr output, and OS status code.
20
- """
21
- try:
22
- p = run(args, capture_output=True, close_fds=os.name != "nt")
23
- except OSError as err:
24
- raise CommandError("Error executing %s" % args[0]) from err
25
- return (
26
- p.stdout.decode(stdout_encoding),
27
- p.stderr.decode(DEFAULT_LOCALE_ENCODING, errors="replace"),
28
- p.returncode,
29
- )
30
-
31
-
32
- def handle_extensions(extensions):
33
- """
34
- Organize multiple extensions that are separated with commas or passed by
35
- using --extension/-e multiple times.
36
-
37
- For example: running 'django-admin makemessages -e js,txt -e xhtml -a'
38
- would result in an extension list: ['.js', '.txt', '.xhtml']
39
-
40
- >>> handle_extensions(['.html', 'html,js,py,py,py,.py', 'py,.py'])
41
- {'.html', '.js', '.py'}
42
- >>> handle_extensions(['.html, txt,.tpl'])
43
- {'.html', '.tpl', '.txt'}
44
- """
45
- ext_list = []
46
- for ext in extensions:
47
- ext_list.extend(ext.replace(" ", "").split(","))
48
- for i, ext in enumerate(ext_list):
49
- if not ext.startswith("."):
50
- ext_list[i] = ".%s" % ext_list[i]
51
- return set(ext_list)
52
-
53
-
54
- def find_command(cmd, path=None, pathext=None):
55
- if path is None:
56
- path = os.environ.get("PATH", "").split(os.pathsep)
57
- if isinstance(path, str):
58
- path = [path]
59
- # check if there are funny path extensions for executables, e.g. Windows
60
- if pathext is None:
61
- pathext = os.environ.get("PATHEXT", ".COM;.EXE;.BAT;.CMD").split(os.pathsep)
62
- # don't use extensions if the command ends with one of them
63
- for ext in pathext:
64
- if cmd.endswith(ext):
65
- pathext = [""]
66
- break
67
- # check if we find the command on PATH
68
- for p in path:
69
- f = os.path.join(p, cmd)
70
- if os.path.isfile(f):
71
- return f
72
- for ext in pathext:
73
- fext = f + ext
74
- if os.path.isfile(fext):
75
- return fext
76
- return None
77
-
78
-
79
- def get_random_secret_key():
80
- """
81
- Return a 50 character random string usable as a SECRET_KEY setting value.
82
- """
83
- chars = "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)"
84
- return get_random_string(50, chars)
85
-
86
-
87
- def parse_packages_and_model_labels(labels):
88
- """
89
- Parse a list of "package_label.ModelName" or "package_label" strings into actual
90
- objects and return a two-element tuple:
91
- (set of model classes, set of package_configs).
92
- Raise a CommandError if some specified models or packages don't exist.
93
- """
94
- packages = set()
95
- models = set()
96
-
97
- for label in labels:
98
- if "." in label:
99
- try:
100
- model = installed_packages.get_model(label)
101
- except LookupError:
102
- raise CommandError("Unknown model: %s" % label)
103
- models.add(model)
104
- else:
105
- try:
106
- package_config = installed_packages.get_package_config(label)
107
- except LookupError as e:
108
- raise CommandError(str(e))
109
- packages.add(package_config)
110
-
111
- return models, packages
112
-
113
-
114
- def get_command_line_option(argv, option):
115
- """
116
- Return the value of a command line option (which should include leading
117
- dashes, e.g. '--testrunner') from an argument list. Return None if the
118
- option wasn't passed or if the argument list couldn't be parsed.
119
- """
120
- parser = CommandParser(add_help=False, allow_abbrev=False)
121
- parser.add_argument(option, dest="value")
122
- try:
123
- options, _ = parser.parse_known_args(argv[2:])
124
- except CommandError:
125
- return None
126
- else:
127
- return options.value
128
-
129
-
130
- def normalize_path_patterns(patterns):
131
- """Normalize an iterable of glob style patterns based on OS."""
132
- patterns = [os.path.normcase(p) for p in patterns]
133
- dir_suffixes = {"%s*" % path_sep for path_sep in {"/", os.sep}}
134
- norm_patterns = []
135
- for pattern in patterns:
136
- for dir_suffix in dir_suffixes:
137
- if pattern.endswith(dir_suffix):
138
- norm_patterns.append(pattern.removesuffix(dir_suffix))
139
- break
140
- else:
141
- norm_patterns.append(pattern)
142
- return norm_patterns
143
-
144
-
145
- def is_ignored_path(path, ignore_patterns):
146
- """
147
- Check if the given path should be ignored or not based on matching
148
- one of the glob style `ignore_patterns`.
149
- """
150
- path = Path(path)
151
-
152
- def ignore(pattern):
153
- return fnmatch.fnmatchcase(path.name, pattern) or fnmatch.fnmatchcase(
154
- str(path), pattern
155
- )
156
-
157
- return any(ignore(pattern) for pattern in normalize_path_patterns(ignore_patterns))
158
-
159
-
160
- def find_formatters():
161
- return {"black_path": shutil.which("black")}
162
-
163
-
164
- def run_formatters(written_files, black_path=(sentinel := object())):
165
- """
166
- Run the black formatter on the specified files.
167
- """
168
- # Use a sentinel rather than None, as which() returns None when not found.
169
- if black_path is sentinel:
170
- black_path = shutil.which("black")
171
- if black_path:
172
- subprocess.run(
173
- [black_path, "--fast", "--", *written_files],
174
- capture_output=True,
175
- )
File without changes
File without changes