commonnexus 1.9.1__tar.gz → 1.9.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. {commonnexus-1.9.1/src/commonnexus.egg-info → commonnexus-1.9.3}/PKG-INFO +21 -3
  2. {commonnexus-1.9.1 → commonnexus-1.9.3}/setup.cfg +4 -2
  3. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/__init__.py +1 -1
  4. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/characters.py +5 -0
  5. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/trees.py +24 -2
  6. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/tokenizer.py +1 -1
  7. {commonnexus-1.9.1 → commonnexus-1.9.3/src/commonnexus.egg-info}/PKG-INFO +21 -3
  8. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_characters.py +53 -0
  9. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_trees.py +8 -0
  10. {commonnexus-1.9.1 → commonnexus-1.9.3}/LICENSE +0 -0
  11. {commonnexus-1.9.1 → commonnexus-1.9.3}/README.md +0 -0
  12. {commonnexus-1.9.1 → commonnexus-1.9.3}/pyproject.toml +0 -0
  13. {commonnexus-1.9.1 → commonnexus-1.9.3}/setup.py +0 -0
  14. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/__main__.py +0 -0
  15. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/__init__.py +0 -0
  16. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/assumptions.py +0 -0
  17. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/base.py +0 -0
  18. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/codons.py +0 -0
  19. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/distances.py +0 -0
  20. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/notes.py +0 -0
  21. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/sets.py +0 -0
  22. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/taxa.py +0 -0
  23. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/blocks/unaligned.py +0 -0
  24. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/cli_util.py +0 -0
  25. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/command.py +0 -0
  26. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/__init__.py +0 -0
  27. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/characters.py +0 -0
  28. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/combine.py +0 -0
  29. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/help.py +0 -0
  30. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/normalise.py +0 -0
  31. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/split.py +0 -0
  32. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/taxa.py +0 -0
  33. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/commands/trees.py +0 -0
  34. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/nexus.py +0 -0
  35. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/tools/__init__.py +0 -0
  36. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/tools/combine.py +0 -0
  37. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/tools/matrix.py +0 -0
  38. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/tools/normalise.py +0 -0
  39. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus/util.py +0 -0
  40. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus.egg-info/SOURCES.txt +0 -0
  41. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus.egg-info/dependency_links.txt +0 -0
  42. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus.egg-info/entry_points.txt +0 -0
  43. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus.egg-info/not-zip-safe +0 -0
  44. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus.egg-info/requires.txt +0 -0
  45. {commonnexus-1.9.1 → commonnexus-1.9.3}/src/commonnexus.egg-info/top_level.txt +0 -0
  46. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_base.py +0 -0
  47. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_distances.py +0 -0
  48. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_notes.py +0 -0
  49. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_sets.py +0 -0
  50. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_blocks_taxa.py +0 -0
  51. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_cli.py +0 -0
  52. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_command.py +0 -0
  53. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_dendropy_examples.py +0 -0
  54. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_nexus.py +0 -0
  55. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_regressions.py +0 -0
  56. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_tokenizer.py +0 -0
  57. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_tools_combine.py +0 -0
  58. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_tools_matrix.py +0 -0
  59. {commonnexus-1.9.1 → commonnexus-1.9.3}/tests/test_tools_normalise.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: commonnexus
3
- Version: 1.9.1
3
+ Version: 1.9.3
4
4
  Summary: A nexus (phylogenetics) file reader and writer (.nex, .trees)
5
5
  Home-page: https://github.com/dlce-eva/commonnexus
6
6
  Author: Robert Forkel
@@ -25,15 +25,33 @@ Classifier: Programming Language :: Python :: 3.9
25
25
  Classifier: Programming Language :: Python :: 3.10
26
26
  Classifier: Programming Language :: Python :: 3.11
27
27
  Classifier: Programming Language :: Python :: 3.12
28
+ Classifier: Programming Language :: Python :: 3.13
29
+ Classifier: Programming Language :: Python :: 3.14
28
30
  Classifier: Programming Language :: Python :: Implementation :: CPython
29
31
  Classifier: Programming Language :: Python :: Implementation :: PyPy
30
32
  Classifier: License :: OSI Approved :: BSD License
31
33
  Requires-Python: >=3.8
32
34
  Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: newick>=1.8.1
33
37
  Provides-Extra: dev
38
+ Requires-Dist: tox; extra == "dev"
39
+ Requires-Dist: flake8; extra == "dev"
40
+ Requires-Dist: wheel>=0.36; extra == "dev"
41
+ Requires-Dist: twine; extra == "dev"
42
+ Requires-Dist: build; extra == "dev"
34
43
  Provides-Extra: test
44
+ Requires-Dist: pytest>=5; extra == "test"
45
+ Requires-Dist: pytest-mock; extra == "test"
46
+ Requires-Dist: pytest-cov; extra == "test"
47
+ Requires-Dist: coverage>=4.2; extra == "test"
35
48
  Provides-Extra: docs
36
- License-File: LICENSE
49
+ Requires-Dist: sphinx<7; extra == "docs"
50
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
51
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
52
+ Requires-Dist: sphinx-prompt; extra == "docs"
53
+ Requires-Dist: sphinxcontrib-programoutput; extra == "docs"
54
+ Requires-Dist: termgraph; extra == "docs"
37
55
 
38
56
  # commonnexus
39
57
 
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = commonnexus
3
- version = 1.9.1
3
+ version = 1.9.3
4
4
  author = Robert Forkel
5
5
  author_email = robert_forkel@eva.mpg.de
6
6
  description = A nexus (phylogenetics) file reader and writer (.nex, .trees)
@@ -30,6 +30,8 @@ classifiers =
30
30
  Programming Language :: Python :: 3.10
31
31
  Programming Language :: Python :: 3.11
32
32
  Programming Language :: Python :: 3.12
33
+ Programming Language :: Python :: 3.13
34
+ Programming Language :: Python :: 3.14
33
35
  Programming Language :: Python :: Implementation :: CPython
34
36
  Programming Language :: Python :: Implementation :: PyPy
35
37
  License :: OSI Approved :: BSD License
@@ -98,7 +100,7 @@ show_missing = true
98
100
  skip_covered = true
99
101
 
100
102
  [tox:tox]
101
- envlist = py38, py39, py310, py311, py312
103
+ envlist = py38, py39, py310, py311, py312, py313, py314
102
104
  isolated_build = true
103
105
  skip_missing_interpreter = true
104
106
 
@@ -1,4 +1,4 @@
1
1
  from .nexus import Nexus, Config # noqa: F401
2
2
  from commonnexus.blocks import Block # noqa: F401
3
3
 
4
- __version__ = '1.9.1'
4
+ __version__ = '1.9.3'
@@ -549,10 +549,15 @@ class Charstatelabels(Payload):
549
549
  if isinstance(w, Token) and w.text == '/':
550
550
  in_states = True
551
551
  continue
552
+ if name:
553
+ raise ValueError(
554
+ 'Illegal token in charstatelabel: "{}{}"'.format(name, w))
552
555
  name = w
553
556
  except StopIteration:
554
557
  break
555
558
  if num:
559
+ if name and name in names:
560
+ duplicate_charlabel(name, 'CHARSTATELABELS', nexus)
556
561
  self.characters.append(types.SimpleNamespace(number=num, name=name, states=states))
557
562
  elif comma: # There was a comma, but no new label.
558
563
  warnings.warn('Trailing comma in CHARSTATELABELS command')
@@ -127,6 +127,25 @@ class Tree(Payload):
127
127
  NEXUS comment commands. The NEXUS standard places no restrictions on the number of taxa
128
128
  contained in each tree.
129
129
 
130
+ Sometimes, trees are annotated with additional information in a NEXUS comment such as
131
+
132
+ .. code-block::
133
+
134
+ TREE tree1 = [&R] [&clockrate=9.118820e-04] ((beetle,fly),spider);
135
+
136
+ Since comments may appear anywhere in NEXUS, this is valid content. However, such comments have
137
+ no semantics whatsoever; in particular they do not "belong" to any object, be it the Newick
138
+ tree or the NEXUS TREE wrapper. Instead, they are just added to the global list of comments in
139
+ a NEXUS file by `commonnexus`. Thus, to retrieve such a comment, one would have to search
140
+ through `Nexus.comments`, picking one that appears immediately after a `"&R"` comment:
141
+
142
+ .. code-block::
143
+
144
+ >>> from commonnexus import Nexus
145
+ >>> nex = Nexus('#nexus begin trees; tree 1 = [&R] [&clockrate] ((a,b)c); end;')
146
+ >>> nex.comments
147
+ ['&R', '&clockrate']
148
+
130
149
  :ivar str name: The name of the tree.
131
150
  :ivar typing.Union[bool, None] rooted: Flag indicating whether the tree is rooted (or `None` \
132
151
  if no information is given)
@@ -172,8 +191,11 @@ class Tree(Payload):
172
191
 
173
192
  while not nwk:
174
193
  t = next(tokens)
175
- if t.type == TokenType.COMMENT and t.text.startswith('&'):
176
- self._rooted = t.text
194
+ if t.type == TokenType.COMMENT:
195
+ if t.text.startswith('&') and t.text[1:] in {'U', 'R'}:
196
+ self._rooted = t.text
197
+ else:
198
+ pass
177
199
  if t.type == TokenType.PUNCTUATION and t.text == '(':
178
200
  nwk = True
179
201
  assert nwk
@@ -11,7 +11,7 @@ Punctuation
11
11
 
12
12
  The following punctuation marks have special properties: [ ] do not break a
13
13
  word; + and - are allowed as state symbols, but none of the rest are allowed; - is
14
- considered punctuation except were it is the minus sign in a negative number.
14
+ considered punctuation except where it is the minus sign in a negative number.
15
15
  """
16
16
  import enum
17
17
  import itertools
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: commonnexus
3
- Version: 1.9.1
3
+ Version: 1.9.3
4
4
  Summary: A nexus (phylogenetics) file reader and writer (.nex, .trees)
5
5
  Home-page: https://github.com/dlce-eva/commonnexus
6
6
  Author: Robert Forkel
@@ -25,15 +25,33 @@ Classifier: Programming Language :: Python :: 3.9
25
25
  Classifier: Programming Language :: Python :: 3.10
26
26
  Classifier: Programming Language :: Python :: 3.11
27
27
  Classifier: Programming Language :: Python :: 3.12
28
+ Classifier: Programming Language :: Python :: 3.13
29
+ Classifier: Programming Language :: Python :: 3.14
28
30
  Classifier: Programming Language :: Python :: Implementation :: CPython
29
31
  Classifier: Programming Language :: Python :: Implementation :: PyPy
30
32
  Classifier: License :: OSI Approved :: BSD License
31
33
  Requires-Python: >=3.8
32
34
  Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Requires-Dist: newick>=1.8.1
33
37
  Provides-Extra: dev
38
+ Requires-Dist: tox; extra == "dev"
39
+ Requires-Dist: flake8; extra == "dev"
40
+ Requires-Dist: wheel>=0.36; extra == "dev"
41
+ Requires-Dist: twine; extra == "dev"
42
+ Requires-Dist: build; extra == "dev"
34
43
  Provides-Extra: test
44
+ Requires-Dist: pytest>=5; extra == "test"
45
+ Requires-Dist: pytest-mock; extra == "test"
46
+ Requires-Dist: pytest-cov; extra == "test"
47
+ Requires-Dist: coverage>=4.2; extra == "test"
35
48
  Provides-Extra: docs
36
- License-File: LICENSE
49
+ Requires-Dist: sphinx<7; extra == "docs"
50
+ Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
51
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
52
+ Requires-Dist: sphinx-prompt; extra == "docs"
53
+ Requires-Dist: sphinxcontrib-programoutput; extra == "docs"
54
+ Requires-Dist: termgraph; extra == "docs"
37
55
 
38
56
  # commonnexus
39
57
 
@@ -267,3 +267,56 @@ def test_Data_with_mixed_charlabels(nexus):
267
267
  nex = nexus(DATA="DIMENSIONS NCHAR=2; CHARSTATELABELS 1 x, 2 ; MATRIX t1 1 1;")
268
268
  m = nex.characters.get_matrix()
269
269
  assert '2' in m['t1'], 'unspecified character label'
270
+
271
+
272
+ def test_illegal_charstatelabel():
273
+ nex = Nexus("""\
274
+ #NEXUS
275
+
276
+ BEGIN DATA;
277
+ DIMENSIONS NTAX=3 NCHAR=3;
278
+ FORMAT DATATYPE=STANDARD MISSING=? GAP=- SYMBOLS="01";
279
+ CHARSTATELABELS
280
+ 1 hand_1,
281
+ 2 burn(tr.)_3,
282
+ 3 claw(nail)_3
283
+ ;
284
+ MATRIX
285
+ A 001
286
+ B 000
287
+ C 000
288
+ ;
289
+ END;""")
290
+ with pytest.raises(ValueError) as e:
291
+ _ = nex.DATA.CHARSTATELABELS
292
+ assert 'burn(' in str(e)
293
+
294
+ with pytest.raises(ValueError):
295
+ nex.validate()
296
+
297
+
298
+ def test_duplicate_charstatelabels():
299
+ nex = Nexus("""\
300
+ #NEXUS
301
+
302
+ BEGIN DATA;
303
+ DIMENSIONS NTAX=3 NCHAR=3;
304
+ FORMAT DATATYPE=STANDARD MISSING=? GAP=- SYMBOLS="01";
305
+ CHARSTATELABELS
306
+ 1 hand_1,
307
+ 2 _3,
308
+ 3 _3
309
+ ;
310
+ MATRIX
311
+ A 001
312
+ B 000
313
+ C 000
314
+ ;
315
+ END;""")
316
+ with warnings.catch_warnings(record=True) as w:
317
+ _ = nex.DATA.CHARSTATELABELS
318
+ assert len(w) == 1, 'Expected 1 warning, got %r' % w
319
+
320
+ nex.cfg.strict = True
321
+ with pytest.raises(ValueError):
322
+ _ = nex.DATA.CHARSTATELABELS
@@ -23,6 +23,14 @@ def test_Trees(nexus):
23
23
  assert nex.TREES.translate(tree).newick == '((Scarabaeus,Drosophila),Aranaeus)'
24
24
 
25
25
 
26
+ def test_Trees_with_leading_comment(nexus):
27
+ nex = nexus(
28
+ TAXA="TAXLABELS Scarabaeus Drosophila Aranaeus;",
29
+ TREES="TREE tree1 = [&R] [&clockrate=9.118820e-04] ((beetle,fly),spider);")
30
+ assert nex.TREES.TREE.rooted
31
+ assert '&clockrate=9.118820e-04' in nex.comments
32
+
33
+
26
34
  def test_Tree_translate_with_taxa_from_linked_block(nexus):
27
35
  nex = nexus(
28
36
  TAXA="TITLE x; TAXLABELS A B C;",
File without changes
File without changes
File without changes
File without changes