Skip to content

Commit

Permalink
Remove deprecated pkg_resources (#1166)
Browse files Browse the repository at this point in the history
* Replace `pkg_resources` with `importlib`

* Update requirements

* Add test to make sure we can read examples from README
  • Loading branch information
JCGoran authored and Omar Awile committed May 21, 2024
1 parent 9b398da commit 3ff1d01
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 50 deletions.
46 changes: 27 additions & 19 deletions nmodl/ast.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
"""
Module for vizualization of NMODL abstract syntax trees (ASTs).
"""
import getpass
import json
import os
import sys
import tempfile
import webbrowser
from shutil import copytree


if sys.version_info >= (3, 9):
from importlib.resources import files
else:
from importlib_resources import files

from ._nmodl import to_json
from ._nmodl.ast import * # noqa
from pkg_resources import *


def view(nmodl_ast):
"""Visualize given NMODL AST in web browser
Expand All @@ -14,31 +32,21 @@ def view(nmodl_ast):
Returns:
None
"""
from ._nmodl import to_json
from distutils.dir_util import copy_tree
import getpass
import json
import os
import tempfile
import webbrowser

resource = "ext/viz"
if resource_exists(__name__, resource) and resource_isdir(__name__, resource):
installed_viz_tool = resource_filename(__name__, resource)
else:

path = files("nmodl") / "ext/viz"
if not path.is_dir():
raise FileNotFoundError("Could not find sample mod files")

work_dir = os.path.join(tempfile.gettempdir(), getpass.getuser(), "nmodl")

# first copy necessary files to temp work directory
copy_tree(installed_viz_tool, work_dir)
copytree(path, work_dir, dirs_exist_ok=True)

# prepare json data
with open(os.path.join(work_dir, 'ast.js'), 'w') as outfile:
json_data = json.loads(to_json(nmodl_ast, True, True, True))
outfile.write('var astRoot = %s;' % json.dumps(json_data))
json_data = json.loads(to_json(nmodl_ast, True, True, True))
with open(os.path.join(work_dir, "ast.js"), "w", encoding="utf-8") as outfile:
outfile.write(f"var astRoot = {json.dumps(json_data)};")

# open browser with ast
url = 'file://' + os.path.join(work_dir, "index.html")
url = "file://" + os.path.join(work_dir, "index.html")
webbrowser.open(url, new=1, autoraise=True)

30 changes: 18 additions & 12 deletions nmodl/dsl.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import os.path as osp
from pkg_resources import *
import sys

if sys.version_info >= (3, 9):
from importlib.resources import files
else:
from importlib_resources import files

from ._nmodl import *

RESOURCE_DIR = "ext/example"


def list_examples():
"""Returns a list of examples available
Expand All @@ -13,10 +18,11 @@ def list_examples():
Returns:
List of available examples
"""
if resource_exists(__name__, RESOURCE_DIR) and resource_isdir(__name__, RESOURCE_DIR):
return resource_listdir(__name__, RESOURCE_DIR)
else:
raise FileNotFoundError("Could not find sample directory")
path = files("nmodl") / RESOURCE_DIR
if path.exists() and path.is_dir():
return [result.name for result in path.glob("*.mod")]

raise FileNotFoundError("Could not find sample directory")


def load_example(example):
Expand All @@ -29,10 +35,10 @@ def load_example(example):
Args:
example: Filename of an example as provided by `list_examples()`
Returns:
List of available examples
An path to the example as a string
"""
resource = osp.join(RESOURCE_DIR, example)
if resource_exists(__name__, resource):
return resource_string(__name__, resource)
else:
raise FileNotFoundError("Could not find sample mod files")
path = files("nmodl") / RESOURCE_DIR / example
if path.exists():
return path.read_text()

raise FileNotFoundError(f"Could not find sample mod file {example}")
39 changes: 22 additions & 17 deletions pywheel/shim/_binwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,44 @@
A generic wrapper to access nmodl binaries from a python installation
Please create a softlink with the binary name to be called.
"""

import os
import sys
import stat
from pkg_resources import working_set
import sys


if sys.version_info >= (3, 9):
from importlib.metadata import metadata, PackageNotFoundError
from importlib.resources import files
else:
from importlib_metadata import metadata, PackageNotFoundError
from importlib_resources import files

from find_libpython import find_libpython


def _config_exe(exe_name):
"""Sets the environment to run the real executable (returned)"""

package_name = "nmodl"

if package_name not in working_set.by_key:
print ("INFO : Using nmodl-nightly Package (Developer Version)")
package_name = 'nmodl-nightly'

assert (
package_name in working_set.by_key
), "NMODL package not found! Verify PYTHONPATH"
try:
metadata("nmodl-nightly")
print("INFO : Using nmodl-nightly Package (Developer Version)")
except PackageNotFoundError:
pass

NMODL_PREFIX = os.path.join(working_set.by_key[package_name].location, "nmodl")
NMODL_HOME = os.path.join(NMODL_PREFIX, ".data")
NMODL_BIN = os.path.join(NMODL_HOME, "bin")
NMODL_PREFIX = files("nmodl")
NMODL_HOME = NMODL_PREFIX / ".data"
NMODL_BIN = NMODL_HOME / "bin"

# add libpython*.so path to environment
os.environ["NMODL_PYLIB"] = find_libpython()

# add nmodl home to environment (i.e. necessary for nrnunits.lib)
os.environ["NMODLHOME"] = NMODL_HOME
os.environ["NMODLHOME"] = str(NMODL_HOME)

# set PYTHONPATH for embedded python to properly find the nmodl module
os.environ["PYTHONPATH"] = working_set.by_key[package_name].location + ':' + os.environ.get("PYTHONPATH", "")
os.environ["PYTHONPATH"] = (
str(NMODL_PREFIX.parent) + ":" + os.environ.get("PYTHONPATH", "")
)

return os.path.join(NMODL_BIN, exe_name)

Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ sympy
numpy
find_libpython
scikit-build
importlib_resources;python_version<"3.9"
importlib_resources;python_version<'3.9'
importlib_metadata;python_version<'3.9'
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
Please create a softlink with the binary name to be called.
"""
import stat
from pkg_resources import working_set
from find_libpython import find_libpython


Expand Down Expand Up @@ -78,6 +77,7 @@ def run(self, *args, **kwargs):
"sympy>=1.3",
"find_libpython",
"importlib_resources;python_version<'3.9'",
"importlib_metadata;python_version<'3.9'",
]


Expand Down
21 changes: 21 additions & 0 deletions test/unit/pybind/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from json import loads
from pathlib import Path

from nmodl import dsl


def test_example():
"""
Test for the Python API from example
"""

examples = dsl.list_examples()

# ordering may be off so we use a set
assert set(examples) == {"exp2syn.mod", "expsyn.mod", "hh.mod", "passive.mod"}

driver = dsl.NmodlDriver()
for example in examples:
nmodl_string = dsl.load_example(example)
# make sure we can parse the string
assert driver.parse_string(nmodl_string)

0 comments on commit 3ff1d01

Please sign in to comment.