devx: add deprecation dumpster (#27887)
* feat: Add deprecation_dumpster.py file * docs: add jovial and jocose docstring for frappe/deprecation_dumpster.py * refactor: fill the dumpster with its own kind * refactor: move to the deprecation dumpster * chore: color coding class * fix: only check import error when import errors
This commit is contained in:
parent
e7776021aa
commit
8cfeb156df
15 changed files with 361 additions and 133 deletions
|
|
@ -326,19 +326,23 @@ def connect(site: str | None = None, db_name: str | None = None, set_admin_as_us
|
|||
from frappe.database import get_db
|
||||
|
||||
if site:
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"unknown",
|
||||
"v17",
|
||||
"Calling frappe.connect with the site argument is deprecated and will be removed in next major version. "
|
||||
"Instead, explicitly invoke frappe.init(site) prior to calling frappe.connect(), if initializing the site is necessary."
|
||||
"Instead, explicitly invoke frappe.init(site) prior to calling frappe.connect(), if initializing the site is necessary.",
|
||||
)
|
||||
init(site)
|
||||
if db_name:
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"unknown",
|
||||
"v17",
|
||||
"Calling frappe.connect with the db_name argument is deprecated and will be removed in next major version. "
|
||||
"Instead, explicitly invoke frappe.init(site) with the right config prior to calling frappe.connect(), if necessary."
|
||||
"Instead, explicitly invoke frappe.init(site) with the right config prior to calling frappe.connect(), if necessary.",
|
||||
)
|
||||
|
||||
assert db_name or local.conf.db_user, "site must be fully initialized, db_user missing"
|
||||
|
|
@ -1210,9 +1214,11 @@ def generate_hash(txt: str | None = None, length: int = 56) -> str:
|
|||
import secrets
|
||||
|
||||
if txt:
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning("The `txt` parameter is deprecated and will be removed in a future release.")
|
||||
deprecation_warning(
|
||||
"unknown", "v17", "The `txt` parameter is deprecated and will be removed in a future release."
|
||||
)
|
||||
|
||||
return secrets.token_hex(math.ceil(length / 2))[:length]
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ from frappe.auth import SAFE_HTTP_METHODS, UNSAFE_HTTP_METHODS, HTTPRequest, val
|
|||
from frappe.middlewares import StaticDataMiddleware
|
||||
from frappe.utils import CallbackManager, cint, get_site_name
|
||||
from frappe.utils.data import escape_html
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.utils.error import log_error_snapshot
|
||||
from frappe.website.serve import get_response
|
||||
|
||||
|
|
@ -105,8 +104,12 @@ def application(request: Request):
|
|||
response = Response()
|
||||
|
||||
elif frappe.form_dict.cmd:
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
f"{frappe.form_dict.cmd}: Sending `cmd` for RPC calls is deprecated, call REST API instead `/api/method/cmd`"
|
||||
"unknown",
|
||||
"v17",
|
||||
f"{frappe.form_dict.cmd}: Sending `cmd` for RPC calls is deprecated, call REST API instead `/api/method/cmd`",
|
||||
)
|
||||
frappe.handler.handle()
|
||||
response = frappe.utils.response.build_response("json")
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ from frappe.twofactor import (
|
|||
should_run_2fa,
|
||||
)
|
||||
from frappe.utils import cint, date_diff, datetime, get_datetime, today
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.utils.password import check_password, get_decrypted_password
|
||||
from frappe.website.utils import get_home_page
|
||||
|
||||
|
|
@ -518,7 +517,9 @@ class LoginAttemptTracker:
|
|||
:param lock_interval: Locking interval incase of maximum failed attempts
|
||||
"""
|
||||
if user_name:
|
||||
deprecation_warning("`username` parameter is deprecated, use `key` instead.")
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning("unknown", "v17", "`username` parameter is deprecated, use `key` instead.")
|
||||
self.key = key or user_name
|
||||
self.lock_interval = datetime.timedelta(seconds=lock_interval)
|
||||
self.max_failed_logins = max_consecutive_login_attempts
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ from frappe.desk.reportview import validate_args
|
|||
from frappe.model.db_query import check_parent_permission
|
||||
from frappe.model.utils import is_virtual_doctype
|
||||
from frappe.utils import get_safe_filters
|
||||
from frappe.utils.deprecations import deprecated
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from frappe.model.document import Document
|
||||
|
|
@ -328,28 +327,9 @@ def get_password(doctype, name, fieldname):
|
|||
return frappe.get_doc(doctype, name).get_password(fieldname)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
@deprecated
|
||||
def get_js(items):
|
||||
"""Load JS code files. Will also append translations
|
||||
and extend `frappe._messages`
|
||||
from frappe.deprecation_dumpster import get_js as _get_js
|
||||
|
||||
:param items: JSON list of paths of the js files to be loaded."""
|
||||
items = json.loads(items)
|
||||
out = []
|
||||
for src in items:
|
||||
src = src.strip("/").split("/")
|
||||
|
||||
if ".." in src or src[0] != "assets":
|
||||
frappe.throw(_("Invalid file path: {0}").format("/".join(src)))
|
||||
|
||||
contentpath = os.path.join(frappe.local.sites_path, *src)
|
||||
with open(contentpath) as srcfile:
|
||||
code = frappe.utils.cstr(srcfile.read())
|
||||
|
||||
out.append(code)
|
||||
|
||||
return out
|
||||
get_js = frappe.whitelist()(_get_js)
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ from frappe.utils import (
|
|||
today,
|
||||
)
|
||||
from frappe.utils.data import sha256_hash
|
||||
from frappe.utils.deprecations import deprecated, deprecation_warning
|
||||
from frappe.utils.password import check_password, get_password_reset_limit
|
||||
from frappe.utils.password import update_password as _update_password
|
||||
from frappe.utils.user import get_system_managers
|
||||
|
|
@ -227,9 +226,7 @@ class User(Document):
|
|||
self.roles = [r for r in self.roles if r.role in new_roles]
|
||||
self.append_roles(*new_roles)
|
||||
|
||||
@deprecated
|
||||
def validate_roles(self):
|
||||
self.populate_role_profile_roles()
|
||||
from frappe.deprecation_dumpster import validate_roles
|
||||
|
||||
def move_role_profile_name_to_role_profiles(self):
|
||||
"""This handles old role_profile_name field if programatically set.
|
||||
|
|
@ -243,8 +240,12 @@ class User(Document):
|
|||
self.role_profile_name = None
|
||||
return
|
||||
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"The field `role_profile_name` is deprecated and will be removed in v16, use `role_profiles` child table instead."
|
||||
"unknown",
|
||||
"v16",
|
||||
"The field `role_profile_name` is deprecated and will be removed in v16, use `role_profiles` child table instead.",
|
||||
)
|
||||
self.append("role_profiles", {"role_profile": self.role_profile_name})
|
||||
self.role_profile_name = None
|
||||
|
|
@ -908,12 +909,15 @@ def update_password(
|
|||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def test_password_strength(new_password: str, key=None, old_password=None, user_data: tuple | None = None):
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.utils.password_strength import test_password_strength as _test_password_strength
|
||||
|
||||
if key is not None or old_password is not None:
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"Arguments `key` and `old_password` are deprecated in function `test_password_strength`."
|
||||
"unknown",
|
||||
"v17",
|
||||
"Arguments `key` and `old_password` are deprecated in function `test_password_strength`.",
|
||||
)
|
||||
|
||||
enable_password_policy = frappe.get_system_settings("enable_password_policy")
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ from frappe.monitor import get_trace_id
|
|||
from frappe.query_builder.functions import Count
|
||||
from frappe.utils import CallbackManager, cint, get_datetime, get_table_name, getdate, now, sbool
|
||||
from frappe.utils import cast as cast_fieldtype
|
||||
from frappe.utils.deprecations import deprecated, deprecation_warning
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from psycopg2 import connection as PostgresConnection
|
||||
|
|
@ -962,8 +961,12 @@ class Database:
|
|||
if dn is None or dt == dn:
|
||||
if not is_single_doctype(dt):
|
||||
return
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"Calling db.set_value on single doctype is deprecated. This behaviour will be removed in future. Use db.set_single_value instead."
|
||||
"unknown",
|
||||
"v17",
|
||||
"Calling db.set_value on single doctype is deprecated. This behaviour will be removed in future. Use db.set_single_value instead.",
|
||||
)
|
||||
self.set_single_value(
|
||||
doctype=dt,
|
||||
|
|
@ -1243,10 +1246,9 @@ class Database:
|
|||
# implemented in specific class
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
@deprecated
|
||||
def is_column_missing(e):
|
||||
return frappe.db.is_missing_column(e)
|
||||
from frappe.deprecation_dumpster import is_column_missing as _is_column_missing
|
||||
|
||||
is_column_missing = staticmethod(_is_column_missing)
|
||||
|
||||
def get_descendants(self, doctype, name):
|
||||
"""Return descendants of the group node in tree"""
|
||||
|
|
|
|||
290
frappe/deprecation_dumpster.py
Normal file
290
frappe/deprecation_dumpster.py
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
"""
|
||||
Welcome to the Deprecation Dumpster: Where Old Code Goes to Party! 🎉🗑️
|
||||
|
||||
This file is the final resting place (or should we say, "retirement home"?) for all the deprecated functions and methods of the Frappe framework. It's like a code nursing home, but with more monkey-patching and less bingo.
|
||||
|
||||
Each function or method that checks in here comes with its own personalized decorator, complete with:
|
||||
1. The date it was marked for deprecation (its "over the hill" birthday)
|
||||
2. The Frappe version in which it will be removed (its "graduation" to the great codebase in the sky)
|
||||
3. A user-facing note on alternative solutions (its "parting wisdom")
|
||||
|
||||
Warning: The global namespace herein is more patched up than a sailor's favorite pair of jeans. Proceed with caution and a sense of humor!
|
||||
|
||||
Remember, deprecated doesn't mean useless - it just means these functions are enjoying their golden years before their final bow. Treat them with respect, and maybe bring them some virtual prune juice.
|
||||
|
||||
Enjoy your stay in the Deprecation Dumpster, where every function gets a second chance to shine (or at least, to not break everything).
|
||||
"""
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
|
||||
def colorize(text, color_code):
|
||||
if sys.stdout.isatty():
|
||||
return f"\033[{color_code}m{text}\033[0m"
|
||||
return text
|
||||
|
||||
|
||||
class Color:
|
||||
RED = 91
|
||||
YELLOW = 93
|
||||
CYAN = 96
|
||||
|
||||
|
||||
try:
|
||||
# since python 3.13, PEP 702
|
||||
from warnings import deprecated as _deprecated
|
||||
except ImportError:
|
||||
import functools
|
||||
import warnings
|
||||
from collections.abc import Callable
|
||||
from typing import Optional, TypeVar, Union, overload
|
||||
|
||||
T = TypeVar("T", bound=Callable)
|
||||
|
||||
def _deprecated(message: str, category=DeprecationWarning, stacklevel=1) -> Callable[[T], T]:
|
||||
def decorator(func: T) -> T:
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if message:
|
||||
warning_msg = f"{func.__name__} is deprecated.\n{message}"
|
||||
else:
|
||||
warning_msg = f"{func.__name__} is deprecated."
|
||||
warnings.warn(warning_msg, category=category, stacklevel=stacklevel + 1)
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
wrapper.__deprecated__ = True # hint for the type checker
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def deprecated(original: str, marked: str, graduation: str, msg: str, stacklevel: int = 1):
|
||||
"""Decorator to wrap a function/method as deprecated.
|
||||
|
||||
Arguments:
|
||||
- original: frappe.utils.make_esc (fully qualified)
|
||||
- marked: 2024-09-13 (the date it has been marked)
|
||||
- graduation: v17 (generally: current version + 2)
|
||||
"""
|
||||
|
||||
def decorator(func):
|
||||
# Get the filename of the caller
|
||||
frame = inspect.currentframe()
|
||||
caller_filepath = frame.f_back.f_code.co_filename
|
||||
if os.path.basename(caller_filepath) != "deprecation_dumpster.py":
|
||||
raise RuntimeError(
|
||||
colorize("The deprecated function ", Color.YELLOW)
|
||||
+ colorize(func.__name__, Color.CYAN)
|
||||
+ colorize(" can only be called from ", Color.YELLOW)
|
||||
+ colorize("frappe/deprecation_dumpster.py\n", Color.CYAN)
|
||||
+ colorize("Move the entire function there and import it back via adding\n ", Color.YELLOW)
|
||||
+ colorize(f"from frappe.deprecation_dumpster import {func.__name__}\n", Color.CYAN)
|
||||
+ colorize("to file\n ", Color.YELLOW)
|
||||
+ colorize(caller_filepath, Color.CYAN)
|
||||
)
|
||||
|
||||
return functools.wraps(func)(
|
||||
_deprecated(
|
||||
colorize(f"`{original}`", Color.CYAN)
|
||||
+ colorize(
|
||||
f" was moved (DATE: {marked}) to frappe/deprecation_dumpster.py"
|
||||
f" for removal (from {graduation} onwards); note:\n ",
|
||||
Color.RED,
|
||||
)
|
||||
+ colorize(f"{msg}\n", Color.YELLOW),
|
||||
stacklevel=stacklevel,
|
||||
)
|
||||
)(func)
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def deprecation_warning(marked: str, graduation: str, msg: str):
|
||||
"""Warn in-place from a deprecated code path, for objects use `@deprecated` decorator from the deprectation_dumpster"
|
||||
|
||||
Arguments:
|
||||
- marked: 2024-09-13 (the date it has been marked)
|
||||
- graduation: v17 (generally: current version + 2)
|
||||
"""
|
||||
|
||||
warnings.warn(
|
||||
colorize(
|
||||
f"This codepath was marked (DATE: {marked}) deprecated"
|
||||
f" for removal (from {graduation} onwards); note:\n ",
|
||||
Color.RED,
|
||||
)
|
||||
+ colorize(f"{msg}\n", Color.YELLOW),
|
||||
category=DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
|
||||
### Party starts here
|
||||
def _old_deprecated(func):
|
||||
return deprecated(
|
||||
"frappe.deprecations.deprecated",
|
||||
"2024-09-13",
|
||||
"v17",
|
||||
"Make use of the frappe/deprecation_dumpster.py file, instead. 🎉🗑️",
|
||||
)(_deprecated("")(func))
|
||||
|
||||
|
||||
def _old_deprecation_warning(msg):
|
||||
@deprecated(
|
||||
"frappe.deprecations.deprecation_warning",
|
||||
"2024-09-13",
|
||||
"v17",
|
||||
"Use frappe.deprecation_dumpster.deprecation_warning, instead. 🎉🗑️",
|
||||
)
|
||||
def deprecation_warning(message, category=DeprecationWarning, stacklevel=1):
|
||||
warnings.warn(message=message, category=category, stacklevel=stacklevel + 2)
|
||||
|
||||
return deprecation_warning(msg)
|
||||
|
||||
|
||||
@deprecated("frappe.utils.make_esc", "unknown", "v17", "Not used anymore.")
|
||||
def make_esc(esc_chars):
|
||||
"""
|
||||
Function generator for Escaping special characters
|
||||
"""
|
||||
return lambda s: "".join("\\" + c if c in esc_chars else c for c in s)
|
||||
|
||||
|
||||
@deprecated(
|
||||
"frappe.db.is_column_missing",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Renamed to frappe.db.is_missing_column.",
|
||||
)
|
||||
def is_column_missing(e):
|
||||
import frappe
|
||||
|
||||
return frappe.db.is_missing_column(e)
|
||||
|
||||
|
||||
@deprecated(
|
||||
"frappe.desk.doctype.bulk_update.bulk_update",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Unknown.",
|
||||
)
|
||||
def show_progress(docnames, message, i, description):
|
||||
import frappe
|
||||
|
||||
n = len(docnames)
|
||||
frappe.publish_progress(float(i) * 100 / n, title=message, description=description)
|
||||
|
||||
|
||||
@deprecated(
|
||||
"frappe.client.get_js",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Unknown.",
|
||||
)
|
||||
def get_js(items):
|
||||
"""Load JS code files. Will also append translations
|
||||
and extend `frappe._messages`
|
||||
|
||||
:param items: JSON list of paths of the js files to be loaded."""
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
items = json.loads(items)
|
||||
out = []
|
||||
for src in items:
|
||||
src = src.strip("/").split("/")
|
||||
|
||||
if ".." in src or src[0] != "assets":
|
||||
frappe.throw(_("Invalid file path: {0}").format("/".join(src)))
|
||||
|
||||
contentpath = os.path.join(frappe.local.sites_path, *src)
|
||||
with open(contentpath) as srcfile:
|
||||
code = frappe.utils.cstr(srcfile.read())
|
||||
|
||||
out.append(code)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
@deprecated(
|
||||
"frappe.utils.print_format.read_multi_pdf",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Unknown.",
|
||||
)
|
||||
def read_multi_pdf(output) -> bytes:
|
||||
from io import BytesIO
|
||||
|
||||
with BytesIO() as merged_pdf:
|
||||
output.write(merged_pdf)
|
||||
return merged_pdf.getvalue()
|
||||
|
||||
|
||||
@deprecated("frappe.gzip_compress", "unknown", "v17", "Use py3 methods directly (this was compat for py2).")
|
||||
def gzip_compress(data, compresslevel=9):
|
||||
"""Compress data in one shot and return the compressed string.
|
||||
Optional argument is the compression level, in range of 0-9.
|
||||
"""
|
||||
import io
|
||||
from gzip import GzipFile
|
||||
|
||||
buf = io.BytesIO()
|
||||
with GzipFile(fileobj=buf, mode="wb", compresslevel=compresslevel) as f:
|
||||
f.write(data)
|
||||
return buf.getvalue()
|
||||
|
||||
|
||||
@deprecated("frappe.gzip_decompress", "unknown", "v17", "Use py3 methods directly (this was compat for py2).")
|
||||
def gzip_decompress(data):
|
||||
"""Decompress a gzip compressed string in one shot.
|
||||
Return the decompressed string.
|
||||
"""
|
||||
import io
|
||||
from gzip import GzipFile
|
||||
|
||||
with GzipFile(fileobj=io.BytesIO(data)) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
@deprecated(
|
||||
"frappe.email.doctype.email_queue.email_queue.send_mail",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Unknown.",
|
||||
)
|
||||
def send_mail(email_queue_name, smtp_server_instance=None):
|
||||
"""This is equivalent to EmailQueue.send.
|
||||
|
||||
This provides a way to make sending mail as a background job.
|
||||
"""
|
||||
from frappe.email.doctype.email_queue.email_queue import EmailQueue
|
||||
|
||||
record = EmailQueue.find(email_queue_name)
|
||||
record.send(smtp_server_instance=smtp_server_instance)
|
||||
|
||||
|
||||
@deprecated(
|
||||
"frappe.geo.country_info.get_translated_dict",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Use frappe.geo.country_info.get_translated_countries, instead.",
|
||||
)
|
||||
def get_translated_dict():
|
||||
from frappe.geo.country_info import get_translated_countries
|
||||
|
||||
return get_translated_countries()
|
||||
|
||||
|
||||
@deprecated(
|
||||
"User.validate_roles",
|
||||
"unknown",
|
||||
"v17",
|
||||
"Use User.populate_role_profile_roles, instead.",
|
||||
)
|
||||
def validate_roles(self):
|
||||
self.populate_role_profile_roles()
|
||||
|
|
@ -6,7 +6,6 @@ from frappe import _
|
|||
from frappe.core.doctype.submission_queue.submission_queue import queue_submission
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint
|
||||
from frappe.utils.deprecations import deprecated
|
||||
from frappe.utils.scheduler import is_scheduler_inactive
|
||||
|
||||
|
||||
|
|
@ -111,7 +110,4 @@ def _bulk_action(doctype, docnames, action, data, task_id=None):
|
|||
return failed
|
||||
|
||||
|
||||
@deprecated
|
||||
def show_progress(docnames, message, i, description):
|
||||
n = len(docnames)
|
||||
frappe.publish_progress(float(i) * 100 / n, title=message, description=description)
|
||||
from frappe.deprecation_dumpster import show_progress
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ from frappe.utils import (
|
|||
sbool,
|
||||
split_emails,
|
||||
)
|
||||
from frappe.utils.deprecations import deprecated
|
||||
from frappe.utils.verified_command import get_signed_params
|
||||
|
||||
|
||||
|
|
@ -223,15 +222,9 @@ class EmailQueue(Document):
|
|||
).run()
|
||||
|
||||
|
||||
@task(queue="short")
|
||||
@deprecated
|
||||
def send_mail(email_queue_name, smtp_server_instance: SMTPServer = None):
|
||||
"""This is equivalent to EmailQueue.send.
|
||||
from frappe.deprecation_dumpster import send_mail as _send_mail
|
||||
|
||||
This provides a way to make sending mail as a background job.
|
||||
"""
|
||||
record = EmailQueue.find(email_queue_name)
|
||||
record.send(smtp_server_instance=smtp_server_instance)
|
||||
send_mail = task(queue="short")(_send_mail)
|
||||
|
||||
|
||||
class SendMailContext:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import os
|
|||
from functools import lru_cache
|
||||
|
||||
import frappe
|
||||
from frappe.utils.deprecations import deprecated
|
||||
from frappe.utils.momentjs import get_all_timezones
|
||||
|
||||
|
||||
|
|
@ -39,9 +38,7 @@ def _get_country_timezone_info():
|
|||
return {"country_info": get_all(), "all_timezones": get_all_timezones()}
|
||||
|
||||
|
||||
@deprecated
|
||||
def get_translated_dict():
|
||||
return get_translated_countries()
|
||||
from frappe.deprecation_dumpster import get_translated_dict
|
||||
|
||||
|
||||
def get_translated_countries():
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from frappe.core.doctype.server_script.server_script_utils import get_server_scr
|
|||
from frappe.monitor import add_data_to_monitor
|
||||
from frappe.utils import cint
|
||||
from frappe.utils.csvutils import build_csv_response
|
||||
from frappe.utils.deprecations import deprecated, deprecation_warning
|
||||
from frappe.utils.deprecations import deprecated
|
||||
from frappe.utils.image import optimize_image
|
||||
from frappe.utils.response import build_response
|
||||
|
||||
|
|
@ -241,8 +241,12 @@ def get_attr(cmd):
|
|||
if "." in cmd:
|
||||
method = frappe.get_attr(cmd)
|
||||
else:
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
f"Calling shorthand for {cmd} is deprecated, please specify full path in RPC call."
|
||||
"unknown",
|
||||
"v17",
|
||||
f"Calling shorthand for {cmd} is deprecated, please specify full path in RPC call.",
|
||||
)
|
||||
method = globals()[cmd]
|
||||
return method
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ from typing import TypedDict
|
|||
|
||||
from werkzeug.test import Client
|
||||
|
||||
from frappe.deprecation_dumpster import gzip_compress, gzip_decompress, make_esc
|
||||
|
||||
# utility functions like cint, int, flt, etc.
|
||||
from frappe.utils.data import *
|
||||
from frappe.utils.deprecations import deprecated
|
||||
from frappe.utils.html_utils import sanitize_html
|
||||
|
||||
EMAIL_NAME_PATTERN = re.compile(r"[^A-Za-z0-9\u00C0-\u024F\/\_\' ]+")
|
||||
|
|
@ -423,14 +424,6 @@ def get_file_timestamp(fn):
|
|||
return None
|
||||
|
||||
|
||||
# to be deprecated
|
||||
def make_esc(esc_chars):
|
||||
"""
|
||||
Function generator for Escaping special characters
|
||||
"""
|
||||
return lambda s: "".join("\\" + c if c in esc_chars else c for c in s)
|
||||
|
||||
|
||||
# esc / unescape characters -- used for command line
|
||||
def esc(s, esc_chars):
|
||||
"""
|
||||
|
|
@ -888,34 +881,6 @@ def call(fn, *args, **kwargs):
|
|||
return json.loads(frappe.as_json(frappe.call(fn, *args, **kwargs)))
|
||||
|
||||
|
||||
# Following methods are aken as-is from Python 3 codebase
|
||||
# since gzip.compress and gzip.decompress are not available in Python 2.7
|
||||
|
||||
|
||||
@deprecated
|
||||
def gzip_compress(data, compresslevel=9):
|
||||
"""Compress data in one shot and return the compressed string.
|
||||
Optional argument is the compression level, in range of 0-9.
|
||||
"""
|
||||
from gzip import GzipFile
|
||||
|
||||
buf = io.BytesIO()
|
||||
with GzipFile(fileobj=buf, mode="wb", compresslevel=compresslevel) as f:
|
||||
f.write(data)
|
||||
return buf.getvalue()
|
||||
|
||||
|
||||
@deprecated
|
||||
def gzip_decompress(data):
|
||||
"""Decompress a gzip compressed string in one shot.
|
||||
Return the decompressed string.
|
||||
"""
|
||||
from gzip import GzipFile
|
||||
|
||||
with GzipFile(fileobj=io.BytesIO(data)) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def get_safe_filters(filters):
|
||||
try:
|
||||
filters = json.loads(filters)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import frappe.monitor
|
|||
from frappe import _
|
||||
from frappe.utils import CallbackManager, cint, get_bench_id
|
||||
from frappe.utils.commands import log
|
||||
from frappe.utils.deprecations import deprecation_warning
|
||||
from frappe.utils.redis_queue import RedisQueue
|
||||
|
||||
# TTL to keep RQ job logs in redis for.
|
||||
|
|
@ -119,11 +118,19 @@ def enqueue(
|
|||
job_id = create_job_id(job_id)
|
||||
|
||||
if job_name:
|
||||
deprecation_warning("Using enqueue with `job_name` is deprecated, use `job_id` instead.")
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"unknown", "v17", "Using enqueue with `job_name` is deprecated, use `job_id` instead."
|
||||
)
|
||||
|
||||
if not is_async and not frappe.flags.in_test:
|
||||
from frappe.deprecation_dumpster import deprecation_warning
|
||||
|
||||
deprecation_warning(
|
||||
"Using enqueue with is_async=False outside of tests is not recommended, use now=True instead."
|
||||
"unknown",
|
||||
"v17",
|
||||
"Using enqueue with is_async=False outside of tests is not recommended, use now=True instead.",
|
||||
)
|
||||
|
||||
call_directly = now or (not is_async and not frappe.flags.in_test)
|
||||
|
|
|
|||
|
|
@ -1,27 +1,12 @@
|
|||
""" Utils for deprecating functionality in Framework.
|
||||
"""Utils for deprecating functionality in Framework.
|
||||
|
||||
WARNING: This file is internal, instead of depending just copy the code or use deprecation
|
||||
libraries.
|
||||
"""
|
||||
import functools
|
||||
import warnings
|
||||
|
||||
|
||||
def deprecated(func):
|
||||
"""Decorator to wrap a function/method as deprecated."""
|
||||
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
deprecation_warning(
|
||||
f"{func.__name__} is deprecated and will be removed in next major version.",
|
||||
stacklevel=1,
|
||||
)
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def deprecation_warning(message, category=DeprecationWarning, stacklevel=1):
|
||||
"""like warnings.warn but with auto incremented sane stacklevel."""
|
||||
|
||||
warnings.warn(message=message, category=category, stacklevel=stacklevel + 2)
|
||||
from frappe.deprecation_dumpster import (
|
||||
_old_deprecated as deprecated,
|
||||
)
|
||||
from frappe.deprecation_dumpster import (
|
||||
_old_deprecation_warning as deprecation_warning,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import frappe
|
|||
from frappe import _
|
||||
from frappe.core.doctype.access_log.access_log import make_access_log
|
||||
from frappe.translate import print_language
|
||||
from frappe.utils.deprecations import deprecated
|
||||
from frappe.utils.pdf import get_pdf
|
||||
|
||||
no_cache = 1
|
||||
|
|
@ -214,11 +213,7 @@ def _download_multi_pdf(
|
|||
frappe.local.response.type = "pdf"
|
||||
|
||||
|
||||
@deprecated
|
||||
def read_multi_pdf(output: PdfWriter) -> bytes:
|
||||
with BytesIO() as merged_pdf:
|
||||
output.write(merged_pdf)
|
||||
return merged_pdf.getvalue()
|
||||
from frappe.deprecation_dumpster import read_multi_pdf
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue