cfquant 0.2.23__tar.gz → 0.2.24__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.
- {cfquant-0.2.23 → cfquant-0.2.24}/PKG-INFO +1 -1
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/_editable_install.py +28 -5
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/16_/345/220/257/345/212/250/345/256/211/350/243/205/346/265/213/350/257/225.py +17 -3
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_project_updater.py +1 -1
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/version.py +1 -1
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant.egg-info/PKG-INFO +1 -1
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant_web_server.py +2 -17
- {cfquant-0.2.23 → cfquant-0.2.24}/pyproject.toml +1 -1
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/app.js +4 -7
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/index.html +2 -2
- {cfquant-0.2.23 → cfquant-0.2.24}/LICENSE +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/LTtx/__init__.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/LTtx/tx/Config.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/LTtx/tx/LTtx_server.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/LTtx/tx/__init__.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/LTtx/tx/tx.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/MANIFEST.in +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/README.md +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/__init__.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/account_routing.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/batch_orders.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/cftrader.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/channels.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/cli.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/client.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/config.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/hub.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/level2.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/logging_i18n.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/normal_bridge.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/order_meta.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/pipe_bridge.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/pipe_client.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/pipe_hub.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/pipe_transport.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/protocol.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/qmt_bridge.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/qmt_strategy_deploy.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/qmt_strategy_package.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/qmt_strategy_runtime.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/runtime_report.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/10_/345/221/275/344/273/244/350/241/214/346/216/245/345/217/243/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/11_/346/231/256/351/200/232/346/241/245/346/216/245/346/264/276/345/217/221/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/12_/350/256/242/345/215/225/345/244/207/346/263/250/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/13_/347/256/241/351/201/223/344/270/255/345/277/203/350/277/236/346/216/245/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/14_/350/277/220/350/241/214/346/227/266/346/212/245/345/221/212/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/15_/347/275/221/351/241/265/347/212/266/346/200/201/347/274/223/345/255/230/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/17_/345/244/247QMT/346/216/245/345/217/243/351/200/202/351/205/215/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/18_/351/253/230/347/272/247/346/250/241/345/274/217/345/256/236/346/234/272/350/201/224/350/260/203.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/19_/345/256/236/346/234/272/350/201/224/350/260/203/345/210/244/345/256/232/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/1_/350/241/214/346/203/205/346/216/245/346/224/266/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/20_/350/201/224/350/260/203/351/227/256/351/242/230/344/277/256/345/244/215/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/21_/345/215/225/350/202/241/350/241/214/346/203/205/350/256/242/351/230/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/22_/350/277/236/346/216/245/350/257/212/346/226/255/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/23_/347/244/272/344/276/213/351/205/215/347/275/256/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/24_/350/264/246/346/210/267/347/274/223/345/255/230/346/214/211/351/234/200/345/210/267/346/226/260/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/25_/350/264/246/346/210/267/347/274/223/345/255/230/351/241/265/351/235/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/26_/345/205/250/346/216/250/350/256/242/351/230/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/27_/345/205/250/346/216/250/350/256/242/351/230/205/351/241/265/351/235/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/28_Level2/346/216/245/345/217/243/351/200/202/351/205/215/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/29_Level2/350/241/214/346/203/205/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/2_/346/225/260/346/215/256/350/216/267/345/217/226/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/30_cftrader/346/211/271/351/207/217/344/270/213/345/215/225/346/200/247/350/203/275/345/237/272/345/207/206.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/31_cftrader/346/250/241/346/213/237/350/264/246/345/217/267/346/211/271/351/207/217/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/3_/346/225/260/346/215/256/344/270/213/350/275/275/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/4_/344/272/244/346/230/223/345/247/224/346/211/230/346/237/245/350/257/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/5_/347/234/237/345/256/236/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/6_/345/233/236/350/260/203/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/7_/345/220/214/346/255/245/345/274/202/346/255/245/344/270/213/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/8_/346/210/220/344/272/244/350/256/242/345/215/225/345/222/214/345/247/224/346/211/230/350/256/242/345/215/225/346/237/245/350/257/242/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/9_/345/217/257/346/222/244/350/256/242/345/215/225/346/265/213/350/257/225.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/_helpers.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/log/cftrader/346/250/241/346/213/237/350/264/246/345/217/267/346/211/271/351/207/217/344/270/213/345/215/225/346/265/213/350/257/225_20260911_024617.md" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/readme.md +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_api_tester_browser.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_api_tester_web.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_binding_delete_confirmation.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_cftrader.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_cftrader_tutorial.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_cftrader_web.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_credit_compat.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_json_serialization.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_python_api_reference.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_qmt_strategy_browser.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_qmt_strategy_deploy.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_qmt_strategy_web.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_tutorial_reader.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tests/test_tx_auto_import.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tx.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/tx_trade_bridge.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/xtconstant.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/xtdata.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/xttrader.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant/xttype.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant.egg-info/SOURCES.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant.egg-info/dependency_links.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant.egg-info/entry_points.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant.egg-info/requires.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant.egg-info/top_level.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/cfquant_pipe_hub.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts/CFQUANT.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts/CFQUANT_LITE.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts/CFQUANT_TRADE_LOWLAT.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts/__init__.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_CTYPE_ALL_LOWLAT_SH.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_CTYPE_ALL_LOWLAT_SZ.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_LITE_SH.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_LITE_SZ.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_TRADE_LOWLAT_SH.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/CFQUANT_TRADE_LOWLAT_SZ.py" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/qmt_scripts//345/220/214/350/264/246/345/217/267/347/213/254/347/253/213/345/270/202/345/234/272/readme.md" +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/requirements.txt +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/setup.cfg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/__init__.py +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/api-tester.js +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/amber-pulse.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/copper-grid.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/market-blue.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/rose-circuit.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/signal-green.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/slate-wave.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/teal-orbit.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/avatars/violet-node.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/cftrader-api-data.js +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/favicon.svg +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-10.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-11.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-12.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-13.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-14.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-15.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-16.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-17.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-18.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-19.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-20.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-21.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-4.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-5.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-6.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-7.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-8.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/image/qmt_deploy/image-9.png +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/python-api-data.js +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/python-api.js +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/styles.css +0 -0
- {cfquant-0.2.23 → cfquant-0.2.24}/web_dashboard/vendor/mermaid.min.js +0 -0
|
@@ -451,6 +451,27 @@ def is_cfquant_installed(python_exe=None):
|
|
|
451
451
|
return completed.returncode == 0
|
|
452
452
|
|
|
453
453
|
|
|
454
|
+
def project_package_version(project_root):
|
|
455
|
+
try:
|
|
456
|
+
import tomllib
|
|
457
|
+
except ImportError:
|
|
458
|
+
from pip._vendor import tomli as tomllib
|
|
459
|
+
with (Path(project_root) / "pyproject.toml").open("rb") as stream:
|
|
460
|
+
return str(tomllib.load(stream)["project"]["version"])
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def installed_package_version(python_exe=None):
|
|
464
|
+
completed = subprocess.run(
|
|
465
|
+
[python_exe or sys.executable, "-c",
|
|
466
|
+
"from importlib.metadata import version; print(version('cfquant'))"],
|
|
467
|
+
cwd=str(neutral_check_cwd()),
|
|
468
|
+
env=python_environment(clear_pythonpath=True),
|
|
469
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
470
|
+
text=True, encoding="utf-8", timeout=30,
|
|
471
|
+
)
|
|
472
|
+
return completed.stdout.strip() if completed.returncode == 0 else ""
|
|
473
|
+
|
|
474
|
+
|
|
454
475
|
def ensure_cfquant_installed(project_root, python_exe=None):
|
|
455
476
|
project_root = Path(project_root).resolve()
|
|
456
477
|
if not (project_root / "pyproject.toml").is_file():
|
|
@@ -458,9 +479,11 @@ def ensure_cfquant_installed(project_root, python_exe=None):
|
|
|
458
479
|
return 2
|
|
459
480
|
|
|
460
481
|
python_exe = python_exe or sys.executable
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
482
|
+
expected = project_package_version(project_root)
|
|
483
|
+
installed = installed_package_version(python_exe)
|
|
484
|
+
print("cfquant installed=%s project=%s" % (installed or "missing", expected))
|
|
485
|
+
if installed == expected:
|
|
486
|
+
print("Package versions match; skip installation.")
|
|
464
487
|
return 0
|
|
465
488
|
|
|
466
489
|
command = editable_install_args(project_root, python_exe)
|
|
@@ -480,8 +503,8 @@ def ensure_cfquant_installed(project_root, python_exe=None):
|
|
|
480
503
|
print("[ERROR] source install failed with exit code %s." % completed.returncode, file=sys.stderr)
|
|
481
504
|
return completed.returncode
|
|
482
505
|
|
|
483
|
-
if
|
|
484
|
-
print("[ERROR]
|
|
506
|
+
if installed_package_version(python_exe) != expected:
|
|
507
|
+
print("[ERROR] Installed cfquant version does not match the project after installation.", file=sys.stderr)
|
|
485
508
|
return 1
|
|
486
509
|
print("%s package is installed." % PACKAGE_NAME)
|
|
487
510
|
return 0
|
|
@@ -292,8 +292,8 @@ def test_run_editable_install_falls_back_to_source_install(monkeypatch, tmp_path
|
|
|
292
292
|
|
|
293
293
|
|
|
294
294
|
def test_ensure_cfquant_installed_falls_back_to_source_install(monkeypatch, tmp_path):
|
|
295
|
-
(tmp_path / "pyproject.toml").write_text("[project]\nname = 'cfquant'\n", encoding="utf-8")
|
|
296
|
-
installed_checks = [
|
|
295
|
+
(tmp_path / "pyproject.toml").write_text("[project]\nname = 'cfquant'\nversion = '0.2.23'\n", encoding="utf-8")
|
|
296
|
+
installed_checks = ["0.2.22", "0.2.23"]
|
|
297
297
|
calls = []
|
|
298
298
|
|
|
299
299
|
def fake_is_installed(python_exe=None):
|
|
@@ -309,7 +309,7 @@ def test_ensure_cfquant_installed_falls_back_to_source_install(monkeypatch, tmp_
|
|
|
309
309
|
result.returncode = 7 if "--editable" in args else 0
|
|
310
310
|
return result
|
|
311
311
|
|
|
312
|
-
monkeypatch.setattr(_editable_install, "
|
|
312
|
+
monkeypatch.setattr(_editable_install, "installed_package_version", fake_is_installed)
|
|
313
313
|
monkeypatch.setattr(_editable_install, "run", fake_run)
|
|
314
314
|
|
|
315
315
|
assert _editable_install.ensure_cfquant_installed(tmp_path, python_exe="python") == 0
|
|
@@ -318,6 +318,20 @@ def test_ensure_cfquant_installed_falls_back_to_source_install(monkeypatch, tmp_
|
|
|
318
318
|
assert calls[1][0][-1] == "."
|
|
319
319
|
|
|
320
320
|
|
|
321
|
+
@pytest.mark.parametrize("installed", ["", "0.2.22", "0.2.24", "0.2.23"])
|
|
322
|
+
def test_startup_installs_only_when_version_differs(monkeypatch, tmp_path, installed):
|
|
323
|
+
(tmp_path / "pyproject.toml").write_text("[project]\nversion='0.2.23'\n", encoding="utf-8")
|
|
324
|
+
versions = iter([installed, "0.2.23"])
|
|
325
|
+
monkeypatch.setattr(_editable_install, "installed_package_version", lambda exe: next(versions))
|
|
326
|
+
calls = []
|
|
327
|
+
def install(args, cwd):
|
|
328
|
+
calls.append(args)
|
|
329
|
+
return subprocess.CompletedProcess(args, 0)
|
|
330
|
+
monkeypatch.setattr(_editable_install, "run", install)
|
|
331
|
+
assert _editable_install.ensure_cfquant_installed(tmp_path, "python") == 0
|
|
332
|
+
assert len(calls) == (0 if installed == "0.2.23" else 1)
|
|
333
|
+
|
|
334
|
+
|
|
321
335
|
def test_start_script_passes_dot_not_trailing_dp0():
|
|
322
336
|
script = (Path(__file__).resolve().parents[2] / "start_cfquant.bat").read_text(encoding="utf-8")
|
|
323
337
|
|
|
@@ -36,7 +36,7 @@ def project_updater(tmp_path, monkeypatch):
|
|
|
36
36
|
monkeypatch.setattr(
|
|
37
37
|
updater,
|
|
38
38
|
"_run_editable_install",
|
|
39
|
-
lambda reason:
|
|
39
|
+
lambda reason: pytest.fail("Web updates must not run pip"),
|
|
40
40
|
)
|
|
41
41
|
monkeypatch.setattr(updater, "_require_editable_install", lambda result: None)
|
|
42
42
|
return web, updater, project_root
|
|
@@ -9038,18 +9038,11 @@ class CfquantProjectUpdater(object):
|
|
|
9038
9038
|
try:
|
|
9039
9039
|
self._set_operation_phase("restore", "正在恢复选中的项目版本")
|
|
9040
9040
|
self._restore_backup(selected)
|
|
9041
|
-
|
|
9042
|
-
editable_install = self._run_editable_install("project_rollback")
|
|
9043
|
-
self._require_editable_install(editable_install)
|
|
9041
|
+
editable_install = {"deferred": True, "attempted": False}
|
|
9044
9042
|
self._set_operation_phase("deploy", "正在同步回滚后的 cfquant 核心到 QMT 目录")
|
|
9045
9043
|
qmt_core_deploy = auto_deploy_qmt_core_for_all_accounts(source_dir=BASE_DIR)
|
|
9046
9044
|
except Exception:
|
|
9047
9045
|
self._restore_backup(rollback_backup)
|
|
9048
|
-
try:
|
|
9049
|
-
recovery_install = self._run_editable_install("project_rollback_recovery")
|
|
9050
|
-
self._require_editable_install(recovery_install)
|
|
9051
|
-
except Exception as recovery_error:
|
|
9052
|
-
safe_print("project rollback editable install recovery failed: %s" % recovery_error)
|
|
9053
9046
|
raise
|
|
9054
9047
|
self._write_rollback_meta(
|
|
9055
9048
|
selected,
|
|
@@ -9113,9 +9106,7 @@ class CfquantProjectUpdater(object):
|
|
|
9113
9106
|
shutil.copy2(src, dst)
|
|
9114
9107
|
copied.append(rel_path)
|
|
9115
9108
|
entry_info = self._entry_update_info(changed)
|
|
9116
|
-
|
|
9117
|
-
editable_install = self._run_editable_install("project_update")
|
|
9118
|
-
self._require_editable_install(editable_install)
|
|
9109
|
+
editable_install = {"deferred": True, "attempted": False}
|
|
9119
9110
|
self._set_operation_phase("deploy", "正在同步最新 cfquant 核心到 QMT 目录")
|
|
9120
9111
|
qmt_core_deploy = auto_deploy_qmt_core_for_all_accounts(source_dir=BASE_DIR)
|
|
9121
9112
|
qmt_deploy_summary = qmt_core_deploy.get("summary") or {}
|
|
@@ -9156,12 +9147,6 @@ class CfquantProjectUpdater(object):
|
|
|
9156
9147
|
}
|
|
9157
9148
|
except Exception:
|
|
9158
9149
|
self._restore_backup(backup)
|
|
9159
|
-
if editable_install and editable_install.get("attempted"):
|
|
9160
|
-
try:
|
|
9161
|
-
recovery_install = self._run_editable_install("project_update_recovery")
|
|
9162
|
-
self._require_editable_install(recovery_install)
|
|
9163
|
-
except Exception as recovery_error:
|
|
9164
|
-
safe_print("project update editable install recovery failed: %s" % recovery_error)
|
|
9165
9150
|
raise
|
|
9166
9151
|
|
|
9167
9152
|
def _run_editable_install(self, reason):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const FRONTEND_VERSION = '
|
|
1
|
+
const FRONTEND_VERSION = 'web_20260917_03';
|
|
2
2
|
|
|
3
3
|
const state = {
|
|
4
4
|
accountId: '',
|
|
@@ -5466,8 +5466,7 @@ function qmtUpdateProgressSteps(kind) {
|
|
|
5466
5466
|
{ key: 'upload', label: '上传项目源码 zip', percent: 42 },
|
|
5467
5467
|
{ key: 'backup', label: '备份当前 Web 项目', percent: 58 },
|
|
5468
5468
|
{ key: 'install', label: '替换 Web 项目文件', percent: 82 },
|
|
5469
|
-
{ key: '
|
|
5470
|
-
{ key: 'restart', label: '重启 Web 服务', percent: 94 },
|
|
5469
|
+
{ key: 'restart', label: '重启并检查 SDK 版本', percent: 94 },
|
|
5471
5470
|
{ key: 'done', label: '更新完成', percent: 100 },
|
|
5472
5471
|
];
|
|
5473
5472
|
}
|
|
@@ -5476,8 +5475,7 @@ function qmtUpdateProgressSteps(kind) {
|
|
|
5476
5475
|
{ key: 'prepare', label: '确认 Web 回滚目标', percent: 12 },
|
|
5477
5476
|
{ key: 'backup', label: '备份当前 Web 项目', percent: 36 },
|
|
5478
5477
|
{ key: 'restore', label: '恢复选中备份', percent: 76 },
|
|
5479
|
-
{ key: '
|
|
5480
|
-
{ key: 'restart', label: '重启 Web 服务', percent: 94 },
|
|
5478
|
+
{ key: 'restart', label: '重启并检查 SDK 版本', percent: 94 },
|
|
5481
5479
|
{ key: 'done', label: '回滚完成', percent: 100 },
|
|
5482
5480
|
];
|
|
5483
5481
|
}
|
|
@@ -5487,8 +5485,7 @@ function qmtUpdateProgressSteps(kind) {
|
|
|
5487
5485
|
{ key: 'download', label: '连接官网并下载发布包', percent: 38 },
|
|
5488
5486
|
{ key: 'backup', label: '备份当前 Web 项目', percent: 58 },
|
|
5489
5487
|
{ key: 'install', label: '替换 Web 项目文件', percent: 82 },
|
|
5490
|
-
{ key: '
|
|
5491
|
-
{ key: 'restart', label: '重启 Web 服务', percent: 94 },
|
|
5488
|
+
{ key: 'restart', label: '重启并检查 SDK 版本', percent: 94 },
|
|
5492
5489
|
{ key: 'done', label: '更新完成', percent: 100 },
|
|
5493
5490
|
];
|
|
5494
5491
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>cfquant 控制台</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
8
|
-
<link rel="stylesheet" href="/styles.css?v=
|
|
8
|
+
<link rel="stylesheet" href="/styles.css?v=web_20260917_03">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="webAuthOverlay" class="auth-overlay hidden" aria-live="polite">
|
|
@@ -3176,6 +3176,6 @@ else:
|
|
|
3176
3176
|
<script src="/cftrader-api-data.js?v=20260911_02"></script>
|
|
3177
3177
|
<script src="/api-tester.js?v=20260916_apikey_01"></script>
|
|
3178
3178
|
<script src="/python-api.js?v=20260911_api_test_01"></script>
|
|
3179
|
-
<script src="/app.js?v=
|
|
3179
|
+
<script src="/app.js?v=web_20260917_03"></script>
|
|
3180
3180
|
</body>
|
|
3181
3181
|
</html>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|