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
3 changes: 2 additions & 1 deletion dev/check_pytest_version_compat.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os
import ubelt as ub
from distutils.version import LooseVersion

import ubelt as ub

os.chdir(ub.expandpath('$HOME/code/pytest'))

info = ub.cmd('git tag')
Expand Down
4 changes: 3 additions & 1 deletion dev/demo/demo_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def demo():
xdoctest.doctest_callable(demo_requires_skips_all_v1)
xdoctest.doctest_callable(demo_requires_skips_all_v2)

import sys, ubelt
import sys

import ubelt

sys.path.append(ubelt.expandpath('~/code/xdoctest/dev/demo'))
import demo_issues
Expand Down
3 changes: 2 additions & 1 deletion dev/maintain/port_ubelt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@


def _autogen_xdoctest_utils():
import ubelt as ub
import liberator
import ubelt as ub

lib = liberator.Liberator()

Expand All @@ -36,6 +36,7 @@ def _autogen_xdoctest_utils():

# target_fpath = ub.Path('~/code/xdoctest/src/xdoctest/utils/util_import.py').expand()
import parso

import xdoctest

target_fpath = ub.Path(xdoctest.utils.util_import.__file__)
Expand Down
1 change: 1 addition & 0 deletions dev/make_rtd.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

def initialize_docs():
from os.path import join

import setup

setupkw = setup.setupkw
Expand Down
3 changes: 2 additions & 1 deletion dev/run_linter.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ def main():
]
flake8_args = ' '.join(flake8_args_list)

import ubelt as ub
import sys

import ubelt as ub

loc = ub.expandpath('~/code/xdoctest/xdoctest')
command = 'flake8 ' + flake8_args + ' ' + loc
print('command = {!r}'.format(command))
Expand Down
1 change: 0 additions & 1 deletion dev/talk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import operator


# def paragraph(text):
# r"""
# Remove leading, trailing, and double whitespace from multi-line strings.
Expand Down
11 changes: 6 additions & 5 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,9 @@
# sys.path.insert(0, os.path.abspath('.'))

# -- Project information -----------------------------------------------------
from os.path import dirname, exists, join

import sphinx_rtd_theme
from os.path import exists
from os.path import dirname
from os.path import join


def parse_version(fpath):
Expand Down Expand Up @@ -836,10 +835,11 @@ def create_doctest_figure(app, obj, name, lines):
The idea is that each doctest that produces a figure should generate that
and then that figure should be part of the docs.
"""
import xdoctest
import sys
import types

import xdoctest

if isinstance(obj, types.ModuleType):
module = obj
else:
Expand Down Expand Up @@ -1033,9 +1033,10 @@ def postprocess_hyperlinks(app, doctree, docname):
"autodoc-process-docstring" event.
"""
# Your hyperlink postprocessing logic here
from docutils import nodes
import pathlib

from docutils import nodes

for node in doctree.traverse(nodes.reference):
if 'refuri' in node.attributes:
refuri = node.attributes['refuri']
Expand Down
2 changes: 0 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,3 @@ indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
docstring-code-format = false


3 changes: 2 additions & 1 deletion run_tests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python
if __name__ == '__main__':
import pytest
import sys

import pytest

package_name = 'xdoctest'
mod_dpath = 'src/xdoctest'
test_dpath = 'tests'
Expand Down
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/usr/bin/env python
# Generated by ~/code/xcookie/xcookie/builders/setup.py
# based on part ~/code/xcookie/xcookie/rc/setup.py.in
import sys
import re
from os.path import exists, dirname, join
from setuptools import find_packages
from setuptools import setup
import sys
from os.path import dirname, exists, join

from setuptools import find_packages, setup


def parse_version(fpath):
Expand Down
3 changes: 2 additions & 1 deletion src/xdoctest/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import difflib
import re
import typing
from collections import OrderedDict

from xdoctest import constants, directive, utils

Expand Down Expand Up @@ -370,7 +371,7 @@ def _ellipsis_match(got: typing.Any, want: typing.Any) -> bool:
def normalize(
got: str,
want: str,
runstate: directive.RuntimeState | dict[str, object] | None = None,
runstate: directive.RuntimeState | dict[str, bool | set[str]] | OrderedDict[str, bool | set[str]] | None = None,
) -> tuple[str, str]:
r"""
Normalizes the got and want string based on the runtime state.
Expand Down
32 changes: 19 additions & 13 deletions src/xdoctest/directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
import typing
import warnings
from collections import OrderedDict, namedtuple
from typing import cast

from xdoctest import static_analysis as static
from xdoctest import utils
Expand All @@ -183,7 +184,12 @@ def named(key: str, pattern: str) -> str:

# TODO: modify global directive defaults via a config file

DEFAULT_RUNTIME_STATE = {
# Type alias for the runtime state dictionary
if typing.TYPE_CHECKING:
# TODO: we can use a more structured dictionary for better type checks.
RuntimeStateDict = dict[str, bool | set[str]]

DEFAULT_RUNTIME_STATE: RuntimeStateDict = {
'DONT_ACCEPT_BLANKLINE': False,
'ELLIPSIS': True,
'IGNORE_WHITESPACE': False,
Expand Down Expand Up @@ -265,18 +271,18 @@ class RuntimeState(utils.NiceRepr):
})>
"""

def __init__(self, default_state: dict[str, object] | None = None):
def __init__(self, default_state: RuntimeStateDict | None = None):
"""
Args:
default_state (None | dict): starting default state, if unspecified
falls back to the global DEFAULT_RUNTIME_STATE
"""
self._global_state = copy.deepcopy(DEFAULT_RUNTIME_STATE)
self._global_state: RuntimeStateDict = copy.deepcopy(DEFAULT_RUNTIME_STATE)
if default_state:
self._global_state.update(default_state)
self._inline_state: dict[str, typing.Any] = {}

def to_dict(self) -> dict[str, object]:
def to_dict(self) -> OrderedDict[str, bool | set[str]]:
"""
Returns:
OrderedDict
Expand Down Expand Up @@ -309,23 +315,23 @@ def __getitem__(self, key: str) -> object:
else:
return self._global_state[key]

def __setitem__(self, key: str, value: object):
def __setitem__(self, key: str, value: bool | set[str]):
"""
Args:
key (str):
value (Any):
value (bool | set[str]):
"""
if key not in self._global_state:
raise KeyError('Unknown key: {}'.format(key))
self._global_state[key] = value

def set_report_style(
self, reportchoice: str, state: dict[str, object] | None = None
self, reportchoice: str, state: RuntimeStateDict | None = None
):
"""
Args:
reportchoice (str): name of report style
state (None | Dict): if unspecified defaults to the global state
state (None | RuntimeStateDict): if unspecified defaults to the global state

Example:
>>> from xdoctest.directive import *
Expand Down Expand Up @@ -375,10 +381,10 @@ def update(self, directives: list[Directive]):
elif action == 'assign':
state[key] = value
elif action == 'set.add':
state[key].add(value) # type: ignore[unresolved-attribute]
cast(set, state[key]).add(value)
elif action == 'set.remove':
try:
state[key].remove(value) # type: ignore[unresolved-attribute]
cast(set, state[key]).remove(value)
except KeyError:
pass
else:
Expand Down Expand Up @@ -573,7 +579,7 @@ def effects(
This is called by :func:`RuntimeState.update` to update itself

Args:
argv (List[str] | None):
argv (list[str] | None):
Command line the directive is interpreted in the context of.
If unspecified, uses ``sys.argv``.

Expand All @@ -582,7 +588,7 @@ def effects(
context of. If unspecified, uses ``os.environ``.

Returns:
List[Effect]: list of named tuples containing:
list[Effect]: list of named tuples containing:
action (str): code indicating how to update
key (str): name of runtime state item to modify
value (object): value to modify with
Expand Down Expand Up @@ -680,7 +686,7 @@ def _split_opstr(optstr: str) -> list[str]:
opstr (str): the command, which may contain more than one directive

Returns:
List[str]: individual directive optstrings
list[str]: individual directive optstrings

Example:
>>> optstr = '+FOO, REQUIRES(foo,bar), +ELLIPSIS'
Expand Down
8 changes: 4 additions & 4 deletions src/xdoctest/doctest_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def str_lower(x):
if argname in environ_aware:
env_argname = 'XDOCTEST_' + argname.replace('-', '_').upper()
if 'default' in kw:
kw['default'] = os.environ.get(env_argname, kw['default']) # type: ignore[invalid-assignment]
kw['default'] = os.environ.get(env_argname, kw['default']) # type: ignore

alias = [
a.replace('--', '--' + p + '-') if p else a
Expand Down Expand Up @@ -972,7 +972,7 @@ def run(
print(f'runstate._global_state={runstate._global_state}')

# Handle runtime actions
if runstate['SKIP'] or len(runstate['REQUIRES']) > 0: # type: ignore[arg-type]
if runstate['SKIP'] or len(runstate['REQUIRES']) > 0: # type: ignore
if DEBUG:
print(f'part[{partx}] runstate requests skipping')
self._skipped_parts.append(part)
Expand Down Expand Up @@ -1573,8 +1573,8 @@ def r1_strip_nl(text):
if hasattr(ex_value, 'output_difference'):
assert hasattr(ex_value, 'output_repr_difference')
lines += [
ex_value.output_difference(self._runstate, colored=colored), # type: ignore[call-non-callable]
ex_value.output_repr_difference(self._runstate), # type: ignore[call-non-callable]
ex_value.output_difference(self._runstate, colored=colored), # type: ignore
ex_value.output_repr_difference(self._runstate), # type: ignore
]
else:
if with_tb:
Expand Down
12 changes: 6 additions & 6 deletions src/xdoctest/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def from_parent(
name,
runner=None,
dtest=None,
): # type: ignore[invalid-method-override]
): # type: ignore
# incompatible signature due to imposed limits on subclass
"""The public named constructor."""
return super().from_parent(
Expand Down Expand Up @@ -321,7 +321,7 @@ def runtest(self):
if not self.dtest.anything_ran():
pytest.skip('doctest is empty or all parts were skipped')

def repr_failure(self, excinfo): # type: ignore[invalid-method-override]
def repr_failure(self, excinfo): # type: ignore
"""
# Args:
# excinfo (_pytest._code.code.ExceptionInfo):
Expand Down Expand Up @@ -454,18 +454,18 @@ def func():
node=xdoctest_item,
func=func,
cls=None,
funcargs=False, # type: ignore[attr-defined, call-arg]
funcargs=False, # type: ignore
)
# Note: FixtureRequest may change in the future, we are using
# private functionality. Hopefully it wont break, but we should
# check to see if there is a better way to do this
# https://github.com/pytest-dev/pytest/discussions/8512#discussioncomment-563347
if _PYTEST_IS_GE_620:
# The "_ispytest" arg was added in 3.6.1
fixture_request = fixtures.FixtureRequest(xdoctest_item, _ispytest=True) # type: ignore[abstract, call-arg, arg-type]
fixture_request = fixtures.FixtureRequest(xdoctest_item, _ispytest=True) # type: ignore
else:
fixture_request = fixtures.FixtureRequest(xdoctest_item) # type: ignore[abstract, call-arg, arg-type]
fixture_request._fillfixtures() # type: ignore[attr-defined]
fixture_request = fixtures.FixtureRequest(xdoctest_item) # type: ignore
fixture_request._fillfixtures() # type: ignore
return fixture_request


Expand Down
8 changes: 4 additions & 4 deletions src/xdoctest/static_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,9 @@ def func7():
endpos = docnode.lineno - 1

if IS_PY_GE_312:
docstr = utils.ensure_unicode(docnode.value.value) # type: ignore[attr-defined]
docstr = utils.ensure_unicode(docnode.value.value) # type: ignore
else:
docstr = utils.ensure_unicode(docnode.value.s) # type: ignore[attr-defined]
docstr = utils.ensure_unicode(docnode.value.s) # type: ignore
sourcelines = self.sourcelines
assert sourcelines is not None
start, stop = self._find_docstr_startpos_workaround(
Expand Down Expand Up @@ -778,12 +778,12 @@ def parse_static_calldefs(
try:
# fixme: This might never happen, could clean up this code if we can confirm
with open(fpath, 'rb') as file_:
source = file_.read() # type: ignore[invalid-assignment, assignment, arg-type]
source = file_.read() # type: ignore
except Exception:
print('Unable to read fpath = {!r}'.format(fpath))
raise
try:
self = TopLevelVisitor.parse(source) # type: ignore[invalid-argument-type, arg-type]
self = TopLevelVisitor.parse(source) # type: ignore
return self.calldefs
except Exception: # nocover
if fpath:
Expand Down
4 changes: 2 additions & 2 deletions src/xdoctest/utils/util_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class NiceRepr:
def __repr__(self):
try:
classname = self.__class__.__name__
devnice = self.__nice__() # type: ignore[unresolved-attribute]
devnice = self.__nice__() # type: ignore
return '<%s(%s) at %s>' % (classname, devnice, hex(id(self)))
except AttributeError:
if hasattr(self, '__nice__'):
Expand All @@ -40,7 +40,7 @@ def __repr__(self):
def __str__(self):
try:
classname = self.__class__.__name__
devnice = self.__nice__() # type: ignore[unresolved-attribute]
devnice = self.__nice__() # type: ignore
return '<%s(%s)>' % (classname, devnice)
except AttributeError:
if hasattr(self, '__nice__'):
Expand Down
Loading
Loading