Skip to content

Commit 4d81b47

Browse files
authored
Merge pull request #19 from ModECI/development
To v0.2.6; multiple docstring handling updates
2 parents d04c5f6 + 5ef6b46 commit 4d81b47

9 files changed

+111
-68
lines changed

examples/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ with open("document.specification.yaml", "w") as d:
3434

3535
### 3) Create an instance of a Document
3636

37-
The actual instance of a document which is built (in [document.py](document.py)) can be saved in [YAML](document.yaml) or [JSON](document.json) format:
37+
The actual instance of a document which is built (in [document.py](document.py)) can be saved in [YAML](document.yaml) or [JSON](document.json) format or [BSON](document.bson) format:
3838
```
3939
doc = Document(id="MyBook")
4040
doc.title = "My life in Python"
@@ -46,4 +46,5 @@ doc.sections.append(a)
4646
4747
doc.to_json_file("document.json")
4848
doc.to_yaml_file("document.yaml")
49+
doc.to_bson_file("document.bson")
4950
```

examples/document.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ A model for documents.
3838
</table>
3939

4040
## Section
41-
A model of a section of the <a href="#document">Document</a>. Will contain one <a href="#paragraph">Paragraph</a> or more.
41+
A model of a section of the <a href="#document">Document</a>. Will contain one <a href="#paragraph">Paragraph</a> or more, i.e the <a href="#paragraph">Paragraph</a>(s) in the section, probably related to the <b>title</b> of the `Document <#document>`_.
4242

4343
### Allowed parameters
4444
<table>

examples/document.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Paragraph(Base):
1212
A model of a paragraph.
1313
1414
Args:
15-
contents: Paragraph contents, which make up the _Section_s.
15+
contents: Paragraph contents, which make up the :class:`Section`s.
1616
"""
1717

1818
contents: str = field(validator=instance_of(str))
@@ -22,7 +22,7 @@ class Paragraph(Base):
2222
class Section(Base):
2323
"""
2424
A model of a section of the :class:`Document`.
25-
Will contain one :class:`Paragraph` or more.
25+
Will contain one :class:`Paragraph` or more, i.e the :class:`Paragraph`(s) in the section, probably related to the :code:`title` of the `Document <#document>`_.
2626
2727
Args:
2828
id: The id of the section

examples/document.rst

+25-25
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,42 @@ A model for documents.
55

66
**Allowed parameters**
77

8-
=============== =========== ====================================
8+
=============== =========== ==================================
99
Allowed field Data Type Description
10-
=============== =========== ====================================
11-
**id** str *The unique id of the document*
12-
**title** str *Document title*
13-
**ISBN** int *International Standard Book Number*
14-
=============== =========== ====================================
10+
=============== =========== ==================================
11+
**id** str The unique id of the document
12+
**title** str Document title
13+
**ISBN** int International Standard Book Number
14+
=============== =========== ==================================
1515

1616
**Allowed children**
1717

18-
=============== ===================== ==============================
19-
Allowed child Data Type Description
20-
=============== ===================== ==============================
21-
**sections** `Section <#section>`_ *The sections of the document*
22-
=============== ===================== ==============================
18+
=============== ====================== ============================
19+
Allowed child Data Type Description
20+
=============== ====================== ============================
21+
**sections** `Section <#section>`__ The sections of the document
22+
=============== ====================== ============================
2323

2424
=======
2525
Section
2626
=======
27-
A model of a section of the <a href="#document">Document</a>. Will contain one <a href="#paragraph">Paragraph</a> or more.
27+
A model of a section of the `Document <#document>`__. Will contain one `Paragraph <#paragraph>`__ or more, i.e the `Paragraph(s) <#paragraph>`__ in the section, probably related to the **title** of the `Document <#document>`_.
2828

2929
**Allowed parameters**
3030

31-
=============== =========== =======================
31+
=============== =========== =====================
3232
Allowed field Data Type Description
33-
=============== =========== =======================
34-
**id** str *The id of the section*
35-
=============== =========== =======================
33+
=============== =========== =====================
34+
**id** str The id of the section
35+
=============== =========== =====================
3636

3737
**Allowed children**
3838

39-
=============== ========================= ================
40-
Allowed child Data Type Description
41-
=============== ========================= ================
42-
**paragraphs** `Paragraph <#paragraph>`_ *The paragraphs*
43-
=============== ========================= ================
39+
=============== ========================== ==============
40+
Allowed child Data Type Description
41+
=============== ========================== ==============
42+
**paragraphs** `Paragraph <#paragraph>`__ The paragraphs
43+
=============== ========================== ==============
4444

4545
=========
4646
Paragraph
@@ -49,8 +49,8 @@ A model of a paragraph.
4949

5050
**Allowed parameters**
5151

52-
=============== =========== =================================================
52+
=============== =========== ==============================================================
5353
Allowed field Data Type Description
54-
=============== =========== =================================================
55-
**contents** str *Paragraph contents, which make up the Sections.*
56-
=============== =========== =================================================
54+
=============== =========== ==============================================================
55+
**contents** str Paragraph contents, which make up the `Sections <#section>`__.
56+
=============== =========== ==============================================================

examples/document.specification.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
}
2424
},
2525
"Section": {
26-
"definition": "A model of a section of the :class:`Document`. Will contain one :class:`Paragraph` or more.",
26+
"definition": "A model of a section of the :class:`Document`. Will contain one :class:`Paragraph` or more, i.e the :class:`Paragraph`(s) in the section, probably related to the :code:`title` of the `Document <#document>`_.",
2727
"allowed_parameters": {
2828
"id": {
2929
"type": "str",
@@ -42,7 +42,7 @@
4242
"allowed_parameters": {
4343
"contents": {
4444
"type": "str",
45-
"description": "Paragraph contents, which make up the _Section_s."
45+
"description": "Paragraph contents, which make up the :class:`Section`s."
4646
}
4747
}
4848
}

examples/document.specification.yaml

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ Document:
1616
description: The sections of the document
1717
Section:
1818
definition: A model of a section of the :class:`Document`. Will contain one :class:`Paragraph`
19-
or more.
19+
or more, i.e the :class:`Paragraph`(s) in the section, probably related to
20+
the :code:`title` of the `Document <#document>`_.
2021
allowed_parameters:
2122
id:
2223
type: str
@@ -30,4 +31,4 @@ Paragraph:
3031
allowed_parameters:
3132
contents:
3233
type: str
33-
description: Paragraph contents, which make up the _Section_s.
34+
description: Paragraph contents, which make up the :class:`Section`s.

src/modelspec/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.2.5"
1+
__version__ = "0.2.6"
22

33
from .base_types import Base, define, has, field, fields, optional, instance_of, in_
44

src/modelspec/base_types.py

+37-13
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,9 @@ def _parse_definition(cls) -> str:
373373
p = parse(cls.__doc__)
374374

375375
# Extract the description, use the long description if available.
376+
# "short_description" only parse the first non-empty line and
377+
# "long_description" parse the rest of the docstring i.e.
378+
# it skips the first non-empty line and parse the rest of the docstring
376379
if p.long_description:
377380
definition = f"{p.short_description} {p.long_description}"
378381
else:
@@ -578,7 +581,7 @@ def _cls_generate_documentation(cls, format: str = MARKDOWN_FORMAT):
578581

579582
print(f" - {cls.__name__} ({definition})")
580583

581-
rst_url_format = "`%s <%s>`_"
584+
rst_url_format = "`%s <%s>`__"
582585

583586
def insert_links(text, format=MARKDOWN_FORMAT):
584587

@@ -591,7 +594,12 @@ def insert_links(text, format=MARKDOWN_FORMAT):
591594
pre = text2[0:ind]
592595
ref = text2[ind + len(code_ref) : ind2]
593596
post = text2[ind2 + 1 :]
594-
text2 = f"{pre}<b>{ref}</b>{post}"
597+
598+
if format == MARKDOWN_FORMAT:
599+
text2 = f"{pre}<b>{ref}</b>{post}"
600+
elif format == RST_FORMAT:
601+
text2 = f"{pre}**{ref}**{post}"
602+
595603
# print(" > Converted to: %s" % text2)
596604
text = text2
597605

@@ -606,28 +614,44 @@ def insert_links(text, format=MARKDOWN_FORMAT):
606614
if ref[0] == "~":
607615
ref = ref[1:]
608616
post = text2[ind2 + 1 :]
609-
text2 = f'{pre}<a href="#{ref.lower()}">{ref}</a>{post}'
617+
if format == MARKDOWN_FORMAT:
618+
text2 = f'{pre}<a href="#{ref.lower()}">{ref}</a>{post}'
619+
elif format == RST_FORMAT:
620+
rr = ref
621+
pp = post
622+
623+
######################################
624+
# Some hardcoded fixes for plurals...
625+
if pp.startswith("s "):
626+
rr += "s"
627+
pp = pp[1:]
628+
if pp.startswith("s."):
629+
rr += "s"
630+
pp = pp[1:]
631+
if pp.startswith("(s)"):
632+
rr += "(s)"
633+
pp = pp[3:]
634+
######################################
635+
636+
text2 = f"{pre}`{rr} <#{ref.lower()}>`__{pp}"
637+
610638
# print(" > Converted to: %s" % text2)
611639
text = text2
612640

613641
if "_" not in text:
614642
return text
615643
if '"' in text:
616644
return text # Assume it's a quoted string containing an underscore...
645+
if format == RST_FORMAT:
646+
return text # No need to remove underscore for RST format
647+
617648
split = text.split("_")
618649
text2 = ""
619650
for i in range(int(len(split) / 2.0)):
620651
pre = split[i * 2]
621652
type = split[i * 2 + 1]
622-
if format == MARKDOWN_FORMAT:
623-
text2 += f'{pre}<a href="#{type.lower()}">{type}</a>'
624-
elif format == RST_FORMAT:
625-
# text2 += ('%s'+rst_url_format) % (pre, type, '#'+type.lower # problem with handling links ending with s e.g. _Graph_s
653+
text2 += f'{pre}<a href="#{type.lower()}">{type}</a>'
626654

627-
text2 += ("%s%s") % (
628-
pre,
629-
type,
630-
) # temp hack... problem with handling links ending with s e.g. _Graph_s
631655
if int(len(split) / 2.0) != len(split) / 2.0:
632656
text2 += split[-1]
633657
return text2
@@ -691,7 +715,7 @@ def insert_links(text, format=MARKDOWN_FORMAT):
691715
if referencable
692716
else type_str,
693717
)
694-
d = "*%s*" % (insert_links(description, format=RST_FORMAT))
718+
d = "%s" % (insert_links(description, format=RST_FORMAT))
695719
table_info.append([n, t, d])
696720

697721
if referencable:
@@ -752,7 +776,7 @@ def insert_links(text, format=MARKDOWN_FORMAT):
752776
if referencable
753777
else type_str,
754778
)
755-
d = "*%s*" % (insert_links(description, format=RST_FORMAT))
779+
d = "%s" % (insert_links(description, format=RST_FORMAT))
756780
table_info.append([n, t, d])
757781

758782
# Get the contained type

src/modelspec/utils.py

+38-21
Original file line numberDiff line numberDiff line change
@@ -221,17 +221,19 @@ def evaluate(expr, parameters={}, rng=None, array_format=FORMAT_NUMPY, verbose=F
221221
if array_format == FORMAT_TENSORFLOW:
222222
import tensorflow as tf
223223

224-
print_(
225-
" > Evaluating: [%s] which is a: %s, vs parameters: %s (using %s arrays)..."
226-
% (expr, type(expr).__name__, _params_info(parameters), array_format),
227-
verbose,
228-
)
224+
if verbose:
225+
print_(
226+
" > Evaluating: [%s] which is a: %s, vs parameters: %s (using %s arrays)..."
227+
% (expr, type(expr).__name__, _params_info(parameters), array_format),
228+
verbose,
229+
)
229230
try:
230231
if type(expr) == str and expr in parameters:
231232
expr = parameters[
232233
expr
233234
] # replace with the value in parameters & check whether it's float/int...
234-
print_("Using for that param: %s" % _val_info(expr), verbose)
235+
if verbose:
236+
print_("Using for that param: %s" % _val_info(expr), verbose)
235237

236238
if type(expr) == str:
237239
try:
@@ -250,33 +252,39 @@ def evaluate(expr, parameters={}, rng=None, array_format=FORMAT_NUMPY, verbose=F
250252
pass
251253

252254
if type(expr) == list:
253-
print_("Returning a list in format: %s" % array_format, verbose)
255+
if verbose:
256+
print_("Returning a list in format: %s" % array_format, verbose)
254257
if array_format == FORMAT_TENSORFLOW:
255258
return tf.constant(expr, dtype=tf.float64)
256259
else:
257260
return np.array(expr)
258261

259262
if type(expr) == np.ndarray:
260-
print_("Returning a numpy array in format: %s" % array_format, verbose)
263+
if verbose:
264+
print_("Returning a numpy array in format: %s" % array_format, verbose)
261265
if array_format == FORMAT_TENSORFLOW:
262266
return tf.convert_to_tensor(expr, dtype=tf.float64)
263267
else:
264268
return np.array(expr)
265269

266270
if "Tensor" in type(expr).__name__:
267-
print_(
268-
"Returning a tensorflow Tensor in format: %s" % array_format, verbose
269-
)
271+
if verbose:
272+
print_(
273+
"Returning a tensorflow Tensor in format: %s" % array_format,
274+
verbose,
275+
)
270276
if array_format == FORMAT_NUMPY:
271277
return expr.numpy()
272278
else:
273279
return expr
274280

275281
if int(expr) == expr:
276-
print_("Returning int: %s" % int(expr), verbose)
282+
if verbose:
283+
print_("Returning int: %s" % int(expr), verbose)
277284
return int(expr)
278285
else: # will have failed if not number
279-
print_("Returning float: %s" % expr, verbose)
286+
if verbose:
287+
print_("Returning float: %s" % expr, verbose)
280288
return float(expr)
281289
except:
282290
try:
@@ -289,24 +297,33 @@ def evaluate(expr, parameters={}, rng=None, array_format=FORMAT_NUMPY, verbose=F
289297
if type(expr) == str and "numpy." in expr:
290298
parameters["numpy"] = np
291299

292-
print_(
293-
"Trying to eval [%s] with Python using %s..."
294-
% (expr, parameters.keys()),
295-
verbose,
296-
)
300+
if verbose:
301+
print_(
302+
"Trying to eval [%s] with Python using %s..."
303+
% (expr, parameters.keys()),
304+
verbose,
305+
)
297306

298307
v = eval(expr, parameters)
299-
print_("Evaluated with Python: {} = {}".format(expr, _val_info(v)), verbose)
308+
309+
if verbose:
310+
print_(
311+
"Evaluated with Python: {} = {}".format(expr, _val_info(v)), verbose
312+
)
313+
300314
if (type(v) == float or type(v) == str) and int(v) == v:
301-
print_("Returning int: %s" % int(v), verbose)
315+
316+
if verbose:
317+
print_("Returning int: %s" % int(v), verbose)
302318

303319
if array_format == FORMAT_TENSORFLOW:
304320
return tf.constant(int(v))
305321
else:
306322
return int(v)
307323
return v
308324
except Exception as e:
309-
print_(f"Returning without altering: {expr} (error: {e})", verbose)
325+
if verbose:
326+
print_(f"Returning without altering: {expr} (error: {e})", verbose)
310327
return expr
311328

312329

0 commit comments

Comments
 (0)