• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SAP / sqlalchemy-hana / 26713222657

31 May 2026 11:46AM UTC coverage: 94.509% (-1.5%) from 95.987%
26713222657

push

github

web-flow
Update dependency coverage to v7.14.1 (#628)

This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [coverage](https://redirect.github.com/coveragepy/coveragepy) |
`==7.14.0` → `==7.14.1` |
![age](https://developer.mend.io/api/mc/badges/age/pypi/coverage/7.14.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/coverage/7.14.0/7.14.1?slim=true)
|

---

### Release Notes

<details>
<summary>coveragepy/coveragepy (coverage)</summary>

###
[`v7.14.1`](https://redirect.github.com/coveragepy/coveragepy/blob/HEAD/CHANGES.rst#Version-7141--2026-05-26)

[Compare
Source](https://redirect.github.com/coveragepy/coveragepy/compare/7.14.0...7.14.1)

- Fix: the HTML report used typographic niceties to make file paths more
readable by adding a small amount of space around slashes. Those spaces
interfered with searching the page for file paths of interest. Now the
report
uses CSS to accomplish the same visual tweak so that searches with
slashes
  work correctly. Closes `issue 2170`\_.

- `Add a 3.16 PyPI classifier <hugo-316_>`\_ since we test on the 3.16
main
  branch.

.. \_issue 2170:
[#&#8203;2170](https://redirect.github.com/coveragepy/coveragepy/issues/2170)
.. \_hugo-316:
<https://mastodon.social/@&#8203;hugovk/116588523571204490>

.. \_changes\_7-14-0:

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

â™» **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [reposit... (continued)

1790 of 1894 relevant lines covered (94.51%)

0.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.55
/test/test_sqlalchemy_dialect_suite.py
1
# pylint: disable=wildcard-import,unused-wildcard-import,function-redefined,arguments-differ
2
"""SQLAlchemy dialect test suite."""
3

4
from __future__ import annotations
1✔
5

6
from typing import Any
1✔
7

8
import pytest
1✔
9
import sqlalchemy.types as sql_types
×
10
from sqlalchemy import (
1✔
11
    ForeignKey,
12
    ForeignKeyConstraint,
13
    Integer,
14
    String,
15
    inspect,
16
    testing,
17
)
18
from sqlalchemy.exc import DBAPIError
×
19
from sqlalchemy.testing.assertions import assert_raises, eq_
×
20
from sqlalchemy.testing.provision import temp_table_keyword_args
×
21
from sqlalchemy.testing.schema import Column, Table
1✔
22
from sqlalchemy.testing.suite import *  # noqa: F401, F403
1✔
23
from sqlalchemy.testing.suite.test_cte import CTETest as _CTETest
1✔
24
from sqlalchemy.testing.suite.test_reflection import (
1✔
25
    BizarroCharacterTest as _BizarroCharacterTest,
26
)
27
from sqlalchemy.testing.suite.test_reflection import (
1✔
28
    ComponentReflectionTest as _ComponentReflectionTest,
29
)
30
from sqlalchemy.testing.suite.test_reflection import (
1✔
31
    ComponentReflectionTestExtra as _ComponentReflectionTestExtra,
32
)
33
from sqlalchemy.testing.suite.test_reflection import (
1✔
34
    IdentityReflectionTest as _IdentityReflectionTest,
35
)
36
from sqlalchemy.testing.suite.test_reflection import (
1✔
37
    TempTableElementsTest as _TempTableElementsTest,
38
)
39
from sqlalchemy.testing.suite.test_select import (
1✔
40
    IdentityColumnTest as _IdentityColumnTest,
41
)
42
from sqlalchemy.testing.suite.test_types import JSONTest as _JSONTest
1✔
43

44
# Import dialect test suite provided by SQLAlchemy into SQLAlchemy-HANA test collection.
45
# Please don't add other tests in this file. Only adjust or overview SQLAlchemy tests
46
# for compatibility with SAP HANA.
47

48

49
@temp_table_keyword_args.for_db("*")
×
50
def _temp_table_keyword_args(*args: Any, **kwargs: Any) -> dict[str, list[str]]:
×
51
    return {
1✔
52
        "prefixes": ["GLOBAL TEMPORARY"],
53
    }
54

55

56
class ComponentReflectionTestExtra(_ComponentReflectionTestExtra):
×
57
    @testing.combinations(
1✔
58
        ("CASCADE", None),
59
        (None, "SET NULL"),
60
        (None, "RESTRICT"),
61
        (None, "RESTRICT"),
62
        argnames="ondelete,onupdate",
63
    )
64
    def test_get_foreign_key_options(self, connection, metadata, ondelete, onupdate):
1✔
65
        options = {}
1✔
66
        if ondelete:
×
67
            options["ondelete"] = ondelete
1✔
68
        if onupdate:
1✔
69
            options["onupdate"] = onupdate
1✔
70

71
        options.setdefault("ondelete", "RESTRICT")
1✔
72
        options.setdefault("onupdate", "RESTRICT")
1✔
73

74
        Table(
1✔
75
            "x",
76
            metadata,
77
            Column("id", Integer, primary_key=True),
78
            test_needs_fk=True,
79
        )
80

81
        Table(
1✔
82
            "table",
83
            metadata,
84
            Column("id", Integer, primary_key=True),
85
            Column("x_id", Integer, ForeignKey("x.id", name="xid")),
86
            Column("test", String(10)),
87
            test_needs_fk=True,
88
        )
89

90
        Table(
1✔
91
            "user",
92
            metadata,
93
            Column("id", Integer, primary_key=True),
94
            Column("name", String(50), nullable=False),
95
            Column("tid", Integer),
96
            ForeignKeyConstraint(["tid"], ["table.id"], name="myfk", **options),
97
            test_needs_fk=True,
98
        )
99

100
        metadata.create_all(connection)
1✔
101

102
        insp = inspect(connection)
×
103

104
        # test 'options' is always present for a backend
105
        # that can reflect these, since alembic looks for this
106
        opts = insp.get_foreign_keys("table")[0]["options"]
×
107

108
        eq_(
1✔
109
            {k: opts[k] for k in opts if opts[k]},
110
            {"onupdate": "RESTRICT", "ondelete": "RESTRICT"},
111
        )
112

113
        opts = insp.get_foreign_keys("user")[0]["options"]
1✔
114
        eq_(opts, options)
×
115

116
    @testing.requires.table_reflection
1✔
117
    @testing.combinations(
1✔
118
        sql_types.String,
119
        sql_types.VARCHAR,
120
        sql_types.CHAR,
121
        (sql_types.NVARCHAR, testing.requires.nvarchar_types),
122
        (sql_types.NCHAR, testing.requires.nvarchar_types),
123
        argnames="type_",
124
    )
125
    def test_string_length_reflection(self, connection, metadata, type_):
1✔
126
        typ = self._type_round_trip(connection, metadata, type_(52))[0]
1✔
127
        if issubclass(type_, sql_types.VARCHAR):
×
128
            assert isinstance(typ, sql_types.VARCHAR | sql_types.NVARCHAR)
1✔
129
        elif issubclass(type_, sql_types.CHAR):
1✔
130
            assert isinstance(typ, sql_types.CHAR | sql_types.NCHAR)
1✔
131
        else:
132
            assert isinstance(typ, sql_types.String)
1✔
133

134
        eq_(typ.length, 52)
×
135
        assert isinstance(typ.length, int)
1✔
136

137

138
class ComponentReflectionTest(_ComponentReflectionTest):
1✔
139
    def _check_table_dict(self, result, exp, req_keys=None, make_lists=False):
×
140
        def _normalize(data):
×
141
            for entry in data.values():
1✔
142
                if isinstance(entry, list):
1✔
143
                    for subentry in entry:
1✔
144
                        if "sqltext" not in subentry:
1✔
145
                            continue
1✔
146
                        sqltext = subentry["sqltext"]
1✔
147
                        # ignore casing
148
                        sqltext = sqltext.lower()
1✔
149
                        # removes spaces because they are not consistent
150
                        sqltext = sqltext.replace(" ", "")
×
151
                        # remove quotes because they are not consistent
152
                        sqltext = sqltext.replace('"', "")
×
153
                        # remove a potential leading (
154
                        if sqltext.startswith("("):
×
155
                            sqltext = sqltext[1:]
1✔
156
                        # remove a potential closing )
157
                        if sqltext.endswith(")"):
1✔
158
                            sqltext = sqltext[:-1]
1✔
159
                        subentry["sqltext"] = sqltext
×
160

161
        _normalize(result)
1✔
162
        _normalize(exp)
1✔
163
        return super()._check_table_dict(result, exp, req_keys, make_lists)
×
164

165

166
class CTETest(_CTETest):
1✔
167
    def test_select_recursive_round_trip(self, connection):
×
168
        pytest.skip("Recursive CTEs are not supported by SAP HANA")
1✔
169

170
    def test_insert_from_select_round_trip(self, connection):
1✔
171
        pytest.skip("Insert CTEs are not supported by SAP HANA")
1✔
172

173

174
class IdentityReflectionTest(_IdentityReflectionTest):
1✔
175
    def test_reflect_identity(self, connection):
1✔
176
        pytest.skip("Identity column reflection is not supported")
1✔
177

178
    def test_reflect_identity_schema(self, connection):
1✔
179
        pytest.skip("Identity column reflection is not supported")
1✔
180

181

182
class IdentityColumnTest(_IdentityColumnTest):
1✔
183
    def test_insert_always_error(self, connection):
×
184
        def fn():
1✔
185
            connection.execute(
1✔
186
                self.tables.tbl_a.insert(),
187
                [{"id": 200, "desc": "a"}],
188
            )
189

190
        assert_raises((DBAPIError,), fn)
×
191

192

193
class JSONTest(_JSONTest):
×
194
    @classmethod
×
195
    def define_tables(cls, metadata):
1✔
196
        Table(
1✔
197
            "data_table",
198
            metadata,
199
            Column("id", Integer, autoincrement=True, primary_key=True),
200
            Column("name", String(30), nullable=False),
201
            Column("data", cls.datatype, nullable=False),
202
            Column("nulldata", cls.datatype(none_as_null=True)),
203
        )
204

205
    def test_index_typed_access(self):
1✔
206
        pytest.skip("Index typed access is not supported")
1✔
207

208
    def test_index_typed_comparison(self):
1✔
209
        pytest.skip("Index typed access is not supported")
×
210

211
    def test_path_typed_comparison(self):
1✔
212
        pytest.skip("Path typed access is not supported")
×
213

214

215
class BizarroCharacterTest(_BizarroCharacterTest):
1✔
216

217
    def test_reflect_identity(self):
1✔
218
        pytest.skip("Identity reflection is not supported")
1✔
219

220

221
class TempTableElementsTest(_TempTableElementsTest):
1✔
222

223
    def test_reflect_identity(self):
1✔
224
        pytest.skip("Identity reflection is not supported")
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc