Repository: gtalarico/pyairtable
Pull request #384 (2024-08-21 03:23:46)

Deprecate `escape_quotes` function in favor of `quoted`
The `escape_quotes` function never quite made sense to me, because it only quotes at most once (so its behavior is hard to predict) and does not enclose the return value in quotes. I don't really know what its utility is, so I'm proposing we deprecate it and encourage people to use `quoted` instead (which takes a string value and returns it as an Airtable-compatible string representation).


Patch:
diff --git a/docs/source/migrations.rst b/docs/source/migrations.rst
index 4cbae28..f2ada1f 100644
--- a/docs/source/migrations.rst
+++ b/docs/source/migrations.rst
@@ -53,6 +53,8 @@ The full list of breaking changes is below:
     * - :func:`~pyairtable.formulas.IF`, :func:`~pyairtable.formulas.FIND`, :func:`~pyairtable.formulas.LOWER`
       - These no longer return ``str``, and instead return instances of
         :class:`~pyairtable.formulas.FunctionCall`.
+    * - :func:`~pyairtable.formulas.escape_quotes`
+      - Deprecated. Use :func:`~pyairtable.formulas.quoted` instead.
 
 Changes to retrieving ORM model configuration
 ---------------------------------------------
diff --git a/pyairtable/formulas.py b/pyairtable/formulas.py
index dac7ad5..6eb71df 100644
--- a/pyairtable/formulas.py
+++ b/pyairtable/formulas.py
@@ -7,6 +7,7 @@ See :doc:`formulas` for more information.
 
 import datetime
 import re
+import warnings
 from decimal import Decimal
 from fractions import Fraction
 from typing import Any, ClassVar, Iterable, List, Optional, Set, Union
@@ -461,13 +462,17 @@ def quoted(value: str) -> str:
     >>> quoted("Guest's Name")
     "'Guest\\'s Name'"
     """
-    return "'{}'".format(escape_quotes(str(value)))
+    value = value.replace("\\", r"\\").replace("'", r"\'")
+    return "'{}'".format(value)
 
 
 def escape_quotes(value: str) -> str:
     r"""
     Ensure any quotes are escaped. Already escaped quotes are ignored.
 
+    This function has been deprecated.
+    Use :func:`~pyairtable.formulas.quoted` instead.
+
     Args:
         value: text to be escaped
 
@@ -477,6 +482,11 @@ def escape_quotes(value: str) -> str:
         >>> escape_quotes(r"Player\'s Name")
         "Player\\'s Name"
     """
+    warnings.warn(
+        "escape_quotes is deprecated; use quoted() instead.",
+        category=DeprecationWarning,
+        stacklevel=2,
+    )
     escaped_value = re.sub("(?<!\\\\)'", "\\'", value)
     return escaped_value
 
@@ -492,12 +502,12 @@ def field_name(name: str) -> str:
         >>> field_name("First Name")
         '{First Name}'
         >>> field_name("Guest's Name")
-        "{Guest\\'s Name}"
+        "{Guest's Name}"
     """
     # This will not actually work with field names that contain more
     # than one closing curly brace; that's a limitation of Airtable.
     # Our library will escape all closing braces, but the API will fail.
-    return "{%s}" % escape_quotes(name.replace("}", r"\}"))
+    return "{%s}" % name.replace("}", r"\}")
 
 
 class FunctionCall(Formula):


Test patch:
diff --git a/tests/test_formulas.py b/tests/test_formulas.py
index 41396da..6514cb7 100644
--- a/tests/test_formulas.py
+++ b/tests/test_formulas.py
@@ -334,7 +334,7 @@ def test_function_call_equivalence():
     "input,expected",
     [
         ("First Name", "{First Name}"),
-        ("Guest's Name", r"{Guest\'s Name}"),
+        ("Guest's Name", r"{Guest's Name}"),
         ("With {Curly Braces}", r"{With {Curly Braces\}}"),
     ],
 )
@@ -343,8 +343,9 @@ def test_field_name(input, expected):
 
 
 def test_quoted():
-    assert F.quoted("John") == "'John'"
-    assert F.quoted("Guest's Name") == "'Guest\\'s Name'"
+    assert F.quoted("Guest") == "'Guest'"
+    assert F.quoted("Guest's Name") == r"'Guest\'s Name'"
+    assert F.quoted(F.quoted("Guest's Name")) == r"'\'Guest\\\'s Name\''"
 
 
 class FakeModel(orm.Model):