Compare commits
9
Commits
2f3fc78f7f
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
502d8b6b5a | ||
|
|
47bef84e7b | ||
|
|
9b6450fcbb | ||
|
|
309667e82b | ||
|
|
195605826f | ||
|
|
e569b3481c | ||
|
|
f0547208ed | ||
|
|
eef434acf7 | ||
|
|
7a625d50fc |
@@ -1,6 +1,6 @@
|
|||||||
# 流行音樂中「女性力量」語彙的挪用與污染——以 Billboard Year-End Hot 100(2016-2025)為例的內容分析
|
# 流行音樂中「女性力量」語彙的挪用與污染——以 Billboard Year-End Hot 100(2016-2025)為例的內容分析
|
||||||
|
|
||||||
這是研究論文《流行音樂中「女性力量」語彙的挪用與污染——以 Billboard Year-End Hot 100(2016-2025)為例的內容分析》的專案資料,包括論文本身、文件、紀錄、資料、工具程式、AI提示詞,等等。
|
這是研究論文《流行音樂中「女性力量」語彙的挪用與污染——以 Billboard Year-End Hot 100(2016-2025)為例的內容分析》的專案資料,包括論文本身、文件、紀錄、資料、工具程式、LLM提示詞,等等。
|
||||||
|
|
||||||
## 論文和摘要
|
## 論文和摘要
|
||||||
|
|
||||||
@@ -10,9 +10,17 @@
|
|||||||
|
|
||||||
研究方法、記錄等文件,請參閱 docs/ 資料夾。
|
研究方法、記錄等文件,請參閱 docs/ 資料夾。
|
||||||
|
|
||||||
|
## LLM提示
|
||||||
|
|
||||||
|
LLM提示請參閱 prompts/ 資料夾。
|
||||||
|
|
||||||
## 輔助工具程式
|
## 輔助工具程式
|
||||||
|
|
||||||
輔助工具程式,請參閱 tools/ 資料夾。
|
輔助工具程式請參閱 tools/ 資料夾。
|
||||||
|
|
||||||
|
## 研究資料
|
||||||
|
|
||||||
|
研究資料請參閱 data/ 資料夾。
|
||||||
|
|
||||||
## 授權
|
## 授權
|
||||||
|
|
||||||
|
|||||||
|
Can't render this file because it is too large.
|
+9
-6
@@ -31,11 +31,11 @@ agent 不得見之)。凡於本專案工作的主會話,動手管線、
|
|||||||
不符預期時,修訂定義檔並重複該循環;絕不手改結果。
|
不符預期時,修訂定義檔並重複該循環;絕不手改結果。
|
||||||
- 一步的每次執行皆自我完備歸檔於 `run-llm` 命令列上
|
- 一步的每次執行皆自我完備歸檔於 `run-llm` 命令列上
|
||||||
明示指定的目的目錄下(慣例為
|
明示指定的目的目錄下(慣例為
|
||||||
`runs/<步驟>/run<N>/`):定義檔快照、原始輸出與
|
`data/runs/<步驟>/run<N>/`):定義檔快照、原始輸出與
|
||||||
`meta.json`(model ID、參數、時間戳、batch ID)。
|
`meta.json`(model ID、參數、時間戳、batch ID)。
|
||||||
一步的 N 次執行即 N 次各自的 `run-llm` 呼叫。覆蓋
|
一步的 N 次執行即 N 次各自的 `run-llm` 呼叫。覆蓋
|
||||||
既有執行歸檔須明示旗標;被取代的執行留在 git 歷史。
|
既有執行歸檔須明示旗標;被取代的執行留在 git 歷史。
|
||||||
確定性步驟歸檔於 `runs/<步驟>/`,不分 `run<N>` 層。
|
確定性步驟歸檔於 `data/runs/<步驟>/`,不分 `run<N>` 層。
|
||||||
- 每次 `run-llm` 執行的 token 用量與費用記入
|
- 每次 `run-llm` 執行的 token 用量與費用記入
|
||||||
`docs/run-costs.md`,與執行歸檔同一 commit。
|
`docs/run-costs.md`,與執行歸檔同一 commit。
|
||||||
- 腳本自環境變數 `ANTHROPIC_API_KEY` 讀取 API key
|
- 腳本自環境變數 `ANTHROPIC_API_KEY` 讀取 API key
|
||||||
@@ -46,19 +46,22 @@ agent 不得見之)。凡於本專案工作的主會話,動手管線、
|
|||||||
- `data/source/` 存手放後不動的原始檔;
|
- `data/source/` 存手放後不動的原始檔;
|
||||||
`data/captures/` 只由 fetch 命令與私人匯入腳本
|
`data/captures/` 只由 fetch 命令與私人匯入腳本
|
||||||
寫入;`data/manual/` 只由研究者親手寫入;
|
寫入;`data/manual/` 只由研究者親手寫入;
|
||||||
`data/derived/` 只由 `build-db` 子命令寫入。
|
`data/derived/` 只由 `build-db` 子命令寫入;
|
||||||
|
`data/runs/` 存 LLM 執行的原始歸檔,只由執行程序
|
||||||
|
寫入;`data/results/` 存論文引用的定案表,只由
|
||||||
|
計票程序寫入。
|
||||||
- 歌詞全文有版權:一律置於 `data/captures/lyrics/`
|
- 歌詞全文有版權:一律置於 `data/captures/lyrics/`
|
||||||
(gitignored),絕不 commit,亦絕不於 repo 任何處
|
(gitignored),絕不 commit,亦絕不於 repo 任何處
|
||||||
全文重現。
|
全文重現。
|
||||||
|
|
||||||
## 文件
|
## 文件
|
||||||
|
|
||||||
- `results/` 存計票後的定案表(論文所引);`runs/` 存
|
- `data/results/` 存計票後的定案表(論文所引);
|
||||||
原始稽核紀錄。論文只引 `results/`。
|
`data/runs/` 存原始稽核紀錄。論文只引 `data/results/`。
|
||||||
- **Commit 判準**:凡能由「committed 的輸入+committed
|
- **Commit 判準**:凡能由「committed 的輸入+committed
|
||||||
的程式」決定性再生者不 commit;凡不能者一律以文字
|
的程式」決定性再生者不 commit;凡不能者一律以文字
|
||||||
格式 commit,格式跟著上文「資料規則」一節所定的
|
格式 commit,格式跟著上文「資料規則」一節所定的
|
||||||
層次走。例外:`results/` 定案表與
|
層次走。例外:`data/results/` 定案表與
|
||||||
`data/derived/` 人讀報表雖可再生仍 commit——理由是
|
`data/derived/` 人讀報表雖可再生仍 commit——理由是
|
||||||
引用穩定性、審稿人零門檻、撰稿期數字變動可 diff;
|
引用穩定性、審稿人零門檻、撰稿期數字變動可 diff;
|
||||||
兩者皆與工作儲存同一動作產出,稽核鏈無中間空缺。
|
兩者皆與工作儲存同一動作產出,稽核鏈無中間空缺。
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# LLM 輸出的契約查核
|
# LLM 輸出的契約查核
|
||||||
|
|
||||||
(2026-08-06 量測。對象為步驟 3 的三份執行歸檔
|
(2026-08-06 量測。對象為步驟 3 的三份執行歸檔
|
||||||
`runs/3a-code/run1`–`run3`,共 883 首歌、44,149 筆標籤
|
`data/runs/3a-code/run1`–`run3`,共 883 首歌、44,149 筆標籤
|
||||||
指派、44,146 句引述。歌詞以模型實際看到的那一份為準,即
|
指派、44,146 句引述。歌詞以模型實際看到的那一份為準,即
|
||||||
`tools/instance/llm-input-code.jsonl`。)
|
`tools/instance/llm-input-code.jsonl`。)
|
||||||
|
|
||||||
|
|||||||
+14
-29
@@ -42,52 +42,37 @@ frame-aware 提示修正實驗,均由當時協作的 Claude Code 設計並
|
|||||||
研究問題。
|
研究問題。
|
||||||
- **粒度選擇**:正式研究鎖定 thematic keywords 這一粒度,
|
- **粒度選擇**:正式研究鎖定 thematic keywords 這一粒度,
|
||||||
係繼承先導研究三種粒度的比較結果(keywords 過碎、themes
|
係繼承先導研究三種粒度的比較結果(keywords 過碎、themes
|
||||||
過早抽象),且於執行前鎖定以防事後擇優。
|
過早抽象)。
|
||||||
- **`women-power` 一詞的來歷**:考據先導研究的 local agent
|
- **`women-power` 一詞的來歷**:考據先導研究的 local agent
|
||||||
存檔可知,其第一步指令含數十個範例 thematic keywords,
|
存檔可知,其第一步指令含數十個範例 thematic keywords,
|
||||||
其中即有 women-power——為當時協作的 Claude Code 依研究者
|
其中即有 women-power——為當時協作的 Claude Code 依研究者
|
||||||
長期表達的關注主動加入(研究者端播種,非明示指定);先導
|
長期表達的關注主動加入(研究者端播種,非明示指定);先導
|
||||||
的標籤 `women-power-and-empowerment` 則是第三步強制合併
|
的標籤 `women-power-and-empowerment` 則是第三步強制合併
|
||||||
兩個關鍵字的管線人工產物。正式研究的探針因此指向被播種的
|
兩個關鍵字的管線人工產物(見 `decision-log.md` 2026-08-04
|
||||||
本詞 `women-power`,不用合併假影(見 `decision-log.md`
|
條)。
|
||||||
2026-08-04 條)。**附帶認清:先導第一步並非零語意提示,
|
|
||||||
此即正式研究「提示詞只定格式、不定語意」設計所矯正者。**
|
|
||||||
- **簿記容量的教訓**:先導研究九百餘詞可以在單一回應內完成
|
- **簿記容量的教訓**:先導研究九百餘詞可以在單一回應內完成
|
||||||
分組,正式研究的關鍵字規模已非此法所能及,詞彙表遂改由
|
分組;此法未沿用,詞彙表改由確定性程序產生(見
|
||||||
確定性程序產生(見 `decision-log.md` 2026-08-06 條)。
|
`decision-log.md` 2026-08-06 條)。
|
||||||
|
|
||||||
## 四、被棄用的成果
|
## 四、被棄用的成果
|
||||||
|
|
||||||
以下先導研究的產物未進入正式研究,論文亦未引用:
|
以下先導研究的產物未進入正式研究,論文亦未引用:
|
||||||
|
|
||||||
- **genuine/peripheral/fake 三分類與「44% 假女性力量」**:
|
- **genuine/peripheral/fake 三分類與「44% 假女性力量」**:
|
||||||
構念與分母皆與正式研究不同(正式研究為 145 首女性力量群
|
構念與分母均未經稽核回溯,未沿用。
|
||||||
歌曲中 111 首有性別問題),兩者不可對讀。
|
- **五種「假女性力量」類型(A–E)**:未沿用。
|
||||||
- **五種「假女性力量」類型(A–E)**:正式研究改由儀器分三個
|
- **pussy 一詞的修辭分類**:未沿用。
|
||||||
發話脈絡各自歸納,得 43 條問題樣態(`results/patterns.csv`)。
|
|
||||||
- **pussy 一詞的修辭分類**:正式研究範圍收斂至語彙的挪用與
|
|
||||||
污染,未納入。
|
|
||||||
- **frame-aware(框架感知)提示修正法**:先導研究以框架判準
|
- **frame-aware(框架感知)提示修正法**:先導研究以框架判準
|
||||||
寫進提示以提高準確率;正式研究刻意不定義編碼,因為研究
|
寫進提示以提高準確率;未沿用。
|
||||||
對象正是 LLM 未受引導的自然編碼——把框架寫進提示,即無法
|
- **三個獨立 LLM subagent+人工仲裁的流程**:未沿用,原因見
|
||||||
再以其輸出為批判對象。兩者的設計方向相反,故未沿用。
|
`decision-log.md` 2026-07-30 條。
|
||||||
- **三個獨立 LLM subagent+人工仲裁的流程**:正式研究改以
|
|
||||||
Anthropic API 逐首獨立呼叫,原因見 `decision-log.md`
|
|
||||||
2026-07-30 條。
|
|
||||||
|
|
||||||
## 五、它如何促成正式研究的設計
|
## 五、它促成了可稽核的設計
|
||||||
|
|
||||||
先導研究的根本限制不在結論對錯,而在**不可稽核**:沒有定義檔
|
先導研究的根本限制不在結論對錯,而在**不可稽核**:沒有定義檔
|
||||||
快照、沒有原始輸出歸檔、沒有參數紀錄,因此任何一個數字都無法
|
快照、沒有原始輸出歸檔、沒有參數紀錄,因此任何一個數字都無法
|
||||||
回溯到產生它的那一次執行。正式研究的幾項設計正是針對這一點:
|
回溯到產生它的那一次執行。正式研究的可稽核設計,正是針對這一點
|
||||||
|
而立。
|
||||||
- 所有 LLM 步驟改以 API script 執行,每次執行自我完備歸檔於
|
|
||||||
`runs/`;
|
|
||||||
- 可逐項機械比對的判斷採三次執行+多數決,並量測其穩定性
|
|
||||||
(見 `reliability.md`);
|
|
||||||
- 定義檔只規定任務形狀,不給主題定義、判準或範例;
|
|
||||||
- 每一筆編碼必附歌詞引述,供逐筆查核;
|
|
||||||
- 輸出的契約遵從另行查核(見 `output-validation.md`)。
|
|
||||||
|
|
||||||
換言之,正式研究對 LLM 輸出所採取的「不信任、須查核」立場,
|
換言之,正式研究對 LLM 輸出所採取的「不信任、須查核」立場,
|
||||||
其第一個案例就是先導研究本身。
|
其第一個案例就是先導研究本身。
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
# Authors:
|
# Authors:
|
||||||
# imacat@mail.imacat.idv.tw (imacat), 2026/7/31
|
# imacat@mail.imacat.idv.tw (imacat), 2026/7/31
|
||||||
|
|
||||||
# The SQLAlchemy database URL.
|
# The SQLAlchemy database URI.
|
||||||
SQLALCHEMY_DATABASE_URL="postgresql://user:password@host/db"
|
SQLALCHEMY_DATABASE_URI="postgresql://user:password@host/db"
|
||||||
# The Anthropic API key
|
# The Anthropic API key
|
||||||
ANTHROPIC_API_KEY=sk-ant-...
|
ANTHROPIC_API_KEY=sk-ant-...
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Change Log
|
||||||
|
==========
|
||||||
|
|
||||||
|
|
||||||
|
version 1.0.0
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Released 2026/8/19
|
||||||
|
|
||||||
|
Initial release.
|
||||||
@@ -13,6 +13,8 @@ This is a collection of supporting tools for the conference paper "流行音樂
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
|
changelog
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
==================
|
==================
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
"""Tools for A Feminist Audit of Pop Music."""
|
"""Tools for A Feminist Audit of Pop Music."""
|
||||||
|
|
||||||
|
|
||||||
VERSION: str = "0.0.0"
|
VERSION: str = "1.0.0"
|
||||||
"""The package version."""
|
"""The package version."""
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ class Settings(BaseSettings):
|
|||||||
"""The application name."""
|
"""The application name."""
|
||||||
admin_email: str = "imacat@mail.imacat.idv.tw"
|
admin_email: str = "imacat@mail.imacat.idv.tw"
|
||||||
"""The administrator email address."""
|
"""The administrator email address."""
|
||||||
SQLALCHEMY_DATABASE_URL: str
|
SQLALCHEMY_DATABASE_URI: str
|
||||||
"""The SQLAlchemy database URL."""
|
"""The SQLAlchemy database URL."""
|
||||||
ANTHROPIC_API_KEY: str
|
ANTHROPIC_API_KEY: str
|
||||||
"""The Anthropic API key."""
|
"""The Anthropic API key."""
|
||||||
|
|
||||||
model_config = SettingsConfigDict(env_file=".env", extra="ignore")
|
model_config = SettingsConfigDict(env_file=".env")
|
||||||
"""The model configuration."""
|
"""The model configuration."""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,11 @@
|
|||||||
"""
|
"""
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.engine.interfaces import DBAPICursor, DBAPIConnection
|
||||||
from sqlalchemy.orm import DeclarativeBase, sessionmaker, Session
|
from sqlalchemy.orm import DeclarativeBase, sessionmaker, Session
|
||||||
|
from sqlalchemy.pool import ConnectionPoolEntry
|
||||||
|
|
||||||
from .config import Settings, get_settings
|
from .config import Settings, get_settings
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ class DataSource:
|
|||||||
:return: The database engine.
|
:return: The database engine.
|
||||||
"""
|
"""
|
||||||
settings: Settings = get_settings()
|
settings: Settings = get_settings()
|
||||||
return self.__create_engine(settings.SQLALCHEMY_DATABASE_URL)
|
return self.__create_engine(settings.SQLALCHEMY_DATABASE_URI)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def __session_local(self) -> sessionmaker:
|
def __session_local(self) -> sessionmaker:
|
||||||
@@ -51,9 +52,6 @@ class DataSource:
|
|||||||
def __create_engine(cls, url: str) -> sa.Engine:
|
def __create_engine(cls, url: str) -> sa.Engine:
|
||||||
"""Constructs and returns the database engine.
|
"""Constructs and returns the database engine.
|
||||||
|
|
||||||
The foreign key enforcement is enabled on every connection
|
|
||||||
of a SQLite engine.
|
|
||||||
|
|
||||||
:param url: The SQLAlchemy database URL.
|
:param url: The SQLAlchemy database URL.
|
||||||
:return: The database engine.
|
:return: The database engine.
|
||||||
"""
|
"""
|
||||||
@@ -65,24 +63,10 @@ class DataSource:
|
|||||||
poolclass=sa.StaticPool)
|
poolclass=sa.StaticPool)
|
||||||
else:
|
else:
|
||||||
engine = sa.create_engine(url)
|
engine = sa.create_engine(url)
|
||||||
if engine.url.get_backend_name() == "sqlite":
|
if engine.dialect.name == "sqlite":
|
||||||
sa.event.listen(engine, "connect",
|
cls.__enable_sqlite_foreign_keys(engine)
|
||||||
cls.__enable_sqlite_foreign_keys)
|
|
||||||
return engine
|
return engine
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def __enable_sqlite_foreign_keys(dbapi_connection: Any,
|
|
||||||
_: Any) -> None:
|
|
||||||
"""Enables the foreign key enforcement on a new connection.
|
|
||||||
|
|
||||||
:param dbapi_connection: The DBAPI connection.
|
|
||||||
:param _: The connection record (unused).
|
|
||||||
:return: None.
|
|
||||||
"""
|
|
||||||
cursor: Any = dbapi_connection.cursor()
|
|
||||||
cursor.execute("PRAGMA foreign_keys=ON")
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __resolve_sqlite_relative_url(url: str) -> str:
|
def __resolve_sqlite_relative_url(url: str) -> str:
|
||||||
"""Resolves the SQLite relative URL to the instance folder.
|
"""Resolves the SQLite relative URL to the instance folder.
|
||||||
@@ -101,6 +85,31 @@ class DataSource:
|
|||||||
path = base / "instance" / path
|
path = base / "instance" / path
|
||||||
return f"sqlite:///{path}"
|
return f"sqlite:///{path}"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __enable_sqlite_foreign_keys(engine: sa.Engine) -> None:
|
||||||
|
"""Turns on the foreign key enforcement of SQLite.
|
||||||
|
|
||||||
|
The ``foreign_keys`` pragma is turned on for every
|
||||||
|
connection of the engine, so that the ``ON DELETE``
|
||||||
|
actions of the schema run.
|
||||||
|
|
||||||
|
:param engine: The SQLite database engine.
|
||||||
|
:return: None.
|
||||||
|
"""
|
||||||
|
def on_connect(dbapi_connection: DBAPIConnection,
|
||||||
|
_: ConnectionPoolEntry) -> None:
|
||||||
|
"""Turns on the pragma on a new connection.
|
||||||
|
|
||||||
|
:param dbapi_connection: The DB-API connection.
|
||||||
|
:param _: The connection record (unused).
|
||||||
|
:return: None.
|
||||||
|
"""
|
||||||
|
cursor: DBAPICursor = dbapi_connection.cursor()
|
||||||
|
cursor.execute("PRAGMA foreign_keys=ON")
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
sa.event.listen(engine, "connect", on_connect)
|
||||||
|
|
||||||
|
|
||||||
ds: DataSource = DataSource()
|
ds: DataSource = DataSource()
|
||||||
"""The data source."""
|
"""The data source."""
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ class TestBuildDB(unittest.TestCase):
|
|||||||
self.__annotations: Path = self.__dir / "annotations.csv"
|
self.__annotations: Path = self.__dir / "annotations.csv"
|
||||||
self.__write_chart(self.CHART_CSV)
|
self.__write_chart(self.CHART_CSV)
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class TestExportLlmInput(unittest.TestCase):
|
|||||||
self.__dir: Path = Path(tmp.name)
|
self.__dir: Path = Path(tmp.name)
|
||||||
self.__output: Path = self.__dir / "llm-input.jsonl"
|
self.__output: Path = self.__dir / "llm-input.jsonl"
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class TestFetchArtists(unittest.TestCase):
|
|||||||
self.__snapshot: Path = \
|
self.__snapshot: Path = \
|
||||||
self.__dir / "artists_wikidata.csv"
|
self.__dir / "artists_wikidata.csv"
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class TestFetchLyrics(unittest.TestCase):
|
|||||||
self.__provenance: Path = \
|
self.__provenance: Path = \
|
||||||
self.__dir / "lyrics-provenance.csv"
|
self.__dir / "lyrics-provenance.csv"
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class TestModels(unittest.TestCase):
|
|||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
"""Create the schema on an in-memory SQLite database."""
|
"""Create the schema on an in-memory SQLite database."""
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
@@ -188,7 +188,8 @@ class TestRequestBuilding(RunLLMTestCase):
|
|||||||
:return: The parsed request.
|
:return: The parsed request.
|
||||||
"""
|
"""
|
||||||
stdout: io.StringIO = io.StringIO()
|
stdout: io.StringIO = io.StringIO()
|
||||||
with redirect_stdout(stdout):
|
stderr: io.StringIO = io.StringIO()
|
||||||
|
with redirect_stdout(stdout), redirect_stderr(stderr):
|
||||||
run_llm.main([
|
run_llm.main([
|
||||||
str(self.__prompt), str(self.__input),
|
str(self.__prompt), str(self.__input),
|
||||||
str(self.__archive_dir), "--dry-run"] + extra_argv)
|
str(self.__archive_dir), "--dry-run"] + extra_argv)
|
||||||
@@ -239,7 +240,7 @@ class TestMainFlow(RunLLMTestCase):
|
|||||||
str(self.__prompt), str(self.__input),
|
str(self.__prompt), str(self.__input),
|
||||||
str(self.__archive_dir)]
|
str(self.__archive_dir)]
|
||||||
self.__settings: config.Settings = config.Settings(
|
self.__settings: config.Settings = config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key")
|
ANTHROPIC_API_KEY="test-key")
|
||||||
config.set_settings(self.__settings)
|
config.set_settings(self.__settings)
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class TestTallyAnnotations(unittest.TestCase):
|
|||||||
run_dir.mkdir()
|
run_dir.mkdir()
|
||||||
self.__runs.append(run_dir)
|
self.__runs.append(run_dir)
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class TestTallyCodings(unittest.TestCase):
|
|||||||
self.__output_csv: Path \
|
self.__output_csv: Path \
|
||||||
= self.__dir / "results" / "codings.csv"
|
= self.__dir / "results" / "codings.csv"
|
||||||
config.set_settings(config.Settings(
|
config.set_settings(config.Settings(
|
||||||
SQLALCHEMY_DATABASE_URL="sqlite://",
|
SQLALCHEMY_DATABASE_URI="sqlite://",
|
||||||
ANTHROPIC_API_KEY="test-key"))
|
ANTHROPIC_API_KEY="test-key"))
|
||||||
self.__ds: DataSource = DataSource()
|
self.__ds: DataSource = DataSource()
|
||||||
self.addCleanup(self.__ds.engine.dispose)
|
self.addCleanup(self.__ds.engine.dispose)
|
||||||
|
|||||||
Reference in New Issue
Block a user