Skip to content

Commit

Permalink
Fix liberator parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Erotemic committed Aug 22, 2023
1 parent c48f643 commit c935c4c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 57 deletions.
70 changes: 40 additions & 30 deletions dev/maintain/port_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,37 @@
Statically port utilities from ubelt and xdocest need for the autoprofile
features.
"""
import ubelt as ub
import liberator
import re


def _autogen_util_static():
import ubelt as ub
import liberator
lib = liberator.Liberator()
def generate_util_static():
lib = liberator.Liberator(verbose=0)

import ubelt
import xdoctest
lib.add_dynamic(ubelt.util_import.modpath_to_modname)
lib.add_dynamic(ubelt.util_import.modname_to_modpath)
lib.expand(['ubelt'])
lib.add_dynamic(xdoctest.static_analysis.package_modpaths)
lib.expand(['xdoctest'])

# Hack because ubelt and xdoctest define this
del lib.body_defs['xdoctest.utils.util_import._platform_pylib_exts']
if 1:
lib.add_dynamic(ubelt.util_import.modpath_to_modname)
lib.add_dynamic(ubelt.util_import.modname_to_modpath)
lib.expand(['ubelt'])

if 1:
lib.add_dynamic(xdoctest.static_analysis.package_modpaths)
lib.expand(['xdoctest'])

# # Hack because ubelt and xdoctest define this
del lib.body_defs['xdoctest.utils.util_import._platform_pylib_exts']

# lib.expand(['ubelt', 'xdoctest'])
text = lib.current_sourcecode()
print(text)

"""
pip install rope
pip install parso
"""

import parso
import xdoctest
import line_profiler
target_fpath = ub.Path(line_profiler.__file__).parent / 'autoprofile' / 'util_static.py'

new_module = parso.parse(text)
if target_fpath.exists():
old_module = parso.parse(target_fpath.read_text())
new_names = [child.name.value for child in new_module.children if child.type in {'funcdef', 'classdef'}]
old_names = [child.name.value for child in old_module.children if child.type in {'funcdef', 'classdef'}]

print(set(old_names) - set(new_names))
print(set(new_names) - set(old_names))

prefix = ub.codeblock(
'''
"""
Expand All @@ -54,7 +44,6 @@ def _autogen_util_static():

# Remove doctest references to ubelt
new_lines = []
import re
for line in text.split('\n'):
if line.strip().startswith('>>> from ubelt'):
continue
Expand All @@ -63,15 +52,36 @@ def _autogen_util_static():
new_lines.append(line)

text = '\n'.join(new_lines)
target_fpath.write_text(prefix + '\n' + text + '\n')
text = prefix + '\n' + text + '\n'
return text


def main():
text = generate_util_static()
print(ub.highlight_code(text, backend='rich'))

import parso
import line_profiler
target_fpath = ub.Path(line_profiler.__file__).parent / 'autoprofile' / 'util_static.py'

new_module = parso.parse(text)
if target_fpath.exists():
old_module = parso.parse(target_fpath.read_text())
new_names = [child.name.value for child in new_module.children if child.type in {'funcdef', 'classdef'}]
old_names = [child.name.value for child in old_module.children if child.type in {'funcdef', 'classdef'}]
print(set(old_names) - set(new_names))
print(set(new_names) - set(old_names))

target_fpath.write_text(text)

# Fixup formatting
ub.cmd(['black', target_fpath])
if 1:
ub.cmd(['black', target_fpath])


if __name__ == '__main__':
"""
CommandLine:
python ~/code/line_profiler/dev/maintain/port_utilities.py
"""
_autogen_util_static()
main()
38 changes: 11 additions & 27 deletions line_profiler/autoprofile/util_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def package_modpaths(
check=True,
):
r"""
Finds sub-packages and sub-modules belonging to a package.
Args:
Expand Down Expand Up @@ -61,7 +60,6 @@ def package_modpaths(
>>> assert 'xdoctest.__main__' in names
>>> assert 'xdoctest' not in names
>>> print('\n'.join(names))
"""
if isfile(pkgpath):
(yield pkgpath)
Expand Down Expand Up @@ -96,9 +94,7 @@ def package_modpaths(

def _parse_static_node_value(node):
"""
Extract a constant value from a node if possible
"""
import ast
from collections import OrderedDict
Expand All @@ -119,18 +115,20 @@ def _parse_static_node_value(node):
value = node.value
else:
print(node.__dict__)
raise TypeError("""Cannot parse a static value from non-static node of type: {!r}""".format(type(node)))
raise TypeError(
"""Cannot parse a static value from non-static node of type: {!r}""".format(
type(node)
)
)
return value


def _extension_module_tags():
"""
Returns valid tags an extension module might have
Returns:
List[str]
"""
import sysconfig

Expand All @@ -142,8 +140,7 @@ def _extension_module_tags():


def _static_parse(varname, fpath):
r"""
"""
Statically parse the a constant variable from a python file
Example:
Expand All @@ -169,7 +166,6 @@ def _static_parse(varname, fpath):
>>> with pytest.raises(AttributeError):
>>> fpath.write_text('a = list(range(10))')
>>> assert _static_parse('c', fpath) is None
"""
import ast

Expand Down Expand Up @@ -197,15 +193,13 @@ def visit_Assign(self, node):

def _platform_pylib_exts():
"""
Returns .so, .pyd, or .dylib depending on linux, win or mac.
On python3 return the previous with and without abi (e.g.
.cpython-35m-x86_64-linux-gnu) flags. On python2 returns with
and without multiarch.
Returns:
tuple
"""
import sysconfig

Expand All @@ -218,8 +212,7 @@ def _platform_pylib_exts():


def _syspath_modname_to_modpath(modname, sys_path=None, exclude=None):
r"""
"""
syspath version of modname_to_modpath
Args:
Expand Down Expand Up @@ -279,7 +272,6 @@ def _syspath_modname_to_modpath(modname, sys_path=None, exclude=None):
>>> ' cwd={} '.format(os.getcwd()) +
>>> ' sys.path={} '.format(sys.path)
>>> )
"""
import glob

Expand Down Expand Up @@ -385,8 +377,7 @@ def check_dpath(dpath):


def modname_to_modpath(modname, hide_init=True, hide_main=False, sys_path=None):
r"""
"""
Finds the path to a python module from its name.
Determines the path to a python module without directly import it
Expand Down Expand Up @@ -425,7 +416,6 @@ def modname_to_modpath(modname, hide_init=True, hide_main=False, sys_path=None):
>>> # xdoctest: +REQUIRES(CPython)
>>> modpath = basename(modname_to_modpath('_ctypes'))
>>> assert 'ctypes' in modpath
"""
modpath = _syspath_modname_to_modpath(modname, sys_path)
if modpath is None:
Expand All @@ -435,8 +425,7 @@ def modname_to_modpath(modname, hide_init=True, hide_main=False, sys_path=None):


def split_modpath(modpath, check=True):
r"""
"""
Splits the modpath into the dir that must be in PYTHONPATH for the module
to be imported and the modulepath relative to this directory.
Expand All @@ -459,7 +448,6 @@ def split_modpath(modpath, check=True):
>>> recon = join(dpath, rel_modpath)
>>> assert recon == modpath
>>> assert rel_modpath == join('xdoctest', 'static_analysis.py')
"""
modpath_ = abspath(expanduser(modpath))
if check:
Expand All @@ -481,8 +469,7 @@ def split_modpath(modpath, check=True):


def normalize_modpath(modpath, hide_init=True, hide_main=False):
r"""
"""
Normalizes __init__ and __main__ paths.
Args:
Expand Down Expand Up @@ -516,7 +503,6 @@ def normalize_modpath(modpath, hide_init=True, hide_main=False):
>>> assert res1.endswith('__init__.py')
>>> assert not res2.endswith('.py')
>>> assert not res3.endswith('.py')
"""
if hide_init:
if basename(modpath) == "__init__.py":
Expand All @@ -537,8 +523,7 @@ def normalize_modpath(modpath, hide_init=True, hide_main=False):
def modpath_to_modname(
modpath, hide_init=True, hide_main=False, check=True, relativeto=None
):
r"""
"""
Determines importable name from file path
Converts the path to a module (__file__) to the importable python name
Expand Down Expand Up @@ -589,7 +574,6 @@ def modpath_to_modname(
>>> modpath = '/foo/libfoobar.linux-x86_64-3.6.so'
>>> modname = modpath_to_modname(modpath, check=False)
>>> assert modname == 'libfoobar'
"""
if check and (relativeto is None):
if not exists(modpath):
Expand Down
2 changes: 2 additions & 0 deletions line_profiler/line_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ def show_func(filename, start_lineno, func_name, timings, unit,
return

if rich:
# References:
# https://github.com/Textualize/rich/discussions/3076
try:
from rich.syntax import Syntax
from rich.highlighter import ReprHighlighter
Expand Down

0 comments on commit c935c4c

Please sign in to comment.