quantpad-data 0.3.0__tar.gz → 0.3.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.
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/PKG-INFO +1 -1
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/pyproject.toml +1 -1
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/quantpad_data/client.py +2 -2
- quantpad_data-0.3.1/tests/test_message_encoding.py +85 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/.gitignore +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/README.md +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/quantpad_data/errors.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/quantpad_data/lean.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/quantpad_data/py.typed +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/quantpad_data/v2.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/tests/test_client.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/tests/test_lean.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/tests/test_v2.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/tests/test_v2_gate.py +0 -0
- {quantpad_data-0.3.0 → quantpad_data-0.3.1}/tests/test_version.py +0 -0
|
@@ -57,7 +57,7 @@ _V2_GATE_REPLIES = frozenset(
|
|
|
57
57
|
)
|
|
58
58
|
|
|
59
59
|
V2_NOT_AVAILABLE = (
|
|
60
|
-
"The /v2 API is not open yet. Your credentials are fine
|
|
60
|
+
"The /v2 API is not open yet. Your credentials are fine - /v2 is "
|
|
61
61
|
"limited to a small allowlist while it is finished, so qpd.v2 and "
|
|
62
62
|
"qpd.Historical will not work for you regardless of what you pass "
|
|
63
63
|
"them. The documented /v1 helpers (get_bars, get_ticks, get_universe, "
|
|
@@ -65,7 +65,7 @@ V2_NOT_AVAILABLE = (
|
|
|
65
65
|
"data. Contact QuantPad support if you need /v2 access."
|
|
66
66
|
)
|
|
67
67
|
|
|
68
|
-
VERSION = "0.3.
|
|
68
|
+
VERSION = "0.3.1"
|
|
69
69
|
USER_AGENT = f"quantpad-data-python/{VERSION}"
|
|
70
70
|
TICK_SCHEMAS = (
|
|
71
71
|
"trades", "mbp-1", "mbp-10", "cmbp-1", "tcbbo", "cbbo-1s",
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Runtime strings stay ASCII, because they are read on real terminals.
|
|
2
|
+
|
|
3
|
+
Found by running the SDK against production and watching the em-dash in
|
|
4
|
+
``V2_NOT_AVAILABLE`` come back as a replacement character on a Windows
|
|
5
|
+
console. The message exists to be legible; a message that renders as
|
|
6
|
+
mojibake on a chunk of our users' terminals is not doing its job, and
|
|
7
|
+
the irony of it being the "here is what actually went wrong" string was
|
|
8
|
+
the tell.
|
|
9
|
+
|
|
10
|
+
Scoped to runtime string *literals*. Docstrings and comments are read in
|
|
11
|
+
an editor and keep their typography.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import ast
|
|
17
|
+
import pathlib
|
|
18
|
+
|
|
19
|
+
import pytest
|
|
20
|
+
|
|
21
|
+
PACKAGE = pathlib.Path(__file__).resolve().parent.parent / "quantpad_data"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _runtime_strings(path: pathlib.Path):
|
|
25
|
+
"""Every string constant that is not a docstring, with its line."""
|
|
26
|
+
tree = ast.parse(path.read_text(encoding="utf-8"))
|
|
27
|
+
docstrings = set()
|
|
28
|
+
for node in ast.walk(tree):
|
|
29
|
+
if isinstance(
|
|
30
|
+
node, (ast.Module, ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)
|
|
31
|
+
):
|
|
32
|
+
text = ast.get_docstring(node, clean=False)
|
|
33
|
+
if text:
|
|
34
|
+
docstrings.add(text)
|
|
35
|
+
for node in ast.walk(tree):
|
|
36
|
+
if isinstance(node, ast.Constant) and isinstance(node.value, str):
|
|
37
|
+
if node.value not in docstrings:
|
|
38
|
+
yield node.lineno, node.value
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.mark.parametrize(
|
|
42
|
+
"module", sorted(PACKAGE.rglob("*.py")), ids=lambda p: p.name
|
|
43
|
+
)
|
|
44
|
+
def test_no_runtime_string_needs_a_utf8_terminal(module: pathlib.Path):
|
|
45
|
+
offenders = [
|
|
46
|
+
(line, sorted({c for c in value if ord(c) > 127}), value[:60])
|
|
47
|
+
for line, value in _runtime_strings(module)
|
|
48
|
+
if any(ord(c) > 127 for c in value)
|
|
49
|
+
]
|
|
50
|
+
assert not offenders, (
|
|
51
|
+
f"{module.name} has runtime strings that need a UTF-8 terminal: "
|
|
52
|
+
f"{offenders}. Use ASCII - these are printed to consoles we do "
|
|
53
|
+
f"not control."
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_the_check_can_actually_see_a_violation():
|
|
58
|
+
"""A guard that passes on everything is not a guard.
|
|
59
|
+
|
|
60
|
+
The trap this repo keeps hitting: a diagnostic built to confirm a
|
|
61
|
+
change will confirm it. So prove the detector fires.
|
|
62
|
+
"""
|
|
63
|
+
source = 'X = "an em dash \u2014 here"\n'
|
|
64
|
+
tree = ast.parse(source)
|
|
65
|
+
found = [
|
|
66
|
+
n.value
|
|
67
|
+
for n in ast.walk(tree)
|
|
68
|
+
if isinstance(n, ast.Constant) and isinstance(n.value, str)
|
|
69
|
+
]
|
|
70
|
+
assert any(any(ord(c) > 127 for c in v) for v in found)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_prose_is_deliberately_exempt():
|
|
74
|
+
"""The scoping is the whole design, so pin it both ways.
|
|
75
|
+
|
|
76
|
+
``client.py`` is full of em-dashes in comments and docstrings and
|
|
77
|
+
must stay passing. If the check ever widens to the raw file, that is
|
|
78
|
+
a false positive on prose nobody prints.
|
|
79
|
+
"""
|
|
80
|
+
source = (PACKAGE / "client.py").read_text(encoding="utf-8")
|
|
81
|
+
assert "\u2014" in source, "expected this module's prose to use em-dashes"
|
|
82
|
+
|
|
83
|
+
runtime = [v for _, v in _runtime_strings(PACKAGE / "client.py")]
|
|
84
|
+
assert runtime, "parser returned nothing - it would pass vacuously"
|
|
85
|
+
assert not [v for v in runtime if any(ord(c) > 127 for c in v)]
|
|
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
|