Skip to content

Commit

Permalink
Merge pull request #9 from tillahoffmann/mypy
Browse files Browse the repository at this point in the history
Add static type analysis.
  • Loading branch information
tillahoffmann authored Feb 16, 2024
2 parents c1cf827 + 6772cf0 commit fe43343
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 11 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ build : setup.py docs doctests lint tests
lint :
flake8
black --check .
mypy localscope

docs :
# Always build from scratch because of dodgy Sphinx caching.
Expand Down
8 changes: 8 additions & 0 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
]
exclude_patterns = [
Expand All @@ -13,3 +14,10 @@
"venv",
]
doctest_global_setup = "from localscope import localscope"
intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
}
nitpick_ignore = [
("py:class", "code"),
("py:class", "function"),
]
19 changes: 10 additions & 9 deletions localscope/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
import inspect
import logging
import types
from typing import Callable, Set, Optional
from typing import Any, Callable, Dict, Optional, Set, Union


LOGGER = logging.getLogger(__name__)


def localscope(
func: Optional[Callable] = None,
func: Optional[Union[types.FunctionType, types.CodeType]] = None,
*,
predicate: Optional[Callable] = None,
allowed: Optional[Set[str]] = None,
allow_closure: bool = False,
_globals: Optional[Set[str]] = None,
_globals: Optional[Dict[str, Any]] = None,
):
"""
Restrict the scope of a callable to local variables to avoid unintentional
Expand Down Expand Up @@ -87,7 +87,7 @@ def localscope(
"""
# Set defaults
predicate = predicate or inspect.ismodule
allowed = list(allowed or [])
allowed = set(allowed) if allowed else set()
if func is None:
return ft.partial(
localscope,
Expand All @@ -101,9 +101,10 @@ def localscope(
_globals = {**func.__globals__, **inspect.getclosurevars(func).nonlocals}
else:
code = func
_globals = _globals or {}

# Add function arguments to the list of allowed exceptions
allowed.extend(code.co_varnames[: code.co_argcount])
allowed.update(code.co_varnames[: code.co_argcount])

opnames = {"LOAD_GLOBAL"}
if not allow_closure:
Expand All @@ -125,9 +126,9 @@ def localscope(
if not predicate(value):
raise ValueError(f"`{name}` is not a permitted global")
elif instruction.opname == "STORE_DEREF":
allowed.append(name)
# Deal with code objects recursively after add the current arguments to the allowed
# exceptions
allowed.add(name)
# Deal with code objects recursively after adding the current arguments to the
# allowed exceptions
for const in code.co_consts:
if isinstance(const, types.CodeType):
localscope(
Expand All @@ -145,4 +146,4 @@ def _allow_mfc(x):
return inspect.ismodule(x) or inspect.isfunction(x) or inspect.isclass(x)


localscope.mfc = localscope(predicate=_allow_mfc)
localscope.mfc = localscope(predicate=_allow_mfc) # type: ignore[attr-defined]
1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
-e file:.[tests,docs]
black
mypy
twine
# Additional version restrictions for Python 3.8.
alabaster <= 0.7.13
Expand Down
11 changes: 9 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ mdurl==0.1.2
# via markdown-it-py
more-itertools==10.2.0
# via jaraco-classes
mypy==1.8.0
# via -r requirements.in
mypy-extensions==1.0.0
# via black
# via
# black
# mypy
nh3==0.2.15
# via readme-renderer
packaging==23.2
Expand Down Expand Up @@ -133,11 +137,14 @@ tomli==2.0.1
# via
# black
# coverage
# mypy
# pytest
twine==5.0.0
# via -r requirements.in
typing-extensions==4.9.0
# via black
# via
# black
# mypy
urllib3==2.2.0
# via
# requests
Expand Down

0 comments on commit fe43343

Please sign in to comment.