t-sql 4.7.0__tar.gz → 4.7.1__tar.gz

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.
Files changed (38) hide show
  1. t_sql-4.7.0/README.md → t_sql-4.7.1/PKG-INFO +26 -0
  2. t_sql-4.7.0/PKG-INFO → t_sql-4.7.1/README.md +16 -10
  3. {t_sql-4.7.0 → t_sql-4.7.1}/pyproject.toml +1 -1
  4. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_deep_nesting.py +2 -1
  5. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_tsql.py +15 -4
  6. {t_sql-4.7.0 → t_sql-4.7.1}/tsql/__init__.py +3 -2
  7. {t_sql-4.7.0 → t_sql-4.7.1}/.dockerignore +0 -0
  8. {t_sql-4.7.0 → t_sql-4.7.1}/.github/workflows/publish.yml +0 -0
  9. {t_sql-4.7.0 → t_sql-4.7.1}/.github/workflows/test.yml +0 -0
  10. {t_sql-4.7.0 → t_sql-4.7.1}/.gitignore +0 -0
  11. {t_sql-4.7.0 → t_sql-4.7.1}/Dockerfile +0 -0
  12. {t_sql-4.7.0 → t_sql-4.7.1}/LICENSE +0 -0
  13. {t_sql-4.7.0 → t_sql-4.7.1}/compose.yaml +0 -0
  14. {t_sql-4.7.0 → t_sql-4.7.1}/context7.json +0 -0
  15. {t_sql-4.7.0 → t_sql-4.7.1}/pytest.ini +0 -0
  16. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_alembic_integration.py +0 -0
  17. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_asyncpg_integration.py +0 -0
  18. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_different_object_types.py +0 -0
  19. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_error_messages.py +0 -0
  20. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_escaped.py +0 -0
  21. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_escaped_binary_hex.py +0 -0
  22. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_helper_functions.py +0 -0
  23. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_injection_edge_cases.py +0 -0
  24. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_injection_protection_validation.py +0 -0
  25. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_injections_for_escaped.py +0 -0
  26. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_mysql_integration.py +0 -0
  27. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_parameter_names.py +0 -0
  28. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_query_builder.py +0 -0
  29. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_sqlalchemy_integration.py +0 -0
  30. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_sqlite_integration.py +0 -0
  31. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_string_based_builders.py +0 -0
  32. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_styles.py +0 -0
  33. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_template_in_builders.py +0 -0
  34. {t_sql-4.7.0 → t_sql-4.7.1}/tests/test_type_processor.py +0 -0
  35. {t_sql-4.7.0 → t_sql-4.7.1}/tsql/query_builder.py +0 -0
  36. {t_sql-4.7.0 → t_sql-4.7.1}/tsql/row.py +0 -0
  37. {t_sql-4.7.0 → t_sql-4.7.1}/tsql/styles.py +0 -0
  38. {t_sql-4.7.0 → t_sql-4.7.1}/tsql/type_processor.py +0 -0
@@ -1,3 +1,13 @@
1
+ Metadata-Version: 2.4
2
+ Name: t-sql
3
+ Version: 4.7.1
4
+ Summary: Safe SQL. SQL queries for python t-strings (PEP 750)
5
+ Project-URL: Homepage, https://github.com/nhumrich/t-sql
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.14
8
+ Requires-Dist: alembic>=1.17.0
9
+ Description-Content-Type: text/markdown
10
+
1
11
  # t-sql
2
12
 
3
13
  A lightweight SQL templating library that leverages Python 3.14's t-strings (PEP 750).
@@ -105,6 +115,22 @@ sql, params = tsql.render(t"UPDATE users SET {values:as_set} WHERE id='abc123'")
105
115
  # ('UPDATE users SET name = ?, email = ? WHERE id='abc123'', ['joe', 'joe@example.com'])
106
116
  ```
107
117
 
118
+ #### Tuples for IN clauses
119
+
120
+ Use tuples to expand lists of values for SQL IN clauses:
121
+
122
+ ```python
123
+ # Convert list to tuple for IN clause
124
+ my_ids = ['123', '234', '531']
125
+ sql, params = tsql.render(t"SELECT * FROM mytable WHERE id IN {tuple(my_ids)}")
126
+ # ('SELECT * FROM mytable WHERE id IN (?, ?, ?)', ['123', '234', '531'])
127
+
128
+ # Or use a tuple directly
129
+ active_statuses = ('active', 'pending', 'approved')
130
+ sql, params = tsql.render(t"SELECT * FROM orders WHERE status IN {active_statuses}")
131
+ # ('SELECT * FROM orders WHERE status IN (?, ?, ?)', ['active', 'pending', 'approved'])
132
+ ```
133
+
108
134
  ### Helper Functions
109
135
 
110
136
  t-sql provides several convenience functions for common SQL operations:
@@ -1,13 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: t-sql
3
- Version: 4.7.0
4
- Summary: Safe SQL. SQL queries for python t-strings (PEP 750)
5
- Project-URL: Homepage, https://github.com/nhumrich/t-sql
6
- License-File: LICENSE
7
- Requires-Python: >=3.14
8
- Requires-Dist: alembic>=1.17.0
9
- Description-Content-Type: text/markdown
10
-
11
1
  # t-sql
12
2
 
13
3
  A lightweight SQL templating library that leverages Python 3.14's t-strings (PEP 750).
@@ -115,6 +105,22 @@ sql, params = tsql.render(t"UPDATE users SET {values:as_set} WHERE id='abc123'")
115
105
  # ('UPDATE users SET name = ?, email = ? WHERE id='abc123'', ['joe', 'joe@example.com'])
116
106
  ```
117
107
 
108
+ #### Tuples for IN clauses
109
+
110
+ Use tuples to expand lists of values for SQL IN clauses:
111
+
112
+ ```python
113
+ # Convert list to tuple for IN clause
114
+ my_ids = ['123', '234', '531']
115
+ sql, params = tsql.render(t"SELECT * FROM mytable WHERE id IN {tuple(my_ids)}")
116
+ # ('SELECT * FROM mytable WHERE id IN (?, ?, ?)', ['123', '234', '531'])
117
+
118
+ # Or use a tuple directly
119
+ active_statuses = ('active', 'pending', 'approved')
120
+ sql, params = tsql.render(t"SELECT * FROM orders WHERE status IN {active_statuses}")
121
+ # ('SELECT * FROM orders WHERE status IN (?, ?, ?)', ['active', 'pending', 'approved'])
122
+ ```
123
+
118
124
  ### Helper Functions
119
125
 
120
126
  t-sql provides several convenience functions for common SQL operations:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "t-sql"
7
- version = "4.7.0"
7
+ version = "4.7.1"
8
8
  description = "Safe SQL. SQL queries for python t-strings (PEP 750)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.14"
@@ -311,7 +311,8 @@ def test_case_expression_with_subqueries():
311
311
 
312
312
  sql, params = tsql.render(query, style=styles.QMARK)
313
313
 
314
- assert "CASE WHEN (SELECT COUNT(*)" in sql
314
+ assert "CASE" in sql
315
+ assert "WHEN (SELECT COUNT(*)" in sql
315
316
  assert "> ?" in sql
316
317
  assert "THEN 'active'" in sql
317
318
  assert params == [10]
@@ -35,15 +35,26 @@ def test_merges_literals_using_exsiting_tstring():
35
35
  assert result._sql == 'hello there'
36
36
 
37
37
 
38
- def test_strips_literal_whitespace():
39
- result = tsql.render(t"SELECT \n * \n FROM table")
38
+ def test_strips_horizontal_whitespace():
39
+ # Horizontal whitespace (spaces/tabs) is collapsed, but newlines are preserved
40
+ result = tsql.render(t"SELECT * FROM table")
40
41
  assert result[0] == 'SELECT * FROM table'
41
42
 
42
43
 
44
+ def test_preserves_newlines_for_sql_comments():
45
+ # Newlines must be preserved so -- style SQL comments work correctly
46
+ query = t"""SELECT * FROM users
47
+ -- Filter by active status
48
+ WHERE active = true"""
49
+ result = tsql.render(query)
50
+ assert '-- Filter by active status\n' in result[0]
51
+ assert 'WHERE active = true' in result[0]
52
+
53
+
43
54
  def test_doesnt_strip_whitespace_in_values():
44
55
  user_input = 'Some string\nWith whitespace. With Formating that is \n just right'
45
- result = tsql.render(t'INSERT \n INTO table (vals) VALUES({user_input})')
46
- assert result[0] == f'INSERT INTO table (vals) VALUES(?)'
56
+ result = tsql.render(t'INSERT INTO table (vals) VALUES({user_input})')
57
+ assert result[0] == 'INSERT INTO table (vals) VALUES(?)'
47
58
  assert result[1] == [user_input]
48
59
 
49
60
 
@@ -9,8 +9,9 @@ from tsql.styles import ParamStyle, QMARK
9
9
 
10
10
  logger = logging.getLogger(__name__)
11
11
 
12
- # Pre-compile regex for whitespace collapsing to avoid cache lookup overhead
13
- _WHITESPACE_RE = re.compile(r'\s+')
12
+ # Pre-compile regex for horizontal whitespace collapsing (spaces/tabs only)
13
+ # Preserves newlines so that -- style SQL comments work correctly
14
+ _WHITESPACE_RE = re.compile(r'[ \t]+')
14
15
 
15
16
  if TYPE_CHECKING:
16
17
  from tsql.query_builder import QueryBuilder
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes