Revert: DocRef (#32866)
- Hardly used anywhere - Too many hardcoded `__value__` calls without which it's not usable. - Another type to worry about
This commit is contained in:
parent
49a11a0112
commit
e4bc7f361b
10 changed files with 7 additions and 116 deletions
|
|
@ -8,11 +8,10 @@ from functools import cached_property, wraps
|
|||
import frappe
|
||||
from frappe.query_builder.builder import MariaDB, Postgres, SQLite
|
||||
from frappe.query_builder.functions import Function
|
||||
from frappe.types import DocRef
|
||||
|
||||
Query = str | MariaDB | Postgres | SQLite
|
||||
QueryValues = tuple | list | dict | None
|
||||
FilterValue = DocRef | str | int | bool
|
||||
FilterValue = str | int | bool
|
||||
|
||||
EmptyQueryValues = object()
|
||||
FallBackDateTimeStr = "0001-01-01 00:00:00.000000"
|
||||
|
|
@ -29,8 +28,6 @@ QUERY_TYPE_PATTERN = re.compile(r"\s*([A-Za-z]*)")
|
|||
|
||||
|
||||
def convert_to_value(o: FilterValue):
|
||||
if hasattr(o, "__value__"):
|
||||
return o.__value__()
|
||||
if isinstance(o, bool):
|
||||
return int(o)
|
||||
return o
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ from frappe.model.dynamic_links import invalidate_distinct_link_doctypes
|
|||
from frappe.model.naming import set_new_name
|
||||
from frappe.model.utils.link_count import notify_link_count
|
||||
from frappe.modules import load_doctype_module
|
||||
from frappe.types.docref import DocRef
|
||||
from frappe.utils import (
|
||||
cached_property,
|
||||
cast_fieldtype,
|
||||
|
|
@ -475,9 +474,6 @@ class BaseDocument:
|
|||
else:
|
||||
value = get_not_null_defaults(df.fieldtype)
|
||||
|
||||
if hasattr(value, "__value__"):
|
||||
value = value.__value__()
|
||||
|
||||
d[fieldname] = value
|
||||
|
||||
return d
|
||||
|
|
@ -865,7 +861,7 @@ class BaseDocument:
|
|||
if not docname:
|
||||
continue
|
||||
|
||||
assert isinstance(docname, str | int | DocRef) or (
|
||||
assert isinstance(docname, str | int) or (
|
||||
isinstance(docname, list | tuple | set) and len(docname) == 1
|
||||
), f"Unexpected value for field {df.fieldname}: {docname}"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from frappe.model.docstatus import DocStatus
|
|||
from frappe.model.naming import set_new_name, validate_name
|
||||
from frappe.model.utils import is_virtual_doctype, simple_singledispatch
|
||||
from frappe.model.workflow import set_workflow_state_on_action, validate_workflow
|
||||
from frappe.types import DF, DocRef
|
||||
from frappe.types import DF
|
||||
from frappe.utils import compare, cstr, date_diff, file_lock, flt, get_table_name, now
|
||||
from frappe.utils.data import get_absolute_url, get_datetime, get_timedelta, getdate
|
||||
from frappe.utils.global_search import update_global_search
|
||||
|
|
@ -105,7 +105,7 @@ def get_doc(*args, **kwargs) -> "Document":
|
|||
if not args and kwargs:
|
||||
return get_doc_from_dict(kwargs)
|
||||
else:
|
||||
raise ValueError("First non keyword argument must be a string, dict or DocRef")
|
||||
raise ValueError("First non keyword argument must be a string or dict")
|
||||
|
||||
|
||||
@get_doc.register(BaseDocument)
|
||||
|
|
@ -113,11 +113,6 @@ def _basedoc(doc: BaseDocument, *args, **kwargs) -> "Document":
|
|||
return doc
|
||||
|
||||
|
||||
@get_doc.register(DocRef)
|
||||
def _docref(doc_ref: DocRef, **kwargs) -> "Document":
|
||||
return get_doc(doc_ref.doctype, doc_ref.name, **kwargs)
|
||||
|
||||
|
||||
@get_doc.register(str)
|
||||
def get_doc_str(doctype: str, name: str | None = None, **kwargs) -> "Document":
|
||||
# if no name: it's a single
|
||||
|
|
@ -143,7 +138,7 @@ def get_doc_from_dict(data: dict[str, Any], **kwargs) -> "Document":
|
|||
raise ImportError(data["doctype"])
|
||||
|
||||
|
||||
class Document(BaseDocument, DocRef):
|
||||
class Document(BaseDocument):
|
||||
"""All controllers inherit from `Document`."""
|
||||
|
||||
doctype: DF.Data
|
||||
|
|
@ -197,9 +192,6 @@ class Document(BaseDocument, DocRef):
|
|||
if isinstance(arg, dict):
|
||||
return self._init_from_kwargs(arg)
|
||||
|
||||
if isinstance(arg, DocRef):
|
||||
return self._init_known_doc(arg.doctype, arg.name, **kwargs)
|
||||
|
||||
raise ValueError(f"Unsupported argument type: {type(arg)}")
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ from frappe.model.document import Document
|
|||
from frappe.model.utils import is_single_doctype
|
||||
from frappe.model.workflow import get_workflow_name
|
||||
from frappe.modules import load_doctype_module
|
||||
from frappe.types import DocRef
|
||||
from frappe.utils import cached_property, cast, cint, cstr
|
||||
from frappe.utils.caching import site_cache
|
||||
from frappe.utils.data import add_to_date, get_datetime
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
import frappe
|
||||
from frappe.model.document import Document, get_doc
|
||||
from frappe.tests import IntegrationTestCase
|
||||
from frappe.types import DocRef
|
||||
|
||||
EXTRA_TEST_RECORD_DEPENDENCIES = ["User"]
|
||||
|
||||
|
||||
class TestDocRef(IntegrationTestCase):
|
||||
def test_doc_ref_get_doc(self):
|
||||
# Test using DocRef with get_doc
|
||||
doc_ref = DocRef("User", "test@example.com")
|
||||
user = get_doc(doc_ref)
|
||||
|
||||
# Assert that user is an instance of both Document and DocRef
|
||||
self.assertIsInstance(user, Document)
|
||||
self.assertIsInstance(user, DocRef)
|
||||
|
||||
# Check more attributes
|
||||
self.assertEqual(user.doctype, "User")
|
||||
self.assertEqual(user.name, "test@example.com")
|
||||
self.assertEqual(user.email, "test@example.com")
|
||||
self.assertEqual(user.first_name, "_Test")
|
||||
|
||||
def test_doc_ref_in_query(self):
|
||||
# Test using DocRef in a database query
|
||||
user = frappe.get_doc("User", "test@example.com")
|
||||
|
||||
# Assert that user is an instance of both Document and DocRef
|
||||
self.assertIsInstance(user, Document)
|
||||
self.assertIsInstance(user, DocRef)
|
||||
|
||||
# Create a test document that references the user
|
||||
test_doc = frappe.get_doc(
|
||||
{
|
||||
"doctype": "ToDo",
|
||||
"description": "Test ToDo",
|
||||
"reference_type": "User",
|
||||
"reference_name": user, # This should work with DocRef
|
||||
}
|
||||
).insert()
|
||||
|
||||
# Getter using the DocRef
|
||||
result = frappe.db.get_value("ToDo", {"reference_name": user}, ["name", "description"])
|
||||
self.assertEqual(result[0], test_doc.name)
|
||||
self.assertEqual(result[1], "Test ToDo")
|
||||
# Setter using Document as DocRef
|
||||
frappe.db.set_value("ToDo", test_doc, "description", "Revised Test ToDo")
|
||||
test_doc.reload()
|
||||
self.assertEqual(test_doc.description, "Revised Test ToDo")
|
||||
|
||||
def test_doc_ref_value_representation(self):
|
||||
# Test the value representation of DocRef
|
||||
doc_ref = DocRef("User", "test@example.com")
|
||||
self.assertEqual(doc_ref.__value__(), "test@example.com")
|
||||
|
||||
def test_doc_ref_attributes(self):
|
||||
# Test DocRef attributes
|
||||
doc_ref = DocRef("User", "test@example.com")
|
||||
self.assertEqual(doc_ref.doctype, "User")
|
||||
self.assertEqual(doc_ref.name, "test@example.com")
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
from .docref import DocRef
|
||||
from .filter import Filters, FilterSignature, FilterTuple
|
||||
from .frappedict import _dict
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
from typing import Union
|
||||
|
||||
from typing_extensions import override
|
||||
|
||||
|
||||
class DocRef:
|
||||
"""A lightweight reference to a document, containing just the doctype and name."""
|
||||
|
||||
def __init__(self, doctype: str, name: str):
|
||||
self.doctype = doctype
|
||||
self.name = name
|
||||
|
||||
def __value__(self) -> str:
|
||||
# Used when requiring its value representation for db interactions, serializations, etc
|
||||
return self.name
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return f"{self.doctype} ({self.name or 'n/a'})"
|
||||
|
||||
@override
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.__class__.__name__}: doctype={self.doctype} name={self.name or 'n/a'}>"
|
||||
|
|
@ -9,14 +9,12 @@ from typing import Any, NamedTuple, TypeAlias, TypeGuard, TypeVar, cast
|
|||
from pypika import Column
|
||||
from typing_extensions import Self, override
|
||||
|
||||
from .docref import DocRef
|
||||
|
||||
Doct: TypeAlias = str
|
||||
Fld: TypeAlias = str
|
||||
Op: TypeAlias = str
|
||||
DateTime: TypeAlias = datetime | date
|
||||
_Value: TypeAlias = str | int | float | None | DateTime | Column
|
||||
_InputValue: TypeAlias = _Value | DocRef | bool
|
||||
_InputValue: TypeAlias = _Value | bool
|
||||
Value: TypeAlias = _Value | Sequence[_Value]
|
||||
InputValue: TypeAlias = _InputValue | Sequence[_InputValue]
|
||||
|
||||
|
|
@ -55,10 +53,8 @@ class _FilterTuple(NamedTuple):
|
|||
def _type_narrow(v: _InputValue) -> _Value:
|
||||
if isinstance(v, bool): # beware: bool derives int in _Value
|
||||
return int(v)
|
||||
elif isinstance(v, _Value):
|
||||
elif isinstance(v, _Value): # type: ignore[redundant-expr]
|
||||
return v
|
||||
elif isinstance(v, DocRef): # type: ignore[redundant-expr]
|
||||
return v.__value__()
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Value must be one of types: {', '.join(str(t.__name__) for t in _InputValue.__args__)}; found {type(v)}"
|
||||
|
|
|
|||
|
|
@ -248,9 +248,6 @@ def json_handler(obj):
|
|||
elif isinstance(obj, Path):
|
||||
return str(obj)
|
||||
|
||||
elif hasattr(obj, "__value__"): # order imporant: defer to __json__ if implemented
|
||||
return obj.__value__()
|
||||
|
||||
else:
|
||||
raise TypeError(f"""Object of type {type(obj)} with value of {obj!r} is not JSON serializable""")
|
||||
|
||||
|
|
|
|||
|
|
@ -223,7 +223,6 @@ files = [
|
|||
# start small, with a lot of multiplication potential
|
||||
"frappe/types/__init__.py",
|
||||
"frappe/types/DF.py",
|
||||
"frappe/types/docref.py",
|
||||
"frappe/types/frappedict.py",
|
||||
"frappe/types/filter.py",
|
||||
]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue