Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]
python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
runs-on: [ubuntu-latest, macos-latest, windows-latest]
exclude:
- runs-on: macos-latest
Expand All @@ -49,7 +49,6 @@ jobs:
- name: Install package
run: |
python -m pip install --upgrade pip
pip install 'numpy<2.0.0' # due to lingering issues with other modules & numpy...
pip install .[dev]

- name: Lint with flake8
Expand All @@ -61,6 +60,7 @@ jobs:
pip list

- name: Run simple examples
shell: bash
run: |
cd examples
python document.py
Expand All @@ -70,6 +70,7 @@ jobs:
python test.py

- name: Test NeuroML examples
shell: bash
run: |

cd examples/neuroml2
Expand All @@ -78,6 +79,7 @@ jobs:
# Note: NeuroML files will be validated with OMV below

- name: Test SBML examples
shell: bash
run: |

cd examples/sbml
Expand Down Expand Up @@ -126,7 +128,6 @@ jobs:
# Run OMV tests on all engines
cd examples
omv all -V

omv list -V # list installed engines

- name: Final version info
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/source/api/Contributors.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Modelspec contributors

This page list names and Github profiles of contributors to Modelspec, listed in no particular order.
This page is generated periodically, most recently on 2025-02-05.
This page is generated periodically, most recently on 2025-04-16.

- Padraig Gleeson ([@pgleeson](https://github.com/pgleeson))
- Manifest Chakalov ([@mqnifestkelvin](https://github.com/mqnifestkelvin))
Expand Down
7 changes: 4 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ classifiers =
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Topic :: Scientific/Engineering
Topic :: Software Development
Typing :: Typed
Expand All @@ -44,7 +45,7 @@ install_requires =
typing_compat;python_version<'3.8'


python_requires = >=3.7
python_requires = >=3.8
include_package_data = True
package_dir =
=src
Expand Down Expand Up @@ -83,8 +84,8 @@ docs =

dev =
flake8
pyneuroml>=0.7.2
NeuroMLlite>=0.5.3
pyneuroml>=1.3.15
NeuroMLlite>=0.6.1
python-libsbml
modelspec[test]
pre-commit
Expand Down
2 changes: 1 addition & 1 deletion src/modelspec/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.3.6"
__version__ = "0.3.7"

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

Expand Down
32 changes: 16 additions & 16 deletions src/modelspec/base_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,9 @@ def _is_child_field(cls, field_name: str) -> bool:

# Check if the type of the field is a list or dict
collection_arg = None
if get_origin(f.type) == list and len(get_args(f.type)) > 0:
if get_origin(f.type) is list and len(get_args(f.type)) > 0:
collection_arg = get_args(f.type)[0]
elif get_origin(f.type) == dict and len(get_args(f.type)) > 0:
elif get_origin(f.type) is dict and len(get_args(f.type)) > 0:
collection_arg = get_args(f.type)[1]

try:
Expand Down Expand Up @@ -641,16 +641,16 @@ def _is_base_type(
value = get_origin(value)

return (
value == int
or value == str
or value == bool
or value == float
or (can_be_list and value == list)
or (can_be_dict and value == dict)
or (can_be_ndarray and value == numpy.ndarray)
value is int
or value is str
or value is bool
or value is float
or (can_be_list and value is list)
or (can_be_dict and value is dict)
or (can_be_ndarray and value is numpy.ndarray)
or (can_be_none and value is None)
or (can_be_eval_expr and cls._is_evaluable_expression(value))
or value == Union
or value is Union
)

@staticmethod
Expand All @@ -671,11 +671,11 @@ def _type_to_str(type_: Any) -> str:

# If its a Generic type
elif get_origin(type_) is not None:
if get_origin(type_) == list and len(get_args(type_)) > 0:
if get_origin(type_) is list and len(get_args(type_)) > 0:
return Base._type_to_str(get_args(type_)[0])
elif get_origin(type_) == dict and len(get_args(type_)) > 0:
elif get_origin(type_) is dict and len(get_args(type_)) > 0:
return Base._type_to_str(get_args(type_)[1])
elif get_origin(type_) == Union and len(get_args(type_)) > 0:
elif get_origin(type_) is Union and len(get_args(type_)) > 0:
return (
"Union["
+ ", ".join([Base._type_to_str(arg) for arg in get_args(type_)])
Expand Down Expand Up @@ -916,9 +916,9 @@ def insert_links(text, format=MARKDOWN_FORMAT):
table_info.append([n, t, d])

# Get the contained type
if get_origin(type_) == list and len(get_args(type_)) > 0:
if get_origin(type_) is list and len(get_args(type_)) > 0:
referenced.append(get_args(type_)[0])
elif get_origin(type_) == dict and len(get_args(type_)) > 1:
elif get_origin(type_) is dict and len(get_args(type_)) > 1:
referenced.append(get_args(type_)[1])
else:
referenced.append(type_)
Expand Down Expand Up @@ -1080,7 +1080,7 @@ def _is_list_base(cl):
Check if a class is a list of Base objects. These will be serialized as dicts if the underlying class has an id
attribute.
"""
return get_origin(cl) == list and issubclass(get_args(cl)[0], Base)
return get_origin(cl) is list and issubclass(get_args(cl)[0], Base)


converter.register_unstructure_hook_factory(_is_list_base, _unstructure_list_base)
Expand Down
10 changes: 5 additions & 5 deletions src/modelspec/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,13 +486,13 @@ def evaluate(
expr = tf.constant(int(expr))
else:
expr = int(expr)
except:
except Exception:
try:
if array_format == FORMAT_TENSORFLOW:
expr = tf.constant(float(expr))
else:
expr = float(expr)
except:
except Exception:
pass

if type(expr) is list:
Expand Down Expand Up @@ -525,7 +525,7 @@ def evaluate(
else: # will have failed if not number
print_(" Returning {}: {}".format(type(expr), expr), verbose)
return expr
except:
except Exception:
try:
if rng:
expr = expr.replace("random()", "rng.random()")
Expand Down Expand Up @@ -582,12 +582,12 @@ def parse_list_like(list_str):
try:
expr = int(list_str)
return [expr]
except:
except Exception:
pass
try:
expr = float(list_str)
return [expr]
except:
except Exception:
pass
if "[" in list_str:
return eval(list_str)
14 changes: 7 additions & 7 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ def test_evaluate(self):
assert evaluate("p+p", params, verbose=True) == 66

print("======")
assert type(evaluate("33")) == int
assert type(evaluate("33", cast_to_int=True)) == int
assert type(evaluate("33.0")) == float
assert type(evaluate("33.0", cast_to_int=True)) == int
assert type(evaluate("33")) is int
assert type(evaluate("33", cast_to_int=True)) is int
assert type(evaluate("33.0")) is float
assert type(evaluate("33.0", cast_to_int=True)) is int

assert type(evaluate("33.1")) == float
assert type(evaluate("33.1a", verbose=True)) == str
assert type(evaluate("33.1")) is float
assert type(evaluate("33.1a", verbose=True)) is str

assert type(evaluate("a")) == str
assert type(evaluate("a")) is str

import random

Expand Down
Loading