| 356 | } |
| 357 | |
| 358 | size_t CorpusObject::addDocs(PyObject* tokenizedIter, PyObject* rawIter, PyObject* metadataIter) |
| 359 | { |
| 360 | if (!isIndependent()) |
| 361 | throw py::RuntimeError{ "Cannot modify the corpus bound to a topic model." }; |
| 362 | |
| 363 | size_t cnt = 0; |
| 364 | py::UniqueObj stopwords{ PyObject_GetAttrString((PyObject*)this, "_stopwords") }; |
| 365 | |
| 366 | py::foreach<PyObject*>(tokenizedIter, [&](PyObject* tokenized) |
| 367 | { |
| 368 | tomoto::RawDoc doc; |
| 369 | py::foreach<PyObject*>(tokenized, [&](PyObject* t) |
| 370 | { |
| 371 | if (PyUnicode_Check(t)) |
| 372 | { |
| 373 | doc.words.emplace_back(vocab->vocabs->add(py::toCpp<std::string>(t))); |
| 374 | } |
| 375 | else if (t == Py_None) |
| 376 | { |
| 377 | doc.words.emplace_back(tomoto::non_vocab_id); |
| 378 | } |
| 379 | else if (PyTuple_Size(t) == 3) |
| 380 | { |
| 381 | PyObject* word = PyTuple_GetItem(t, 0); |
| 382 | PyObject* pos = PyTuple_GetItem(t, 1); |
| 383 | PyObject* len = PyTuple_GetItem(t, 2); |
| 384 | if (!((PyUnicode_Check(word) || word == Py_None) && PyLong_Check(pos) && PyLong_Check(len))) throw py::ValueError{ "`tokenizer` must return an iterable of `str` or `tuple` of (`str`, `int`, `int`)." }; |
| 385 | |
| 386 | bool isStopword = false; |
| 387 | if (stopwords.get() != Py_None) |
| 388 | { |
| 389 | py::UniqueObj stopRet{ PyObject_CallObject(stopwords.get(), py::buildPyTuple(word).get())}; |
| 390 | if (!stopRet) throw py::ExcPropagation{}; |
| 391 | isStopword = PyObject_IsTrue(stopRet.get()); |
| 392 | } |
| 393 | else if (word == Py_None) |
| 394 | { |
| 395 | isStopword = true; |
| 396 | } |
| 397 | doc.words.emplace_back(isStopword ? tomoto::non_vocab_id : vocab->vocabs->add(py::toCpp<std::string>(word))); |
| 398 | doc.origWordPos.emplace_back(PyLong_AsLong(pos)); |
| 399 | doc.origWordLen.emplace_back(PyLong_AsLong(len)); |
| 400 | } |
| 401 | else |
| 402 | { |
| 403 | throw py::ValueError{ "`tokenizer` must return an iterable of `str` or `tuple` of (`str`, `int`, `int`)." }; |
| 404 | } |
| 405 | }, "`tokenizer` must return an iterable of `str` or `tuple` of (`str`, `int`, `int`)."); |
| 406 | py::UniqueObj raw{ PyIter_Next(rawIter) }; |
| 407 | if (!raw) throw py::ExcPropagation{}; |
| 408 | py::UniqueObj metadata{ PyIter_Next(metadataIter) }; |
| 409 | if (!metadata) throw py::ExcPropagation{}; |
| 410 | |
| 411 | doc.rawStr = tomoto::SharedString{ py::toCpp<std::string>(raw.get()) }; |
| 412 | |
| 413 | PyObject* key, * value; |
| 414 | Py_ssize_t p = 0; |
| 415 | while (PyDict_Next(metadata.get(), &p, &key, &value)) |
nothing calls this directly
no test coverage detected