perrette / papers

Command-line tool to manage bibliography (pdfs + bibtex)
MIT License
146 stars 22 forks source link

Test coverage issues #44

Closed boyanpenkov closed 1 year ago

boyanpenkov commented 1 year ago

Test coverage is pretty poor, as I was reminded during the last few days.

Originally posted by @perrette in https://github.com/perrette/papers/issues/42#issuecomment-1519837073

boyanpenkov commented 1 year ago

I see:

pytest -vv . --cov=. -n auto                                   7:19:59
========================================== test session starts ==========================================
platform linux -- Python 3.11.3, pytest-7.1.2, pluggy-1.0.0 -- /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python
cachedir: .pytest_cache
rootdir: /home/boyan/boyanshouse/Vazhno/Work/papers
plugins: anyio-3.5.0, xdist-3.2.1, cov-4.0.0
[gw0] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw1] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw2] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw3] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw0] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
[gw1] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
[gw2] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
[gw3] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
gw0 [103] / gw1 [103] / gw2 [103] / gw3 [103]
scheduling tests via LoadScheduling

tests/test_papers.py::TestSimple::test_fetch_scholar 
tests/test_papers.py::TestAdd2::test_add 
tests/test_papers.py::TestAddDir::test_adddir_pdf 
tests/test_papers.py::TestBibtexFileEntry::test_format_file 
[gw0] [  0%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_format_file 
tests/test_papers.py::TestBibtexFileEntry::test_format_files 
[gw0] [  1%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_format_files 
tests/test_papers.py::TestBibtexFileEntry::test_parse_file 
[gw0] [  2%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_parse_file 
[gw1] [  3%] PASSED tests/test_papers.py::TestSimple::test_fetch_scholar 
tests/test_papers.py::TestInstall::test_local_install 
tests/test_papers.py::TestBibtexFileEntry::test_parse_files 
[gw0] [  4%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_parse_files 
tests/test_papers.py::TestSimple::test_doi 
[gw1] [  5%] PASSED tests/test_papers.py::TestInstall::test_local_install 
tests/test_papers.py::TestAdd::test_add 
[gw0] [  6%] PASSED tests/test_papers.py::TestSimple::test_doi 
tests/test_papers.py::TestSimple::test_fetch 
[gw3] [  7%] PASSED tests/test_papers.py::TestAddDir::test_adddir_pdf 
tests/test_papers.py::TestAddDir::test_adddir_pdf_cmd 
[gw2] [  8%] PASSED tests/test_papers.py::TestAdd2::test_add 
tests/test_papers.py::TestAdd2::test_add_attachment 
[gw0] [  9%] PASSED tests/test_papers.py::TestSimple::test_fetch 
tests/test_papers.py::TestDuplicatesExact::test_exactsame 
[gw0] [ 10%] PASSED tests/test_papers.py::TestDuplicatesExact::test_exactsame 
tests/test_papers.py::TestDuplicatesExact::test_missingdoi 
[gw0] [ 11%] PASSED tests/test_papers.py::TestDuplicatesExact::test_missingdoi 
tests/test_papers.py::TestDuplicatesExact::test_missingfield 
[gw0] [ 12%] PASSED tests/test_papers.py::TestDuplicatesExact::test_missingfield 
[gw1] [ 13%] PASSED tests/test_papers.py::TestAdd::test_add 
tests/test_papers.py::TestAdd::test_add_rename 
tests/test_papers.py::TestDuplicatesExact::test_missingtitauthor 
[gw0] [ 14%] PASSED tests/test_papers.py::TestDuplicatesExact::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesGood::test_anotherkey 
[gw0] [ 15%] PASSED tests/test_papers.py::TestDuplicatesGood::test_anotherkey 
tests/test_papers.py::TestDuplicatesGood::test_conflictauthor 
[gw0] [ 16%] PASSED tests/test_papers.py::TestDuplicatesGood::test_conflictauthor 
tests/test_papers.py::TestDuplicatesGood::test_conflictdoi 
[gw0] [ 17%] PASSED tests/test_papers.py::TestDuplicatesGood::test_conflictdoi 
tests/test_papers.py::TestDuplicatesGood::test_conflictyear 
[gw2] [ 18%] PASSED tests/test_papers.py::TestAdd2::test_add_attachment 
tests/test_papers.py::TestAdd2::test_add_rename 
[gw0] [ 19%] PASSED tests/test_papers.py::TestDuplicatesGood::test_conflictyear 
tests/test_papers.py::TestDuplicatesGood::test_exactsame 
[gw0] [ 20%] PASSED tests/test_papers.py::TestDuplicatesGood::test_exactsame 
tests/test_papers.py::TestDuplicatesGood::test_missingdoi 
[gw0] [ 21%] PASSED tests/test_papers.py::TestDuplicatesGood::test_missingdoi 
tests/test_papers.py::TestDuplicatesGood::test_missingfield 
[gw0] [ 22%] PASSED tests/test_papers.py::TestDuplicatesGood::test_missingfield 
tests/test_papers.py::TestDuplicatesGood::test_missingtitauthor 
[gw0] [ 23%] PASSED tests/test_papers.py::TestDuplicatesGood::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesFair::test_anotherkey 
[gw0] [ 24%] PASSED tests/test_papers.py::TestDuplicatesFair::test_anotherkey 
tests/test_papers.py::TestDuplicatesFair::test_conflictauthor 
[gw0] [ 25%] PASSED tests/test_papers.py::TestDuplicatesFair::test_conflictauthor 
tests/test_papers.py::TestDuplicatesFair::test_conflictdoi 
[gw0] [ 26%] PASSED tests/test_papers.py::TestDuplicatesFair::test_conflictdoi 
tests/test_papers.py::TestDuplicatesFair::test_conflictyear 
[gw0] [ 27%] PASSED tests/test_papers.py::TestDuplicatesFair::test_conflictyear 
tests/test_papers.py::TestDuplicatesFair::test_exactsame 
[gw0] [ 28%] PASSED tests/test_papers.py::TestDuplicatesFair::test_exactsame 
tests/test_papers.py::TestDuplicatesFair::test_missingdoi 
[gw0] [ 29%] PASSED tests/test_papers.py::TestDuplicatesFair::test_missingdoi 
tests/test_papers.py::TestDuplicatesFair::test_missingfield 
[gw0] [ 30%] PASSED tests/test_papers.py::TestDuplicatesFair::test_missingfield 
tests/test_papers.py::TestDuplicatesFair::test_missingtitauthor 
[gw0] [ 31%] PASSED tests/test_papers.py::TestDuplicatesFair::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesPartial::test_anotherkey 
[gw0] [ 32%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_anotherkey 
tests/test_papers.py::TestDuplicatesPartial::test_conflictauthor 
[gw0] [ 33%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_conflictauthor 
tests/test_papers.py::TestDuplicatesPartial::test_conflictdoi 
[gw0] [ 33%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_conflictdoi 
tests/test_papers.py::TestDuplicatesPartial::test_conflictyear 
[gw0] [ 34%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_conflictyear 
[gw1] [ 35%] PASSED tests/test_papers.py::TestAdd::test_add_rename 
tests/test_papers.py::TestAdd::test_add_rename_copy 
tests/test_papers.py::TestDuplicatesPartial::test_exactsame 
[gw3] [ 36%] PASSED tests/test_papers.py::TestAddDir::test_adddir_pdf_cmd 
tests/test_papers.py::TestDuplicatesExact::test_anotherkey 
[gw0] [ 37%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_exactsame 
tests/test_papers.py::TestDuplicatesPartial::test_missingdoi 
[gw3] [ 38%] PASSED tests/test_papers.py::TestDuplicatesExact::test_anotherkey 
tests/test_papers.py::TestDuplicatesExact::test_conflictauthor 
[gw0] [ 39%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_missingdoi 
tests/test_papers.py::TestDuplicatesPartial::test_missingfield 
[gw3] [ 40%] PASSED tests/test_papers.py::TestDuplicatesExact::test_conflictauthor 
tests/test_papers.py::TestDuplicatesExact::test_conflictdoi 
[gw0] [ 41%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_missingfield 
tests/test_papers.py::TestDuplicatesPartial::test_missingtitauthor 
[gw3] [ 42%] PASSED tests/test_papers.py::TestDuplicatesExact::test_conflictdoi 
tests/test_papers.py::TestDuplicatesExact::test_conflictyear 
[gw0] [ 43%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_missingtitauthor 
tests/test_papers.py::TestDuplicates::test_anotherkey 
[gw3] [ 44%] PASSED tests/test_papers.py::TestDuplicatesExact::test_conflictyear 
tests/test_papers.py::TestDuplicates::test_conflictyear 
[gw2] [ 45%] PASSED tests/test_papers.py::TestAdd2::test_add_rename 
tests/test_papers.py::TestAdd2::test_add_rename_copy 
[gw0] [ 46%] PASSED tests/test_papers.py::TestDuplicates::test_anotherkey 
tests/test_papers.py::TestDuplicates::test_conflictauthor 
[gw3] [ 47%] PASSED tests/test_papers.py::TestDuplicates::test_conflictyear 
tests/test_papers.py::TestDuplicates::test_exactsame 
[gw0] [ 48%] PASSED tests/test_papers.py::TestDuplicates::test_conflictauthor 
tests/test_papers.py::TestDuplicates::test_conflictdoi 
[gw3] [ 49%] PASSED tests/test_papers.py::TestDuplicates::test_exactsame 
tests/test_papers.py::TestDuplicates::test_missingdoi 
[gw0] [ 50%] PASSED tests/test_papers.py::TestDuplicates::test_conflictdoi 
tests/test_papers.py::TestDuplicates::test_missingtitauthor 
[gw3] [ 51%] PASSED tests/test_papers.py::TestDuplicates::test_missingdoi 
tests/test_papers.py::TestDuplicates::test_missingfield 
[gw0] [ 52%] PASSED tests/test_papers.py::TestDuplicates::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesAdd::test_anotherkey 
[gw0] [ 53%] SKIPPED tests/test_papers.py::TestDuplicatesAdd::test_anotherkey 
tests/test_papers.py::TestDuplicatesAdd::test_conflictauthor 
[gw3] [ 54%] PASSED tests/test_papers.py::TestDuplicates::test_missingfield 
tests/test_papers.py::TestDuplicatesAdd::test_conflictyear 
[gw1] [ 55%] PASSED tests/test_papers.py::TestAdd::test_add_rename_copy 
tests/test_papers.py::TestAdd::test_fails_without_install 
[gw1] [ 56%] PASSED tests/test_papers.py::TestAdd::test_fails_without_install 
tests/test_papers.py::TestDuplicatesAdd::test_missingtitauthor 
[gw0] [ 57%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_conflictauthor 
tests/test_papers.py::TestDuplicatesAdd::test_conflictdoi 
[gw2] [ 58%] PASSED tests/test_papers.py::TestAdd2::test_add_rename_copy 
tests/test_papers.py::TestAdd2::test_fails_without_install 
[gw2] [ 59%] PASSED tests/test_papers.py::TestAdd2::test_fails_without_install 
tests/test_papers.py::TestAddBib::test_addbib 
[gw3] [ 60%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_conflictyear 
tests/test_papers.py::TestDuplicatesAdd::test_exactsame 
[gw3] [ 61%] SKIPPED tests/test_papers.py::TestDuplicatesAdd::test_exactsame 
tests/test_papers.py::TestDuplicatesAdd::test_missingdoi 
[gw2] [ 62%] PASSED tests/test_papers.py::TestAddBib::test_addbib 
tests/test_papers.py::TestAddResolveDuplicate::test_raises 
[gw1] [ 63%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_missingtitauthor 
tests/test_papers.py::TestAddResolveDuplicate::test_append 
[gw0] [ 64%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_conflictdoi 
tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original_but_originalkey 
[gw3] [ 65%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_missingdoi 
tests/test_papers.py::TestDuplicatesAdd::test_missingfield 
[gw2] [ 66%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_raises 
tests/test_papers.py::TestAddResolveDuplicate::test_skip 
[gw1] [ 66%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_append 
tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original 
[gw0] [ 67%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original_but_originalkey 
tests/test_papers.py::TestAddResolveDuplicate::test_original_updated_from_conflict 
[gw3] [ 68%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_missingfield 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_append 
[gw2] [ 69%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_skip 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original_but_originalkey 
[gw1] [ 70%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_overwrite 
[gw0] [ 71%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_original_updated_from_conflict 
tests/test_papers.py::TestAddResolveDuplicate::test_overwrite 
[gw2] [ 72%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original_but_originalkey 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_original_updated_from_conflict 
[gw3] [ 73%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_append 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original 
[gw1] [ 74%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_overwrite 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_raises 
[gw0] [ 75%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_overwrite 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_skip 
[gw3] [ 76%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original 
tests/test_papers.py::TestCheckResolveDuplicate::test_not_a_duplicate 
[gw2] [ 77%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_original_updated_from_conflict 
tests/test_papers.py::TestCheckResolveDuplicate::test_merge 
[gw1] [ 78%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_raises 
tests/test_papers.py::TestCheckResolveDuplicate::test_pick_conflict_1 
[gw0] [ 79%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_skip 
tests/test_papers.py::TestCheckResolveDuplicate::test_pick_reference_2 
[gw3] [ 80%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_not_a_duplicate 
tests/test_papers.py::TestCheckResolveDuplicate::test_raises 
[gw2] [ 81%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_merge 
tests/test_papers.py::TestCheckResolveDuplicate::test_skip_check 
[gw1] [ 82%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_pick_conflict_1 
tests/test_papers.py::TestAddConflict::test_add_conflict_key_check_raises 
[gw0] [ 83%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_pick_reference_2 
tests/test_papers.py::TestAddConflict::test_add_conflict_key_nocheck_raises 
[gw2] [ 84%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_skip_check 
[gw3] [ 85%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_raises 
tests/test_papers.py::TestAddConflict::test_add_miss_doi_merge 
tests/test_papers.py::TestAddConflict::test_add_conflict_key_update 
[gw1] [ 86%] PASSED tests/test_papers.py::TestAddConflict::test_add_conflict_key_check_raises 
tests/test_papers.py::TestAddConflict::test_add_miss_field_fails 
[gw0] [ 87%] PASSED tests/test_papers.py::TestAddConflict::test_add_conflict_key_nocheck_raises 
tests/test_papers.py::TestAddConflict::test_add_miss_merge 
[gw3] [ 88%] PASSED tests/test_papers.py::TestAddConflict::test_add_conflict_key_update 
tests/test_papers.py::TestAddConflict::test_add_same 
[gw2] [ 89%] PASSED tests/test_papers.py::TestAddConflict::test_add_miss_doi_merge 
tests/test_papers.py::TestAddConflict::test_add_miss_titauthor_merge 
[gw1] [ 90%] PASSED tests/test_papers.py::TestAddConflict::test_add_miss_field_fails 
tests/test_papers.py::TestAddConflict::test_add_same_but_file 
[gw0] [ 91%] PASSED tests/test_papers.py::TestAddConflict::test_add_miss_merge 
tests/test_papers.py::TestAddConflict::test_add_same_but_key_fails 
[gw0] [ 92%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_but_key_fails 
tests/test_papers.py::TestAddConflict::test_add_same_doi_unchecked 
[gw2] [ 93%] PASSED tests/test_papers.py::TestAddConflict::test_add_miss_titauthor_merge 
tests/test_papers.py::TestAddConflict::test_add_same_but_key_update 
[gw3] [ 94%] PASSED tests/test_papers.py::TestAddConflict::test_add_same 
tests/test_papers.py::TestAddConflict::test_add_same_but_key_interactive 
[gw1] [ 95%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_but_file 
tests/test_papers.py::TestAddConflict::test_add_same_doi_fails 
[gw0] [ 96%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_doi_unchecked 
tests/test_papers.py::TestAddConflict::test_add_same_doi_update_key 
[gw2] [ 97%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_but_key_update 
[gw3] [ 98%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_but_key_interactive 
[gw1] [ 99%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_doi_fails 
[gw0] [100%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_doi_update_key 

---------- coverage: platform linux, python 3.11.3-final-0 -----------
Name                   Stmts   Miss  Cover
------------------------------------------
papers/__init__.py         4      0   100%
papers/_version.py         2      0   100%
papers/bib.py           1000    407    59%
papers/config.py         251     86    66%
papers/duplicate.py      384    136    65%
papers/encoding.py        84     22    74%
papers/extract.py        236    151    36%
papers/filename.py        51      4    92%
papers/latexenc.py        57     36    37%
setup.py                   2      2     0%
tests/download.py         27     11    59%
tests/test_papers.py     473     15    97%
versioneer.py            577    577     0%
------------------------------------------
TOTAL                   3148   1447    54%

==================================== 101 passed, 2 skipped in 12.07s ====================================

which seems like a good place to start.

perrette commented 1 year ago

Yep good to use coverage info. I reckon the bare minimum would be to have one test per command. Things like papers check --duplicate, papers filecheck, and corner cases of papers add entry are not tested at all.

perrette commented 1 year ago

Here updated after merging PR #43 and #47

---------- coverage: platform linux, python 3.10.11-final-0 ----------
  Name                  Stmts   Miss  Cover   Missing
  ---------------------------------------------------
  papers/__init__.py        4      0   100%
  papers/__main__.py      520    520     0%   1-847
  papers/_version.py        2      0   100%
  papers/bib.py           492    304    38%   42-57, 67, 136-[143](https://github.com/perrette/papers/actions/runs/4788451379/jobs/8515076858?pr=47#step:5:144), 157-158, 175-190, 194, 214, 228-229, 233-234, 237, 262, 273, 289-291, 298-306, 318-363, 371, 375, 381, 386, 388, 390, 401-402, 408, 420, 440-446, 450, 455-459, 463, 466-471, 494-495, 504-571, 575-580, 587-682, 686, 692-703, 709-781
  papers/config.py        250    168    33%   24-39, 60-68, 94-98, 102-105, 108-119, 122-126, 130, 143-153, 157-159, 171, 174-186, 189-205, 209-278, 294, 299, 317-319, 322-326, 333, 339-370
  papers/duplicate.py     384    326    15%   23-27, 39-49, 71-91, 95-96, 100-101, 111, 115-120, 126, 129-133, 137-[144](https://github.com/perrette/papers/actions/runs/4788451379/jobs/8515076858?pr=47#step:5:145), 150-157, 163, 169-183, 188-195, 200-235, 241-278, 286-295, 300-330, 335-341, 349-371, 380, 384, 397, 401-404, 407, 410, 414, 417, 420, 423, 427, 430-433, 436-451, 456-527, 532-544, 551-562, 572-627, 636-640
  papers/encoding.py       84     27    68%   35, 49, 63-64, 81, 88-90, 106-120, 125-128
  papers/extract.py       236    [149](https://github.com/perrette/papers/actions/runs/4788451379/jobs/8515076858?pr=47#step:5:150)    37%   32, 51-78, 97, 105, 109, 115-119, 132, 139, 144-159, 179-189, 193-199, 202, 221, 226-229, 234-239, 244-245, 250-268, 272, 277-286, 292-332, 337-367, 372-386
  papers/filename.py       51      5    90%   18-19, 45-46, 102
  papers/latexenc.py       57     36    37%   23-31, 41-90, 100-101
  ---------------------------------------------------
  TOTAL                  2080   1535    26%

  ================== 101 passed, 2 skipped, 1 warning in 28.49s ==================

copied from:

https://github.com/perrette/papers/actions/runs/4788451379/jobs/8515076858?pr=47#step:5:140

perrette commented 1 year ago

I'm not sure why the coverage looks so widely different (and poorer) from your estimate. E.g. __main__.py (previously in bib.py) is 0%. Even things that should be unaffected like duplicates.py are shown to be 15% here instead of 65% in your estimate. I must be missing something. When trying to locally run pytest with -n auto I get an error (unknown command). The pytest command now used in github actions is pyproject.toml, in case you can spot what's missing @boyanpenkov.

boyanpenkov commented 1 year ago

For -n auto you need https://pypi.org/project/pytest-xdist/ which you can conda install -c conda-forge pytest-xdist or though pip; this will parallelize test runs in separate procs over all your cores, which reduces the test time at present from 14 sec to 12 sec on my machine, which is like totally a rounding error.

boyanpenkov commented 1 year ago

For me, on master before the merge:

pytest --cov=papers --cov-append --cov-report=term-missing tests -xv                       12:25:04
======================================================== test session starts ========================================================
platform linux -- Python 3.11.3, pytest-7.1.2, pluggy-1.0.0 -- /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python
cachedir: .pytest_cache
rootdir: /home/boyan/boyanshouse/Vazhno/Work/papers
plugins: anyio-3.5.0, xdist-3.2.1, cov-4.0.0
collected 103 items                                                                                                                 

tests/test_papers.py::TestBibtexFileEntry::test_format_file PASSED                                                            [  0%]
tests/test_papers.py::TestBibtexFileEntry::test_format_files PASSED                                                           [  1%]
tests/test_papers.py::TestBibtexFileEntry::test_parse_file PASSED                                                             [  2%]
tests/test_papers.py::TestBibtexFileEntry::test_parse_files PASSED                                                            [  3%]
tests/test_papers.py::TestSimple::test_doi PASSED                                                                             [  4%]
tests/test_papers.py::TestSimple::test_fetch PASSED                                                                           [  5%]
tests/test_papers.py::TestSimple::test_fetch_scholar PASSED                                                                   [  6%]
tests/test_papers.py::TestInstall::test_local_install PASSED                                                                  [  7%]
tests/test_papers.py::TestAdd::test_add PASSED                                                                                [  8%]
tests/test_papers.py::TestAdd::test_add_rename PASSED                                                                         [  9%]
tests/test_papers.py::TestAdd::test_add_rename_copy PASSED                                                                    [ 10%]
tests/test_papers.py::TestAdd::test_fails_without_install PASSED                                                              [ 11%]
tests/test_papers.py::TestAdd2::test_add PASSED                                                                               [ 12%]
tests/test_papers.py::TestAdd2::test_add_attachment PASSED                                                                    [ 13%]
tests/test_papers.py::TestAdd2::test_add_rename PASSED                                                                        [ 14%]
tests/test_papers.py::TestAdd2::test_add_rename_copy PASSED                                                                   [ 15%]
tests/test_papers.py::TestAdd2::test_fails_without_install PASSED                                                             [ 16%]
tests/test_papers.py::TestAddBib::test_addbib PASSED                                                                          [ 17%]
tests/test_papers.py::TestAddDir::test_adddir_pdf PASSED                                                                      [ 18%]
tests/test_papers.py::TestAddDir::test_adddir_pdf_cmd PASSED                                                                  [ 19%]
tests/test_papers.py::TestDuplicatesExact::test_anotherkey PASSED                                                             [ 20%]
tests/test_papers.py::TestDuplicatesExact::test_conflictauthor PASSED                                                         [ 21%]
tests/test_papers.py::TestDuplicatesExact::test_conflictdoi PASSED                                                            [ 22%]
tests/test_papers.py::TestDuplicatesExact::test_conflictyear PASSED                                                           [ 23%]
tests/test_papers.py::TestDuplicatesExact::test_exactsame PASSED                                                              [ 24%]
tests/test_papers.py::TestDuplicatesExact::test_missingdoi PASSED                                                             [ 25%]
tests/test_papers.py::TestDuplicatesExact::test_missingfield PASSED                                                           [ 26%]
tests/test_papers.py::TestDuplicatesExact::test_missingtitauthor PASSED                                                       [ 27%]
tests/test_papers.py::TestDuplicatesGood::test_anotherkey PASSED                                                              [ 28%]
tests/test_papers.py::TestDuplicatesGood::test_conflictauthor PASSED                                                          [ 29%]
tests/test_papers.py::TestDuplicatesGood::test_conflictdoi PASSED                                                             [ 30%]
tests/test_papers.py::TestDuplicatesGood::test_conflictyear PASSED                                                            [ 31%]
tests/test_papers.py::TestDuplicatesGood::test_exactsame PASSED                                                               [ 32%]
tests/test_papers.py::TestDuplicatesGood::test_missingdoi PASSED                                                              [ 33%]
tests/test_papers.py::TestDuplicatesGood::test_missingfield PASSED                                                            [ 33%]
tests/test_papers.py::TestDuplicatesGood::test_missingtitauthor PASSED                                                        [ 34%]
tests/test_papers.py::TestDuplicatesFair::test_anotherkey PASSED                                                              [ 35%]
tests/test_papers.py::TestDuplicatesFair::test_conflictauthor PASSED                                                          [ 36%]
tests/test_papers.py::TestDuplicatesFair::test_conflictdoi PASSED                                                             [ 37%]
tests/test_papers.py::TestDuplicatesFair::test_conflictyear PASSED                                                            [ 38%]
tests/test_papers.py::TestDuplicatesFair::test_exactsame PASSED                                                               [ 39%]
tests/test_papers.py::TestDuplicatesFair::test_missingdoi PASSED                                                              [ 40%]
tests/test_papers.py::TestDuplicatesFair::test_missingfield PASSED                                                            [ 41%]
tests/test_papers.py::TestDuplicatesFair::test_missingtitauthor PASSED                                                        [ 42%]
tests/test_papers.py::TestDuplicatesPartial::test_anotherkey PASSED                                                           [ 43%]
tests/test_papers.py::TestDuplicatesPartial::test_conflictauthor PASSED                                                       [ 44%]
tests/test_papers.py::TestDuplicatesPartial::test_conflictdoi PASSED                                                          [ 45%]
tests/test_papers.py::TestDuplicatesPartial::test_conflictyear PASSED                                                         [ 46%]
tests/test_papers.py::TestDuplicatesPartial::test_exactsame PASSED                                                            [ 47%]
tests/test_papers.py::TestDuplicatesPartial::test_missingdoi PASSED                                                           [ 48%]
tests/test_papers.py::TestDuplicatesPartial::test_missingfield PASSED                                                         [ 49%]
tests/test_papers.py::TestDuplicatesPartial::test_missingtitauthor PASSED                                                     [ 50%]
tests/test_papers.py::TestDuplicates::test_anotherkey PASSED                                                                  [ 51%]
tests/test_papers.py::TestDuplicates::test_conflictauthor PASSED                                                              [ 52%]
tests/test_papers.py::TestDuplicates::test_conflictdoi PASSED                                                                 [ 53%]
tests/test_papers.py::TestDuplicates::test_conflictyear PASSED                                                                [ 54%]
tests/test_papers.py::TestDuplicates::test_exactsame PASSED                                                                   [ 55%]
tests/test_papers.py::TestDuplicates::test_missingdoi PASSED                                                                  [ 56%]
tests/test_papers.py::TestDuplicates::test_missingfield PASSED                                                                [ 57%]
tests/test_papers.py::TestDuplicates::test_missingtitauthor PASSED                                                            [ 58%]
tests/test_papers.py::TestDuplicatesAdd::test_anotherkey SKIPPED (skip cause does not make sense with add)                    [ 59%]
tests/test_papers.py::TestDuplicatesAdd::test_conflictauthor PASSED                                                           [ 60%]
tests/test_papers.py::TestDuplicatesAdd::test_conflictdoi PASSED                                                              [ 61%]
tests/test_papers.py::TestDuplicatesAdd::test_conflictyear PASSED                                                             [ 62%]
tests/test_papers.py::TestDuplicatesAdd::test_exactsame SKIPPED (skip cause does not make sense with add)                     [ 63%]
tests/test_papers.py::TestDuplicatesAdd::test_missingdoi PASSED                                                               [ 64%]
tests/test_papers.py::TestDuplicatesAdd::test_missingfield PASSED                                                             [ 65%]
tests/test_papers.py::TestDuplicatesAdd::test_missingtitauthor PASSED                                                         [ 66%]
tests/test_papers.py::TestAddResolveDuplicate::test_append PASSED                                                             [ 66%]
tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original PASSED                                     [ 67%]
tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original_but_originalkey PASSED                     [ 68%]
tests/test_papers.py::TestAddResolveDuplicate::test_original_updated_from_conflict PASSED                                     [ 69%]
tests/test_papers.py::TestAddResolveDuplicate::test_overwrite PASSED                                                          [ 70%]
tests/test_papers.py::TestAddResolveDuplicate::test_raises PASSED                                                             [ 71%]
tests/test_papers.py::TestAddResolveDuplicate::test_skip PASSED                                                               [ 72%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_append PASSED                                                      [ 73%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original PASSED                              [ 74%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original_but_originalkey PASSED              [ 75%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_original_updated_from_conflict PASSED                              [ 76%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_overwrite PASSED                                                   [ 77%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_raises PASSED                                                      [ 78%]
tests/test_papers.py::TestAddResolveDuplicateCommand::test_skip PASSED                                                        [ 79%]
tests/test_papers.py::TestCheckResolveDuplicate::test_merge PASSED                                                            [ 80%]
tests/test_papers.py::TestCheckResolveDuplicate::test_not_a_duplicate PASSED                                                  [ 81%]
tests/test_papers.py::TestCheckResolveDuplicate::test_pick_conflict_1 PASSED                                                  [ 82%]
tests/test_papers.py::TestCheckResolveDuplicate::test_pick_reference_2 PASSED                                                 [ 83%]
tests/test_papers.py::TestCheckResolveDuplicate::test_raises PASSED                                                           [ 84%]
tests/test_papers.py::TestCheckResolveDuplicate::test_skip_check PASSED                                                       [ 85%]
tests/test_papers.py::TestAddConflict::test_add_conflict_key_check_raises PASSED                                              [ 86%]
tests/test_papers.py::TestAddConflict::test_add_conflict_key_nocheck_raises PASSED                                            [ 87%]
tests/test_papers.py::TestAddConflict::test_add_conflict_key_update PASSED                                                    [ 88%]
tests/test_papers.py::TestAddConflict::test_add_miss_doi_merge PASSED                                                         [ 89%]
tests/test_papers.py::TestAddConflict::test_add_miss_field_fails PASSED                                                       [ 90%]
tests/test_papers.py::TestAddConflict::test_add_miss_merge PASSED                                                             [ 91%]
tests/test_papers.py::TestAddConflict::test_add_miss_titauthor_merge PASSED                                                   [ 92%]
tests/test_papers.py::TestAddConflict::test_add_same PASSED                                                                   [ 93%]
tests/test_papers.py::TestAddConflict::test_add_same_but_file PASSED                                                          [ 94%]
tests/test_papers.py::TestAddConflict::test_add_same_but_key_fails PASSED                                                     [ 95%]
tests/test_papers.py::TestAddConflict::test_add_same_but_key_interactive PASSED                                               [ 96%]
tests/test_papers.py::TestAddConflict::test_add_same_but_key_update PASSED                                                    [ 97%]
tests/test_papers.py::TestAddConflict::test_add_same_doi_fails PASSED                                                         [ 98%]
tests/test_papers.py::TestAddConflict::test_add_same_doi_unchecked PASSED                                                     [ 99%]
tests/test_papers.py::TestAddConflict::test_add_same_doi_update_key PASSED                                                    [100%]

---------- coverage: platform linux, python 3.11.3-final-0 -----------
Name                   Stmts   Miss  Cover   Missing
----------------------------------------------------
papers/__init__.py         4      0   100%
papers/_version.py         2      0   100%
papers/bib.py           1002    403    60%   47-49, 69, 142-145, 159-160, 177-192, 216, 235-236, 239, 264, 275, 334, 373, 383, 390, 403-404, 410, 442-448, 452, 457-461, 471, 507, 515-516, 525, 543, 564-567, 577-582, 592-596, 600-615, 618-631, 635-662, 666-670, 673, 676-684, 690, 694-699, 705-716, 724, 728, 734-806, 854-862, 878-894, 898-908, 922-924, 927, 946, 952-953, 960-961, 965-979, 990, 994-995, 997-998, 1014, 1020-1025, 1028-1035, 1046, 1081, 1093-1105, 1108-1114, 1118-1122, 1131, 1135-1145, 1149, 1152, 1156-1261, 1264, 1275-1276, 1584-1585, 1588, 1593-1594, 1600, 1602, 1604, 1606, 1611-1615, 1620
papers/config.py         251     86    66%   33-40, 67-68, 95-99, 106, 111, 125, 158-160, 165-166, 172, 175-187, 190-206, 214, 220, 230, 233, 235, 242, 247, 249, 255, 258-263, 300, 307-310, 318-320, 323-327, 334, 345-346, 350-360
papers/duplicate.py      384    136    65%   72-74, 88-89, 95-96, 100-101, 150-157, 163, 174, 176, 178, 195, 200-235, 242, 246, 272, 294, 304, 312, 314-318, 340, 349-371, 401-404, 407, 410, 417, 420, 427, 430-433, 436-451, 477-484, 487, 490, 493, 496-497, 500, 511-525, 538-542, 560-561, 619, 622
papers/encoding.py        84     22    74%   35, 63-64, 106-120, 125-128
papers/extract.py        236    151    36%   32, 51-78, 97, 105, 109, 117-118, 132, 144-159, 179-189, 193-199, 202, 215-221, 226-229, 234-239, 244-245, 250-268, 272, 277-286, 292-332, 337-367, 372-386
papers/filename.py        51      4    92%   18-19, 45-46
papers/latexenc.py        57     36    37%   23-31, 41-90, 100-101
setup.py                   2      2     0%   1-2
tests/download.py         27     11    59%   21-32, 43-44, 48
tests/test_papers.py     473     15    97%   131, 150, 156, 228, 287, 322, 341-345, 508, 512, 814, 818, 928
versioneer.py            577    577     0%   4-1817
----------------------------------------------------
TOTAL                   3150   1443    54%

================================================== 101 passed, 2 skipped in 26.85s ==================================================
boyanpenkov commented 1 year ago

Looking at the above, not sure if the branch you have, with __main__.py is not seeing the tests move? They are not failing, but I've not understood exactly how --cov purports to work.

boyanpenkov commented 1 year ago

After the merge, however, I just see failures:

(python311) → master Work/papers pytest -vv . --cov=. -n auto                                                               12:29:52
======================================================== test session starts ========================================================
platform linux -- Python 3.11.3, pytest-7.1.2, pluggy-1.0.0 -- /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python
cachedir: .pytest_cache
rootdir: /home/boyan/boyanshouse/Vazhno/Work/papers
plugins: anyio-3.5.0, xdist-3.2.1, cov-4.0.0
[gw0] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw1] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw2] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw3] linux Python 3.11.3 cwd: /home/boyan/boyanshouse/Vazhno/Work/papers
[gw0] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
[gw1] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
[gw2] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
[gw3] Python 3.11.3 (main, Apr 19 2023, 23:54:32) [GCC 11.2.0]
gw0 [103] / gw1 [103] / gw2 [103] / gw3 [103]
scheduling tests via LoadScheduling

tests/test_papers.py::TestAdd2::test_add 
tests/test_papers.py::TestBibtexFileEntry::test_format_file 
tests/test_papers.py::TestSimple::test_fetch_scholar 
[gw0] [  0%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_format_file 
tests/test_papers.py::TestAddDir::test_adddir_pdf 
tests/test_papers.py::TestBibtexFileEntry::test_format_files 
[gw0] [  1%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_format_files 
tests/test_papers.py::TestBibtexFileEntry::test_parse_file 
[gw0] [  2%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_parse_file 
tests/test_papers.py::TestBibtexFileEntry::test_parse_files 
[gw1] [  3%] PASSED tests/test_papers.py::TestSimple::test_fetch_scholar 
tests/test_papers.py::TestInstall::test_local_install 
[gw0] [  4%] PASSED tests/test_papers.py::TestBibtexFileEntry::test_parse_files 
tests/test_papers.py::TestSimple::test_doi 
[gw2] [  5%] FAILED tests/test_papers.py::TestAdd2::test_add 
tests/test_papers.py::TestAdd2::test_add_attachment 
[gw3] [  6%] FAILED tests/test_papers.py::TestAddDir::test_adddir_pdf 
tests/test_papers.py::TestAddDir::test_adddir_pdf_cmd 
[gw1] [  7%] FAILED tests/test_papers.py::TestInstall::test_local_install 
tests/test_papers.py::TestAdd::test_add 
[gw0] [  8%] FAILED tests/test_papers.py::TestSimple::test_doi 
tests/test_papers.py::TestSimple::test_fetch 
[gw2] [  9%] FAILED tests/test_papers.py::TestAdd2::test_add_attachment 
tests/test_papers.py::TestAdd2::test_add_rename 
[gw1] [ 10%] FAILED tests/test_papers.py::TestAdd::test_add 
tests/test_papers.py::TestAdd::test_add_rename 
[gw3] [ 11%] FAILED tests/test_papers.py::TestAddDir::test_adddir_pdf_cmd 
tests/test_papers.py::TestDuplicatesExact::test_anotherkey 
[gw3] [ 12%] PASSED tests/test_papers.py::TestDuplicatesExact::test_anotherkey 
tests/test_papers.py::TestDuplicatesExact::test_conflictauthor 
[gw3] [ 13%] PASSED tests/test_papers.py::TestDuplicatesExact::test_conflictauthor 
tests/test_papers.py::TestDuplicatesExact::test_conflictdoi 
[gw3] [ 14%] PASSED tests/test_papers.py::TestDuplicatesExact::test_conflictdoi 
tests/test_papers.py::TestDuplicatesExact::test_conflictyear 
[gw3] [ 15%] PASSED tests/test_papers.py::TestDuplicatesExact::test_conflictyear 
tests/test_papers.py::TestDuplicatesGood::test_conflictdoi 
[gw3] [ 16%] PASSED tests/test_papers.py::TestDuplicatesGood::test_conflictdoi 
tests/test_papers.py::TestDuplicatesGood::test_conflictyear 
[gw3] [ 17%] PASSED tests/test_papers.py::TestDuplicatesGood::test_conflictyear 
tests/test_papers.py::TestDuplicatesGood::test_exactsame 
[gw0] [ 18%] FAILED tests/test_papers.py::TestSimple::test_fetch 
tests/test_papers.py::TestDuplicatesExact::test_exactsame 
[gw3] [ 19%] PASSED tests/test_papers.py::TestDuplicatesGood::test_exactsame 
tests/test_papers.py::TestDuplicatesGood::test_missingdoi 
[gw0] [ 20%] PASSED tests/test_papers.py::TestDuplicatesExact::test_exactsame 
tests/test_papers.py::TestDuplicatesExact::test_missingdoi 
[gw3] [ 21%] PASSED tests/test_papers.py::TestDuplicatesGood::test_missingdoi 
tests/test_papers.py::TestDuplicatesGood::test_missingfield 
[gw0] [ 22%] PASSED tests/test_papers.py::TestDuplicatesExact::test_missingdoi 
tests/test_papers.py::TestDuplicatesExact::test_missingfield 
[gw3] [ 23%] PASSED tests/test_papers.py::TestDuplicatesGood::test_missingfield 
tests/test_papers.py::TestDuplicatesGood::test_missingtitauthor 
[gw0] [ 24%] PASSED tests/test_papers.py::TestDuplicatesExact::test_missingfield 
tests/test_papers.py::TestDuplicatesExact::test_missingtitauthor 
[gw0] [ 25%] PASSED tests/test_papers.py::TestDuplicatesExact::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesGood::test_anotherkey 
[gw3] [ 26%] PASSED tests/test_papers.py::TestDuplicatesGood::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesFair::test_anotherkey 
[gw0] [ 27%] PASSED tests/test_papers.py::TestDuplicatesGood::test_anotherkey 
tests/test_papers.py::TestDuplicatesGood::test_conflictauthor 
[gw3] [ 28%] PASSED tests/test_papers.py::TestDuplicatesFair::test_anotherkey 
tests/test_papers.py::TestDuplicatesFair::test_conflictauthor 
[gw0] [ 29%] PASSED tests/test_papers.py::TestDuplicatesGood::test_conflictauthor 
tests/test_papers.py::TestDuplicatesFair::test_missingdoi 
[gw3] [ 30%] PASSED tests/test_papers.py::TestDuplicatesFair::test_conflictauthor 
tests/test_papers.py::TestDuplicatesFair::test_conflictdoi 
[gw0] [ 31%] PASSED tests/test_papers.py::TestDuplicatesFair::test_missingdoi 
tests/test_papers.py::TestDuplicatesFair::test_missingfield 
[gw3] [ 32%] PASSED tests/test_papers.py::TestDuplicatesFair::test_conflictdoi 
tests/test_papers.py::TestDuplicatesFair::test_conflictyear 
[gw0] [ 33%] PASSED tests/test_papers.py::TestDuplicatesFair::test_missingfield 
tests/test_papers.py::TestDuplicatesFair::test_missingtitauthor 
[gw0] [ 33%] PASSED tests/test_papers.py::TestDuplicatesFair::test_missingtitauthor 
tests/test_papers.py::TestDuplicatesPartial::test_anotherkey 
[gw3] [ 34%] PASSED tests/test_papers.py::TestDuplicatesFair::test_conflictyear 
tests/test_papers.py::TestDuplicatesFair::test_exactsame 
[gw3] [ 35%] PASSED tests/test_papers.py::TestDuplicatesFair::test_exactsame 
tests/test_papers.py::TestDuplicatesPartial::test_conflictdoi 
[gw0] [ 36%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_anotherkey 
tests/test_papers.py::TestDuplicatesPartial::test_conflictauthor 
[gw3] [ 37%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_conflictdoi 
[gw0] [ 38%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_conflictauthor 
tests/test_papers.py::TestDuplicatesPartial::test_conflictyear 
tests/test_papers.py::TestDuplicatesPartial::test_missingtitauthor 
[gw0] [ 39%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_missingtitauthor 
tests/test_papers.py::TestDuplicates::test_anotherkey 
[gw3] [ 40%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_conflictyear 
tests/test_papers.py::TestDuplicatesPartial::test_exactsame 
[gw0] [ 41%] PASSED tests/test_papers.py::TestDuplicates::test_anotherkey 
tests/test_papers.py::TestDuplicates::test_conflictauthor 
[gw3] [ 42%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_exactsame 
tests/test_papers.py::TestDuplicatesPartial::test_missingdoi 
[gw0] [ 43%] PASSED tests/test_papers.py::TestDuplicates::test_conflictauthor 
tests/test_papers.py::TestDuplicates::test_conflictdoi 
[gw3] [ 44%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_missingdoi 
[gw0] [ 45%] PASSED tests/test_papers.py::TestDuplicates::test_conflictdoi 
tests/test_papers.py::TestDuplicatesPartial::test_missingfield 
tests/test_papers.py::TestDuplicates::test_conflictyear 
[gw0] [ 46%] PASSED tests/test_papers.py::TestDuplicates::test_conflictyear 
tests/test_papers.py::TestDuplicates::test_exactsame 
[gw2] [ 47%] FAILED tests/test_papers.py::TestAdd2::test_add_rename 
tests/test_papers.py::TestAdd2::test_add_rename_copy 
[gw3] [ 48%] PASSED tests/test_papers.py::TestDuplicatesPartial::test_missingfield 
tests/test_papers.py::TestDuplicates::test_missingtitauthor 
[gw0] [ 49%] PASSED tests/test_papers.py::TestDuplicates::test_exactsame 
tests/test_papers.py::TestDuplicates::test_missingdoi 
[gw1] [ 50%] FAILED tests/test_papers.py::TestAdd::test_add_rename 
[gw3] [ 51%] PASSED tests/test_papers.py::TestDuplicates::test_missingtitauthor 
tests/test_papers.py::TestAdd::test_add_rename_copy 
tests/test_papers.py::TestDuplicatesAdd::test_anotherkey 
[gw3] [ 52%] SKIPPED tests/test_papers.py::TestDuplicatesAdd::test_anotherkey 
tests/test_papers.py::TestDuplicatesAdd::test_conflictauthor 
[gw0] [ 53%] PASSED tests/test_papers.py::TestDuplicates::test_missingdoi 
tests/test_papers.py::TestDuplicates::test_missingfield 
[gw0] [ 54%] PASSED tests/test_papers.py::TestDuplicates::test_missingfield 
tests/test_papers.py::TestDuplicatesAdd::test_conflictyear 
[gw3] [ 55%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_conflictauthor 
tests/test_papers.py::TestDuplicatesAdd::test_conflictdoi 
[gw0] [ 56%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_conflictyear 
tests/test_papers.py::TestDuplicatesAdd::test_exactsame 
[gw0] [ 57%] SKIPPED tests/test_papers.py::TestDuplicatesAdd::test_exactsame 
tests/test_papers.py::TestDuplicatesAdd::test_missingdoi 
[gw2] [ 58%] FAILED tests/test_papers.py::TestAdd2::test_add_rename_copy 
tests/test_papers.py::TestAdd2::test_fails_without_install 
[gw2] [ 59%] PASSED tests/test_papers.py::TestAdd2::test_fails_without_install 
tests/test_papers.py::TestAddBib::test_addbib 
[gw1] [ 60%] FAILED tests/test_papers.py::TestAdd::test_add_rename_copy 
[gw2] [ 61%] PASSED tests/test_papers.py::TestAddBib::test_addbib 
tests/test_papers.py::TestAdd::test_fails_without_install 
tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original_but_originalkey 
[gw1] [ 62%] PASSED tests/test_papers.py::TestAdd::test_fails_without_install 
tests/test_papers.py::TestAddResolveDuplicate::test_raises 
[gw3] [ 63%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_conflictdoi 
tests/test_papers.py::TestDuplicatesAdd::test_missingtitauthor 
[gw0] [ 64%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_missingdoi 
tests/test_papers.py::TestDuplicatesAdd::test_missingfield 
[gw1] [ 65%] PASSED tests/test_papers.py::TestAddResolveDuplicate::test_raises 
tests/test_papers.py::TestAddResolveDuplicate::test_skip 
[gw2] [ 66%] FAILED tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original_but_originalkey 
tests/test_papers.py::TestAddResolveDuplicate::test_original_updated_from_conflict 
[gw3] [ 66%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_missingtitauthor 
tests/test_papers.py::TestAddResolveDuplicate::test_append 
[gw0] [ 67%] PASSED tests/test_papers.py::TestDuplicatesAdd::test_missingfield 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_append 
[gw1] [ 68%] FAILED tests/test_papers.py::TestAddResolveDuplicate::test_skip 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original_but_originalkey 
[gw2] [ 69%] FAILED tests/test_papers.py::TestAddResolveDuplicate::test_original_updated_from_conflict 
tests/test_papers.py::TestAddResolveDuplicate::test_overwrite 
[gw3] [ 70%] FAILED tests/test_papers.py::TestAddResolveDuplicate::test_append 
tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original 
[gw0] [ 71%] FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_append 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original 
[gw1] [ 72%] FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original_but_originalkey 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_original_updated_from_conflict 
[gw2] [ 73%] FAILED tests/test_papers.py::TestAddResolveDuplicate::test_overwrite 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_overwrite 
[gw0] [ 74%] FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original 
tests/test_papers.py::TestCheckResolveDuplicate::test_merge 
[gw3] [ 75%] FAILED tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_skip 
[gw1] [ 76%] FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_original_updated_from_conflict 
tests/test_papers.py::TestCheckResolveDuplicate::test_not_a_duplicate 
[gw0] [ 77%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_merge 
tests/test_papers.py::TestCheckResolveDuplicate::test_pick_conflict_1 
[gw2] [ 78%] FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_overwrite 
tests/test_papers.py::TestAddResolveDuplicateCommand::test_raises 
[gw3] [ 79%] FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_skip 
tests/test_papers.py::TestCheckResolveDuplicate::test_pick_reference_2 
[gw1] [ 80%] FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_not_a_duplicate 
tests/test_papers.py::TestCheckResolveDuplicate::test_raises 
[gw0] [ 81%] FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_pick_conflict_1 
tests/test_papers.py::TestCheckResolveDuplicate::test_skip_check 
[gw2] [ 82%] PASSED tests/test_papers.py::TestAddResolveDuplicateCommand::test_raises 
tests/test_papers.py::TestAddConflict::test_add_conflict_key_check_raises 
[gw1] [ 83%] PASSED tests/test_papers.py::TestCheckResolveDuplicate::test_raises 
tests/test_papers.py::TestAddConflict::test_add_conflict_key_update 
[gw3] [ 84%] FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_pick_reference_2 
tests/test_papers.py::TestAddConflict::test_add_conflict_key_nocheck_raises 
[gw2] [ 85%] PASSED tests/test_papers.py::TestAddConflict::test_add_conflict_key_check_raises 
tests/test_papers.py::TestAddConflict::test_add_miss_field_fails 
[gw0] [ 86%] FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_skip_check 
tests/test_papers.py::TestAddConflict::test_add_miss_doi_merge 
[gw3] [ 87%] PASSED tests/test_papers.py::TestAddConflict::test_add_conflict_key_nocheck_raises 
tests/test_papers.py::TestAddConflict::test_add_miss_titauthor_merge 
[gw1] [ 88%] FAILED tests/test_papers.py::TestAddConflict::test_add_conflict_key_update 
tests/test_papers.py::TestAddConflict::test_add_miss_merge 
[gw2] [ 89%] PASSED tests/test_papers.py::TestAddConflict::test_add_miss_field_fails 
tests/test_papers.py::TestAddConflict::test_add_same 
[gw3] [ 90%] FAILED tests/test_papers.py::TestAddConflict::test_add_miss_titauthor_merge 
tests/test_papers.py::TestAddConflict::test_add_same_but_key_fails 
[gw3] [ 91%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_but_key_fails 
tests/test_papers.py::TestAddConflict::test_add_same_doi_fails 
[gw0] [ 92%] FAILED tests/test_papers.py::TestAddConflict::test_add_miss_doi_merge 
tests/test_papers.py::TestAddConflict::test_add_same_but_file 
[gw2] [ 93%] FAILED tests/test_papers.py::TestAddConflict::test_add_same 
tests/test_papers.py::TestAddConflict::test_add_same_but_key_update 
[gw1] [ 94%] FAILED tests/test_papers.py::TestAddConflict::test_add_miss_merge 
tests/test_papers.py::TestAddConflict::test_add_same_but_key_interactive 
[gw3] [ 95%] PASSED tests/test_papers.py::TestAddConflict::test_add_same_doi_fails 
tests/test_papers.py::TestAddConflict::test_add_same_doi_unchecked 
[gw0] [ 96%] FAILED tests/test_papers.py::TestAddConflict::test_add_same_but_file 
tests/test_papers.py::TestAddConflict::test_add_same_doi_update_key 
[gw2] [ 97%] FAILED tests/test_papers.py::TestAddConflict::test_add_same_but_key_update 
[gw1] [ 98%] FAILED tests/test_papers.py::TestAddConflict::test_add_same_but_key_interactive 
[gw0] [ 99%] FAILED tests/test_papers.py::TestAddConflict::test_add_same_doi_update_key 
[gw3] [100%] FAILED tests/test_papers.py::TestAddConflict::test_add_same_doi_unchecked 

============================================================= FAILURES ==============================================================
_________________________________________________________ TestAdd2.test_add _________________________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd2 testMethod=test_add>

    def test_add(self):
        self.assertTrue(os.path.exists(self.mybib))
        print("bibtex", self.mybib, 'exists?', os.path.exists(self.mybib))
>       sp.check_call('papers add --bibtex {} {}'.format(
            self.mybib, self.pdf), shell=True)

tests/test_papers.py:177: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add --bibtex /tmp/papers.bibejjm1ldo /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add --bibtex /tmp/papers.bibejjm1ldo /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add --bibtex /tmp/papers.bibejjm1ldo /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stdout call --------------------------------------------------------
bibtex /tmp/papers.bibejjm1ldo exists? True
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
____________________________________________________ TestAddDir.test_adddir_pdf _____________________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddDir testMethod=test_adddir_pdf>

    def setUp(self):
        self.pdf1, self.doi, self.key1, self.newkey1, self.year, self.bibtex1, self.file_rename1 = prepare_paper()
        self.pdf2, self.si, self.doi, self.key2, self.newkey2, self.year, self.bibtex2, self.file_rename2 = prepare_paper2()
        self.somedir = tempfile.mktemp(prefix='papers.somedir')
        self.subdir = os.path.join(self.somedir, 'subdir')
        os.makedirs(self.somedir)
        os.makedirs(self.subdir)
        shutil.copy(self.pdf1, self.somedir)
        shutil.copy(self.pdf2, self.subdir)
        self.mybib = tempfile.mktemp(prefix='papers.bib')
>       sp.check_call('papers install --local --no-prompt --bibtex {}'.format(self.mybib), shell=True)

tests/test_papers.py:302: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers install --local --no-prompt --bibtex /tmp/papers.bib9zlb68el',), kwargs = {'shell': True}, retcode = 1
cmd = 'papers install --local --no-prompt --bibtex /tmp/papers.bib9zlb68el'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers install --local --no-prompt --bibtex /tmp/papers.bib9zlb68el' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
__________________________________________________ TestInstall.test_local_install ___________________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestInstall testMethod=test_local_install>

    def test_local_install(self):
>       sp.check_call('papers install --local --bibtex {} --files {}'.format(self.mybib, self.filesdir),
            shell=True)

tests/test_papers.py:120: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers install --local --bibtex /tmp/papers.bibov4zwjlz --files /tmp/papers.filesi592xyq2',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers install --local --bibtex /tmp/papers.bibov4zwjlz --files /tmp/papers.filesi592xyq2'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers install --local --bibtex /tmp/papers.bibov4zwjlz --files /tmp/papers.filesi592xyq2' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
________________________________________________________ TestSimple.test_doi ________________________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestSimple testMethod=test_doi>

    def test_doi(self):
>       self.assertEqual(run('papers doi '+self.pdf).strip(), self.doi)

tests/test_papers.py:102: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_papers.py:13: in run
    return str(sp.check_output(cmd, shell=True).strip().decode())
../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:466: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True
popenargs = ('papers doi /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf',)
kwargs = {'shell': True, 'stdout': -1}, process = <Popen: returncode: 1 args: 'papers doi /home/boyan/boyanshouse/Vazhno/Work/...>
stdout = b'', stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,
        or pass capture_output=True to capture both.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command 'papers doi /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:571: CalledProcessError
------------------------------------------------------- Captured stdout call --------------------------------------------------------
papers doi /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________________ TestAdd2.test_add_attachment ____________________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd2 testMethod=test_add_attachment>

    def test_add_attachment(self):
>       sp.check_call('papers add -rc --bibtex {} --filesdir {} {} -a {}'.format(
            self.mybib, self.filesdir, self.pdf, self.si), shell=True)

tests/test_papers.py:242: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add -rc --bibtex /tmp/papers.bibtnh5ja1e --filesdir /tmp/papers.filesdmpxhi1w /home/boyan/boyanshouse/Vazhno/.../esd-4-11-2013.pdf -a /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013-supplement.pdf',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add -rc --bibtex /tmp/papers.bibtnh5ja1e --filesdir /tmp/papers.filesdmpxhi1w /home/boyan/boyanshouse/Vazhno/W...rs/esd-4-11-2013.pdf -a /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013-supplement.pdf'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add -rc --bibtex /tmp/papers.bibtnh5ja1e --filesdir /tmp/papers.filesdmpxhi1w /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf -a /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013-supplement.pdf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_________________________________________________________ TestAdd.test_add __________________________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd testMethod=test_add>

    def test_add(self):
        self.assertTrue(os.path.exists(self.mybib))
        print("bibtex", self.mybib, 'exists?', os.path.exists(self.mybib))
>       sp.check_call('papers add --bibtex {} {}'.format(
            self.mybib, self.pdf), shell=True)

tests/test_papers.py:177: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add --bibtex /tmp/papers.bibspeo15_x /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add --bibtex /tmp/papers.bibspeo15_x /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add --bibtex /tmp/papers.bibspeo15_x /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stdout call --------------------------------------------------------
bibtex /tmp/papers.bibspeo15_x exists? True
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
__________________________________________________ TestAddDir.test_adddir_pdf_cmd ___________________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddDir testMethod=test_adddir_pdf_cmd>

    def setUp(self):
        self.pdf1, self.doi, self.key1, self.newkey1, self.year, self.bibtex1, self.file_rename1 = prepare_paper()
        self.pdf2, self.si, self.doi, self.key2, self.newkey2, self.year, self.bibtex2, self.file_rename2 = prepare_paper2()
        self.somedir = tempfile.mktemp(prefix='papers.somedir')
        self.subdir = os.path.join(self.somedir, 'subdir')
        os.makedirs(self.somedir)
        os.makedirs(self.subdir)
        shutil.copy(self.pdf1, self.somedir)
        shutil.copy(self.pdf2, self.subdir)
        self.mybib = tempfile.mktemp(prefix='papers.bib')
>       sp.check_call('papers install --local --no-prompt --bibtex {}'.format(self.mybib), shell=True)

tests/test_papers.py:302: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers install --local --no-prompt --bibtex /tmp/papers.bibx2jyxvrk',), kwargs = {'shell': True}, retcode = 1
cmd = 'papers install --local --no-prompt --bibtex /tmp/papers.bibx2jyxvrk'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers install --local --no-prompt --bibtex /tmp/papers.bibx2jyxvrk' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_______________________________________________________ TestSimple.test_fetch _______________________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestSimple testMethod=test_fetch>

    def test_fetch(self):
>       bibtexs = run('papers fetch '+self.doi).strip()

tests/test_papers.py:105: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_papers.py:13: in run
    return str(sp.check_output(cmd, shell=True).strip().decode())
../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:466: in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

input = None, capture_output = False, timeout = None, check = True, popenargs = ('papers fetch 10.5194/bg-8-515-2011',)
kwargs = {'shell': True, 'stdout': -1}, process = <Popen: returncode: 1 args: 'papers fetch 10.5194/bg-8-515-2011'>, stdout = b''
stderr = None, retcode = 1

    def run(*popenargs,
            input=None, capture_output=False, timeout=None, check=False, **kwargs):
        """Run command with arguments and return a CompletedProcess instance.

        The returned instance will have attributes args, returncode, stdout and
        stderr. By default, stdout and stderr are not captured, and those attributes
        will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them,
        or pass capture_output=True to capture both.

        If check is True and the exit code was non-zero, it raises a
        CalledProcessError. The CalledProcessError object will have the return code
        in the returncode attribute, and output & stderr attributes if those streams
        were captured.

        If timeout is given, and the process takes too long, a TimeoutExpired
        exception will be raised.

        There is an optional argument "input", allowing you to
        pass bytes or a string to the subprocess's stdin.  If you use this argument
        you may not also use the Popen constructor's "stdin" argument, as
        it will be used internally.

        By default, all communication is in bytes, and therefore any "input" should
        be bytes, and the stdout and stderr will be bytes. If in text mode, any
        "input" should be a string, and stdout and stderr will be strings decoded
        according to locale encoding, or by "encoding" if set. Text mode is
        triggered by setting any of text, encoding, errors or universal_newlines.

        The other arguments are the same as for the Popen constructor.
        """
        if input is not None:
            if kwargs.get('stdin') is not None:
                raise ValueError('stdin and input arguments may not both be used.')
            kwargs['stdin'] = PIPE

        if capture_output:
            if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
                raise ValueError('stdout and stderr arguments may not be used '
                                 'with capture_output.')
            kwargs['stdout'] = PIPE
            kwargs['stderr'] = PIPE

        with Popen(*popenargs, **kwargs) as process:
            try:
                stdout, stderr = process.communicate(input, timeout=timeout)
            except TimeoutExpired as exc:
                process.kill()
                if _mswindows:
                    # Windows accumulates the output in a single blocking
                    # read() call run on child threads, with the timeout
                    # being done in a join() on those threads.  communicate()
                    # _after_ kill() is required to collect that and add it
                    # to the exception.
                    exc.stdout, exc.stderr = process.communicate()
                else:
                    # POSIX _communicate already populated the output so
                    # far into the TimeoutExpired exception.
                    process.wait()
                raise
            except:  # Including KeyboardInterrupt, communicate handled that.
                process.kill()
                # We don't call process.wait() as .__exit__ does that for us.
                raise
            retcode = process.poll()
            if check and retcode:
>               raise CalledProcessError(retcode, process.args,
                                         output=stdout, stderr=stderr)
E               subprocess.CalledProcessError: Command 'papers fetch 10.5194/bg-8-515-2011' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:571: CalledProcessError
------------------------------------------------------- Captured stdout call --------------------------------------------------------
papers fetch 10.5194/bg-8-515-2011
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_____________________________________________________ TestAdd2.test_add_rename ______________________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd2 testMethod=test_add_rename>

    def test_add_rename(self):

        pdfcopy = tempfile.mktemp(prefix='myref_test', suffix='.pdf')
        shutil.copy(self.pdf, pdfcopy)

>       sp.check_call('papers add -r --bibtex {} --filesdir {} {} --debug'.format(
            self.mybib, self.filesdir, pdfcopy), shell=True)

tests/test_papers.py:213: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add -r --bibtex /tmp/papers.biby9jvt0sc --filesdir /tmp/papers.files0tuulhrr /tmp/myref_test8ltivyfr.pdf --debug',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add -r --bibtex /tmp/papers.biby9jvt0sc --filesdir /tmp/papers.files0tuulhrr /tmp/myref_test8ltivyfr.pdf --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add -r --bibtex /tmp/papers.biby9jvt0sc --filesdir /tmp/papers.files0tuulhrr /tmp/myref_test8ltivyfr.pdf --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
______________________________________________________ TestAdd.test_add_rename ______________________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd testMethod=test_add_rename>

    def test_add_rename(self):

        pdfcopy = tempfile.mktemp(prefix='myref_test', suffix='.pdf')
        shutil.copy(self.pdf, pdfcopy)

>       sp.check_call('papers add -r --bibtex {} --filesdir {} {} --debug'.format(
            self.mybib, self.filesdir, pdfcopy), shell=True)

tests/test_papers.py:213: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add -r --bibtex /tmp/papers.bib5yc_nv9w --filesdir /tmp/papers.files1zeypi6s /tmp/myref_testwu2hwscq.pdf --debug',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add -r --bibtex /tmp/papers.bib5yc_nv9w --filesdir /tmp/papers.files1zeypi6s /tmp/myref_testwu2hwscq.pdf --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add -r --bibtex /tmp/papers.bib5yc_nv9w --filesdir /tmp/papers.files1zeypi6s /tmp/myref_testwu2hwscq.pdf --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________________ TestAdd2.test_add_rename_copy ___________________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd2 testMethod=test_add_rename_copy>

    def test_add_rename_copy(self):

>       sp.check_call('papers add -rc --bibtex {} --filesdir {} {}'.format(
            self.mybib, self.filesdir, self.pdf), shell=True)

tests/test_papers.py:199: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add -rc --bibtex /tmp/papers.bibumwjbetk --filesdir /tmp/papers.filespuqvfda2 /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add -rc --bibtex /tmp/papers.bibumwjbetk --filesdir /tmp/papers.filespuqvfda2 /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add -rc --bibtex /tmp/papers.bibumwjbetk --filesdir /tmp/papers.filespuqvfda2 /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/esd-4-11-2013.pdf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________________ TestAdd.test_add_rename_copy ____________________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAdd testMethod=test_add_rename_copy>

    def test_add_rename_copy(self):

>       sp.check_call('papers add -rc --bibtex {} --filesdir {} {}'.format(
            self.mybib, self.filesdir, self.pdf), shell=True)

tests/test_papers.py:199: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add -rc --bibtex /tmp/papers.bibx0f_qqrw --filesdir /tmp/papers.filesdo18w713 /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add -rc --bibtex /tmp/papers.bibx0f_qqrw --filesdir /tmp/papers.filesdo18w713 /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add -rc --bibtex /tmp/papers.bibx0f_qqrw --filesdir /tmp/papers.filesdo18w713 /home/boyan/boyanshouse/Vazhno/Work/papers/tests/downloadedpapers/bg-8-515-2011.pdf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
____________________________ TestAddResolveDuplicate.test_conflict_updated_from_original_but_originalkey ____________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicate testMethod=test_conflict_updated_from_original_but_originalkey>

        def test_conflict_updated_from_original_but_originalkey(self):

            expected = """@article{Perrette_2011,
     author = {New Author Field},
     doi = {10.5194/bg-8-515-2011},
     journal = {ConflictJournal},
     year = {RareYear}
    }"""
            open(self.otherbib, 'w').write(self.conflict)
>           sp.check_call(self.command('U') + ' --update-key', shell=True)

tests/test_papers.py:613: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo U | papers add /tmp/papers.otherbibvvuer5m4 --bibtex /tmp/papers.bibp0nvks6f --debug --update-key',)
kwargs = {'shell': True}, retcode = 1
cmd = 'echo U | papers add /tmp/papers.otherbibvvuer5m4 --bibtex /tmp/papers.bibp0nvks6f --debug --update-key'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo U | papers add /tmp/papers.otherbibvvuer5m4 --bibtex /tmp/papers.bibp0nvks6f --debug --update-key' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_________________________________________________ TestAddResolveDuplicate.test_skip _________________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicate testMethod=test_skip>

    def test_skip(self):

        expected = self.original

        open(self.otherbib, 'w').write(self.conflict)
>       sp.check_call(self.command('s'), shell=True)

tests/test_papers.py:558: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo s | papers add /tmp/papers.otherbiby1v5gp5e --bibtex /tmp/papers.bib8gopqu5w --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'echo s | papers add /tmp/papers.otherbiby1v5gp5e --bibtex /tmp/papers.bib8gopqu5w --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo s | papers add /tmp/papers.otherbiby1v5gp5e --bibtex /tmp/papers.bib8gopqu5w --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
____________________________________ TestAddResolveDuplicate.test_original_updated_from_conflict ____________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicate testMethod=test_original_updated_from_conflict>

        def test_original_updated_from_conflict(self):

            expected = """@article{Perrette_2011,
     author = {New Author Field},
     doi = {10.5194/bg-8-515-2011},
     journal = {Biogeosciences},
     year = {RareYear}
    }"""

            open(self.otherbib, 'w').write(self.conflict)
>           sp.check_call(self.command('u'), shell=True)

tests/test_papers.py:586: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo u | papers add /tmp/papers.otherbibu4bf1s7g --bibtex /tmp/papers.bibw9ms1z4g --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'echo u | papers add /tmp/papers.otherbibu4bf1s7g --bibtex /tmp/papers.bibw9ms1z4g --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo u | papers add /tmp/papers.otherbibu4bf1s7g --bibtex /tmp/papers.bibw9ms1z4g --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
________________________________________________ TestAddResolveDuplicate.test_append ________________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicate testMethod=test_append>

    def test_append(self):
        open(self.otherbib, 'w').write(self.conflict)
>       sp.check_call(self.command('a'), shell=True)

tests/test_papers.py:563: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo a | papers add /tmp/papers.otherbibtd0t_eny --bibtex /tmp/papers.bibz0zw6w1n --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'echo a | papers add /tmp/papers.otherbibtd0t_eny --bibtex /tmp/papers.bibz0zw6w1n --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo a | papers add /tmp/papers.otherbibtd0t_eny --bibtex /tmp/papers.bibz0zw6w1n --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
____________________________________________ TestAddResolveDuplicateCommand.test_append _____________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicateCommand testMethod=test_append>

    def test_append(self):
        open(self.otherbib, 'w').write(self.conflict)
>       sp.check_call(self.command('a'), shell=True)

tests/test_papers.py:563: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibewe8ii95 --bibtex /tmp/papers.bibfjhzzgpk --mode a --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbibewe8ii95 --bibtex /tmp/papers.bibfjhzzgpk --mode a --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibewe8ii95 --bibtex /tmp/papers.bibfjhzzgpk --mode a --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
________________________ TestAddResolveDuplicateCommand.test_conflict_updated_from_original_but_originalkey _________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicateCommand testMethod=test_conflict_updated_from_original_but_originalkey>

        def test_conflict_updated_from_original_but_originalkey(self):

            expected = """@article{Perrette_2011,
     author = {New Author Field},
     doi = {10.5194/bg-8-515-2011},
     journal = {ConflictJournal},
     year = {RareYear}
    }"""
            open(self.otherbib, 'w').write(self.conflict)
>           sp.check_call(self.command('U') + ' --update-key', shell=True)

tests/test_papers.py:613: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibj7f28hka --bibtex /tmp/papers.bibaqvrrqxl --mode U --debug --update-key',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibj7f28hka --bibtex /tmp/papers.bibaqvrrqxl --mode U --debug --update-key'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibj7f28hka --bibtex /tmp/papers.bibaqvrrqxl --mode U --debug --update-key' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
______________________________________________ TestAddResolveDuplicate.test_overwrite _______________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicate testMethod=test_overwrite>

    def test_overwrite(self):

        expected = self.conflict

        open(self.otherbib, 'w').write(self.conflict)
>       sp.check_call(self.command('o'), shell=True)

tests/test_papers.py:549: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo o | papers add /tmp/papers.otherbib8g7kr_x2 --bibtex /tmp/papers.bib44rat69o --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'echo o | papers add /tmp/papers.otherbib8g7kr_x2 --bibtex /tmp/papers.bib44rat69o --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo o | papers add /tmp/papers.otherbib8g7kr_x2 --bibtex /tmp/papers.bib44rat69o --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
________________________________ TestAddResolveDuplicateCommand.test_conflict_updated_from_original _________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicateCommand testMethod=test_conflict_updated_from_original>

        def test_conflict_updated_from_original(self):

            expected = """@article{AnotherKey,
     author = {New Author Field},
     doi = {10.5194/bg-8-515-2011},
     journal = {ConflictJournal},
     year = {RareYear}
    }"""

            open(self.otherbib, 'w').write(self.conflict)
>           sp.check_call(self.command('U'), shell=True)

tests/test_papers.py:600: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibi7p6okhx --bibtex /tmp/papers.bibcp0t2p1z --mode U --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbibi7p6okhx --bibtex /tmp/papers.bibcp0t2p1z --mode U --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibi7p6okhx --bibtex /tmp/papers.bibcp0t2p1z --mode U --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
____________________________________ TestAddResolveDuplicate.test_conflict_updated_from_original ____________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicate testMethod=test_conflict_updated_from_original>

        def test_conflict_updated_from_original(self):

            expected = """@article{AnotherKey,
     author = {New Author Field},
     doi = {10.5194/bg-8-515-2011},
     journal = {ConflictJournal},
     year = {RareYear}
    }"""

            open(self.otherbib, 'w').write(self.conflict)
>           sp.check_call(self.command('U'), shell=True)

tests/test_papers.py:600: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo U | papers add /tmp/papers.otherbibvi0631qs --bibtex /tmp/papers.bib53r_fxab --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'echo U | papers add /tmp/papers.otherbibvi0631qs --bibtex /tmp/papers.bib53r_fxab --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo U | papers add /tmp/papers.otherbibvi0631qs --bibtex /tmp/papers.bib53r_fxab --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
________________________________ TestAddResolveDuplicateCommand.test_original_updated_from_conflict _________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicateCommand testMethod=test_original_updated_from_conflict>

        def test_original_updated_from_conflict(self):

            expected = """@article{Perrette_2011,
     author = {New Author Field},
     doi = {10.5194/bg-8-515-2011},
     journal = {Biogeosciences},
     year = {RareYear}
    }"""

            open(self.otherbib, 'w').write(self.conflict)
>           sp.check_call(self.command('u'), shell=True)

tests/test_papers.py:586: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbiblel0dynn --bibtex /tmp/papers.bibwkcmlid4 --mode u --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbiblel0dynn --bibtex /tmp/papers.bibwkcmlid4 --mode u --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbiblel0dynn --bibtex /tmp/papers.bibwkcmlid4 --mode u --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________ TestAddResolveDuplicateCommand.test_overwrite ___________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicateCommand testMethod=test_overwrite>

    def test_overwrite(self):

        expected = self.conflict

        open(self.otherbib, 'w').write(self.conflict)
>       sp.check_call(self.command('o'), shell=True)

tests/test_papers.py:549: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibcuiertdn --bibtex /tmp/papers.bib9pzbmc9f --mode o --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbibcuiertdn --bibtex /tmp/papers.bib9pzbmc9f --mode o --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibcuiertdn --bibtex /tmp/papers.bib9pzbmc9f --mode o --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_____________________________________________ TestAddResolveDuplicateCommand.test_skip ______________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddResolveDuplicateCommand testMethod=test_skip>

    def test_skip(self):

        expected = self.original

        open(self.otherbib, 'w').write(self.conflict)
>       sp.check_call(self.command('s'), shell=True)

tests/test_papers.py:558: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbib1g1ukyt5 --bibtex /tmp/papers.bibqygtpwvc --mode s --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbib1g1ukyt5 --bibtex /tmp/papers.bibqygtpwvc --mode s --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbib1g1ukyt5 --bibtex /tmp/papers.bibqygtpwvc --mode s --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
__________________________________________ TestCheckResolveDuplicate.test_not_a_duplicate ___________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestCheckResolveDuplicate testMethod=test_not_a_duplicate>

    def test_not_a_duplicate(self):

        expected = self.conflict + '\n\n' + self.original

>       sp.check_call(self.command('n'), shell=True)

tests/test_papers.py:678: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo n | papers check --duplicates --bibtex /tmp/papers.bibhcd9m3sk --debug',), kwargs = {'shell': True}, retcode = 1
cmd = 'echo n | papers check --duplicates --bibtex /tmp/papers.bibhcd9m3sk --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo n | papers check --duplicates --bibtex /tmp/papers.bibhcd9m3sk --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
__________________________________________ TestCheckResolveDuplicate.test_pick_conflict_1 ___________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestCheckResolveDuplicate testMethod=test_pick_conflict_1>

    def test_pick_conflict_1(self):

        expected = self.conflict

>       sp.check_call(self.command('1'), shell=True)

tests/test_papers.py:655: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo 1 | papers check --duplicates --bibtex /tmp/papers.bibgu7jca2e --debug',), kwargs = {'shell': True}, retcode = 1
cmd = 'echo 1 | papers check --duplicates --bibtex /tmp/papers.bibgu7jca2e --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo 1 | papers check --duplicates --bibtex /tmp/papers.bibgu7jca2e --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
__________________________________________ TestCheckResolveDuplicate.test_pick_reference_2 __________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestCheckResolveDuplicate testMethod=test_pick_reference_2>

    def test_pick_reference_2(self):

        expected = self.original

>       sp.check_call(self.command('2'), shell=True)

tests/test_papers.py:662: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo 2 | papers check --duplicates --bibtex /tmp/papers.bibg8w3m0mc --debug',), kwargs = {'shell': True}, retcode = 1
cmd = 'echo 2 | papers check --duplicates --bibtex /tmp/papers.bibg8w3m0mc --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo 2 | papers check --duplicates --bibtex /tmp/papers.bibg8w3m0mc --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_____________________________________________ TestCheckResolveDuplicate.test_skip_check _____________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestCheckResolveDuplicate testMethod=test_skip_check>

    def test_skip_check(self):

        expected = self.conflict + '\n\n' + self.original

>       sp.check_call(self.command('s'), shell=True)

tests/test_papers.py:670: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo s | papers check --duplicates --bibtex /tmp/papers.bibllwk02jr --debug',), kwargs = {'shell': True}, retcode = 1
cmd = 'echo s | papers check --duplicates --bibtex /tmp/papers.bibllwk02jr --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo s | papers check --duplicates --bibtex /tmp/papers.bibllwk02jr --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________ TestAddConflict.test_add_conflict_key_update ____________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_conflict_key_update>

    def test_add_conflict_key_update(self):
        # key conflict and update entry
        open(self.otherbib, 'w').write(self.bibtex_conflict_key)
>       sp.check_call('papers add {} --bibtex {} -u'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:874: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibydfl20ke --bibtex /tmp/papers.bibjr_5oman -u',), kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibydfl20ke --bibtex /tmp/papers.bibjr_5oman -u'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibydfl20ke --bibtex /tmp/papers.bibjr_5oman -u' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________ TestAddConflict.test_add_miss_titauthor_merge ___________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_miss_titauthor_merge>

    def test_add_miss_titauthor_merge(self):
        # miss field but merges
        open(self.otherbib, 'w').write(self.bibtex_miss_titauthor_field)
>       sp.check_call('papers add {} --mode u --bibtex {} --debug'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:921: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibk985ao93 --mode u --bibtex /tmp/papers.bibw__1l3gk --debug',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbibk985ao93 --mode u --bibtex /tmp/papers.bibw__1l3gk --debug'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibk985ao93 --mode u --bibtex /tmp/papers.bibw__1l3gk --debug' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
______________________________________________ TestAddConflict.test_add_miss_doi_merge ______________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_miss_doi_merge>

    def test_add_miss_doi_merge(self):
        # miss field but merges
        open(self.otherbib, 'w').write(self.bibtex_miss_doi_field)
>       sp.check_call('papers add {} --mode u --bibtex {}'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:914: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbib83ix49kf --mode u --bibtex /tmp/papers.bibl_5ck6bf',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbib83ix49kf --mode u --bibtex /tmp/papers.bibl_5ck6bf'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbib83ix49kf --mode u --bibtex /tmp/papers.bibl_5ck6bf' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________________ TestAddConflict.test_add_same ___________________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_same>

    def test_add_same(self):
        open(self.otherbib, 'w').write(self.bibtex)
>       sp.check_call('papers add {} --bibtex {}'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:823: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibqem_5jn5 --bibtex /tmp/papers.bibq7ey84d2',), kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibqem_5jn5 --bibtex /tmp/papers.bibq7ey84d2'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibqem_5jn5 --bibtex /tmp/papers.bibq7ey84d2' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
________________________________________________ TestAddConflict.test_add_miss_merge ________________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_miss_merge>

    def test_add_miss_merge(self):
        # miss field but merges
        open(self.otherbib, 'w').write(self.bibtex_miss_field)
>       sp.check_call('papers add {} --mode u --bibtex {}'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:907: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibmd5u8v4b --mode u --bibtex /tmp/papers.bibnwzwneii',), kwargs = {'shell': True}
retcode = 1, cmd = 'papers add /tmp/papers.otherbibmd5u8v4b --mode u --bibtex /tmp/papers.bibnwzwneii'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibmd5u8v4b --mode u --bibtex /tmp/papers.bibnwzwneii' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
______________________________________________ TestAddConflict.test_add_same_but_file _______________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_same_but_file>

    def test_add_same_but_file(self):
        open(self.otherbib, 'w').write(self.bibtex_hasfile)
>       sp.check_call('papers add {} --bibtex {} -u'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:849: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibnh00tdlu --bibtex /tmp/papers.bibdr8zv55f -u',), kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibnh00tdlu --bibtex /tmp/papers.bibdr8zv55f -u'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibnh00tdlu --bibtex /tmp/papers.bibdr8zv55f -u' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________ TestAddConflict.test_add_same_but_key_update ____________________________________________
[gw2] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_same_but_key_update>

    def test_add_same_but_key_update(self):
        open(self.otherbib, 'w').write(self.bibtex_otherkey)
>       sp.check_call('papers add {} --bibtex {} -u'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:836: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibtcd43slf --bibtex /tmp/papers.bib6j8cohky -u',), kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibtcd43slf --bibtex /tmp/papers.bib6j8cohky -u'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibtcd43slf --bibtex /tmp/papers.bib6j8cohky -u' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
_________________________________________ TestAddConflict.test_add_same_but_key_interactive _________________________________________
[gw1] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_same_but_key_interactive>

    def test_add_same_but_key_interactive(self):
        # fails in raise mode
        open(self.otherbib, 'w').write(self.bibtex_otherkey)
>       sp.check_call('echo u | papers add {} --bibtex {}'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:830: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('echo u | papers add /tmp/papers.otherbib_8r648dc --bibtex /tmp/papers.bibs0brwlo0',), kwargs = {'shell': True}
retcode = 1, cmd = 'echo u | papers add /tmp/papers.otherbib_8r648dc --bibtex /tmp/papers.bibs0brwlo0'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'echo u | papers add /tmp/papers.otherbib_8r648dc --bibtex /tmp/papers.bibs0brwlo0' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
___________________________________________ TestAddConflict.test_add_same_doi_update_key ____________________________________________
[gw0] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_same_doi_update_key>

    def test_add_same_doi_update_key(self):
        # test doi and update key and identical entry detected
        open(self.otherbib, 'w').write(self.bibtex_same_doi)
>       sp.check_call('papers add {} --update-key --bibtex {} --mode r'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:894: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibomq_hm5r --update-key --bibtex /tmp/papers.bibq6c966yb --mode r',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibomq_hm5r --update-key --bibtex /tmp/papers.bibq6c966yb --mode r'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibomq_hm5r --update-key --bibtex /tmp/papers.bibq6c966yb --mode r' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)
____________________________________________ TestAddConflict.test_add_same_doi_unchecked ____________________________________________
[gw3] linux -- Python 3.11.3 /home/boyan/boyanshouse/miniconda3/envs/python311/bin/python

self = <tests.test_papers.TestAddConflict testMethod=test_add_same_doi_unchecked>

    def test_add_same_doi_unchecked(self):
        # does not normally test doi
        open(self.otherbib, 'w').write(self.bibtex_same_doi)
>       sp.check_call('papers add {} --no-check-duplicate --bibtex {} --mode r'.format(self.otherbib, self.mybib), shell=True)

tests/test_papers.py:881: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

popenargs = ('papers add /tmp/papers.otherbibq98yc4u4 --no-check-duplicate --bibtex /tmp/papers.bibrj98gwo0 --mode r',)
kwargs = {'shell': True}, retcode = 1
cmd = 'papers add /tmp/papers.otherbibq98yc4u4 --no-check-duplicate --bibtex /tmp/papers.bibrj98gwo0 --mode r'

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.

        The arguments are the same as for the call function.  Example:

        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command 'papers add /tmp/papers.otherbibq98yc4u4 --no-check-duplicate --bibtex /tmp/papers.bibrj98gwo0 --mode r' returned non-zero exit status 1.

../../../miniconda3/envs/python311/lib/python3.11/subprocess.py:413: CalledProcessError
------------------------------------------------------- Captured stderr call --------------------------------------------------------
Traceback (most recent call last):
  File "/home/boyan/boyanshouse/miniconda3/envs/python311/bin/papers", line 5, in <module>
    from papers.bib import main
ImportError: cannot import name 'main' from 'papers.bib' (/home/boyan/boyanshouse/Vazhno/Work/papers/papers/bib.py)

---------- coverage: platform linux, python 3.11.3-final-0 -----------
Name                   Stmts   Miss  Cover
------------------------------------------
papers/__init__.py         4      0   100%
papers/__main__.py       520    520     0%
papers/_version.py         2      0   100%
papers/bib.py            492    337    32%
papers/config.py         250    173    31%
papers/duplicate.py      384    326    15%
papers/encoding.py        84     43    49%
papers/extract.py        236    155    34%
papers/filename.py        51     31    39%
papers/latexenc.py        57     36    37%
setup.py                   2      2     0%
tests/__init__.py          0      0   100%
tests/download.py         27     11    59%
tests/test_papers.py     473    105    78%
versioneer.py            577    577     0%
------------------------------------------
TOTAL                   3159   2316    27%

====================================================== short test summary info ======================================================
FAILED tests/test_papers.py::TestAdd2::test_add - subprocess.CalledProcessError: Command 'papers add --bibtex /tmp/papers.bibejjm1...
FAILED tests/test_papers.py::TestAddDir::test_adddir_pdf - subprocess.CalledProcessError: Command 'papers install --local --no-pro...
FAILED tests/test_papers.py::TestInstall::test_local_install - subprocess.CalledProcessError: Command 'papers install --local --bi...
FAILED tests/test_papers.py::TestSimple::test_doi - subprocess.CalledProcessError: Command 'papers doi /home/boyan/boyanshouse/Vaz...
FAILED tests/test_papers.py::TestAdd2::test_add_attachment - subprocess.CalledProcessError: Command 'papers add -rc --bibtex /tmp/...
FAILED tests/test_papers.py::TestAdd::test_add - subprocess.CalledProcessError: Command 'papers add --bibtex /tmp/papers.bibspeo15...
FAILED tests/test_papers.py::TestAddDir::test_adddir_pdf_cmd - subprocess.CalledProcessError: Command 'papers install --local --no...
FAILED tests/test_papers.py::TestSimple::test_fetch - subprocess.CalledProcessError: Command 'papers fetch 10.5194/bg-8-515-2011' ...
FAILED tests/test_papers.py::TestAdd2::test_add_rename - subprocess.CalledProcessError: Command 'papers add -r --bibtex /tmp/paper...
FAILED tests/test_papers.py::TestAdd::test_add_rename - subprocess.CalledProcessError: Command 'papers add -r --bibtex /tmp/papers...
FAILED tests/test_papers.py::TestAdd2::test_add_rename_copy - subprocess.CalledProcessError: Command 'papers add -rc --bibtex /tmp...
FAILED tests/test_papers.py::TestAdd::test_add_rename_copy - subprocess.CalledProcessError: Command 'papers add -rc --bibtex /tmp/...
FAILED tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original_but_originalkey - subprocess.CalledProce...
FAILED tests/test_papers.py::TestAddResolveDuplicate::test_skip - subprocess.CalledProcessError: Command 'echo s | papers add /tmp...
FAILED tests/test_papers.py::TestAddResolveDuplicate::test_original_updated_from_conflict - subprocess.CalledProcessError: Command...
FAILED tests/test_papers.py::TestAddResolveDuplicate::test_append - subprocess.CalledProcessError: Command 'echo a | papers add /t...
FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_append - subprocess.CalledProcessError: Command 'papers add /tmp...
FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original_but_originalkey - subprocess.Call...
FAILED tests/test_papers.py::TestAddResolveDuplicate::test_overwrite - subprocess.CalledProcessError: Command 'echo o | papers add...
FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_conflict_updated_from_original - subprocess.CalledProcessError: ...
FAILED tests/test_papers.py::TestAddResolveDuplicate::test_conflict_updated_from_original - subprocess.CalledProcessError: Command...
FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_original_updated_from_conflict - subprocess.CalledProcessError: ...
FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_overwrite - subprocess.CalledProcessError: Command 'papers add /...
FAILED tests/test_papers.py::TestAddResolveDuplicateCommand::test_skip - subprocess.CalledProcessError: Command 'papers add /tmp/p...
FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_not_a_duplicate - subprocess.CalledProcessError: Command 'echo n | pa...
FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_pick_conflict_1 - subprocess.CalledProcessError: Command 'echo 1 | pa...
FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_pick_reference_2 - subprocess.CalledProcessError: Command 'echo 2 | p...
FAILED tests/test_papers.py::TestCheckResolveDuplicate::test_skip_check - subprocess.CalledProcessError: Command 'echo s | papers ...
FAILED tests/test_papers.py::TestAddConflict::test_add_conflict_key_update - subprocess.CalledProcessError: Command 'papers add /t...
FAILED tests/test_papers.py::TestAddConflict::test_add_miss_titauthor_merge - subprocess.CalledProcessError: Command 'papers add /...
FAILED tests/test_papers.py::TestAddConflict::test_add_miss_doi_merge - subprocess.CalledProcessError: Command 'papers add /tmp/pa...
FAILED tests/test_papers.py::TestAddConflict::test_add_same - subprocess.CalledProcessError: Command 'papers add /tmp/papers.other...
FAILED tests/test_papers.py::TestAddConflict::test_add_miss_merge - subprocess.CalledProcessError: Command 'papers add /tmp/papers...
FAILED tests/test_papers.py::TestAddConflict::test_add_same_but_file - subprocess.CalledProcessError: Command 'papers add /tmp/pap...
FAILED tests/test_papers.py::TestAddConflict::test_add_same_but_key_update - subprocess.CalledProcessError: Command 'papers add /t...
FAILED tests/test_papers.py::TestAddConflict::test_add_same_but_key_interactive - subprocess.CalledProcessError: Command 'echo u |...
FAILED tests/test_papers.py::TestAddConflict::test_add_same_doi_update_key - subprocess.CalledProcessError: Command 'papers add /t...
FAILED tests/test_papers.py::TestAddConflict::test_add_same_doi_unchecked - subprocess.CalledProcessError: Command 'papers add /tm...
============================================= 38 failed, 63 passed, 2 skipped in 14.42s ============================================

So I'm at a loss a little for how tox can finish and pass all.

boyanpenkov commented 1 year ago

Well, the plot thickens, as they say, since on another machine, all tests on HEAD pass as expected, but variable numbers of tests fail if you go -n auto. So my thinking is we stay away from xdist for now, until we can look at the testsuite a little...

Odd.

boyanpenkov commented 1 year ago

For the record, at 100% pass, my cov from pytest -vv --cov=. is:

---------- coverage: platform linux, python 3.11.2-final-0 -----------
Name                   Stmts   Miss  Cover
------------------------------------------
papers/__init__.py         4      0   100%
papers/__main__.py       520    209    60%
papers/_version.py         2      0   100%
papers/bib.py            492    192    61%
papers/config.py         250     86    66%
papers/duplicate.py      384    136    65%
papers/encoding.py        84     22    74%
papers/extract.py        236    151    36%
papers/filename.py        51      4    92%
papers/latexenc.py        57     36    37%
setup.py                   2      2     0%
tests/__init__.py          0      0   100%
tests/download.py         27     11    59%
tests/test_papers.py     473     15    97%
versioneer.py            577    577     0%
------------------------------------------
TOTAL                   3159   1441    54%
boyanpenkov commented 1 year ago

At 100% pass, my cov from pytest --cov=papers --cov-append --cov-report=term-missing tests -xv is:

---------- coverage: platform linux, python 3.11.2-final-0 -----------
Name                   Stmts   Miss  Cover   Missing
----------------------------------------------------
papers/__init__.py         4      0   100%
papers/__main__.py       520    209    60%   26, 30, 79-87, 103-119, 123-133, 147-149, 152, 171, 177-178, 185-186, 190-204, 215, 219-220, 222-223, 239, 245-250, 253-260, 271, 306, 318-330, 333-339, 343-347, 356, 360-370, 374, 377, 381-386, 391-496, 499, 510-511, 815, 820-821, 827, 829, 831, 833, 838-842, 847
papers/_version.py         2      0   100%
papers/bib.py            492    192    61%   45-47, 67, 140-143, 157-158, 175-190, 214, 233-234, 237, 262, 273, 332, 371, 381, 388, 401-402, 408, 440-446, 450, 455-459, 469, 505, 513-514, 523, 541, 562-565, 575-580, 590-594, 598-613, 616-629, 633-660, 664-668, 671, 674-682, 686, 692-703, 709-781
papers/config.py         250     86    66%   32-39, 66-67, 94-98, 105, 110, 124, 157-159, 164-165, 171, 174-186, 189-205, 213, 219, 229, 232, 234, 241, 246, 248, 254, 257-262, 299, 306-309, 317-319, 322-326, 333, 344-345, 349-359
papers/duplicate.py      384    142    63%   72-74, 88-89, 95-96, 100-101, 150-157, 163, 174, 176, 178, 195, 200-235, 242, 246, 272, 294, 304, 312, 314-318, 340, 349-371, 401-404, 407, 410, 417, 420, 427, 430-433, 436-451, 477-484, 487, 490, 493, 496-497, 500, 511-525, 538-542, 560-561, 597, 600, 609-611, 615, 619, 622
papers/encoding.py        84     22    74%   35, 63-64, 106-120, 125-128
papers/extract.py        236    151    36%   32, 51-78, 97, 105, 109, 117-118, 132, 144-159, 179-189, 193-199, 202, 215-221, 226-229, 234-239, 244-245, 250-268, 272, 277-286, 292-332, 337-367, 372-386
papers/filename.py        51      4    92%   18-19, 45-46
papers/latexenc.py        57     36    37%   23-31, 41-90, 100-101
setup.py                   2      2     0%   1-2
tests/__init__.py          0      0   100%
tests/download.py         27     27     0%   2-48
tests/test_papers.py     473    473     0%   1-928
versioneer.py            577    577     0%   4-1817
----------------------------------------------------
TOTAL                   3159   1921    39%
boyanpenkov commented 1 year ago

I'm not sure what the differences are in the pytest, but I'll stick to what's in the TOML there from now on.

boyanpenkov commented 1 year ago

Well, actually this is all over the place, since on yet another machine I see the correct TOML test command give me 52% coverage, so this is definitely something I don't understand.

I think my posture now is to feel inspired by the "Missing" lines above, read those carefully and think about adding tests there as I read through, and enjoy watching that number go up, whatever it happens to be...

perrette commented 1 year ago

I recommend to run the test with tox. Using pytest directly, at least the way it is currently set up requires papers to be installed.

boyanpenkov commented 1 year ago

Is this just pushing and having CI handle it, or do you have a one-liner for this? I'm not that familiar with tox...

perrette commented 1 year ago

Just install tox via pip install, and type the 3-letter command from papers folder. It is already configured in pyproject.toml to do the right thing. It is also used on github. In case you have several python versions and want to run only one you can specify it via tox -e py311 say.

perrette commented 1 year ago

With commit 4960680 the coverage reporting is fixed, and using pytest directly should now work (using tox rather than pytest directly remains the cleaner way IMO). I'll close that issue and start afresh a new one, to make it easier to read with the length outputs and unrelated issues above.

boyanpenkov commented 1 year ago

Confirming tox -e py311 works for me, so pretty nifty!