Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into sandratsy/master
Browse files Browse the repository at this point in the history
  • Loading branch information
lieryan committed Mar 5, 2024
2 parents 3d2cc6d + 8b3478e commit 60d0e02
Show file tree
Hide file tree
Showing 46 changed files with 419 additions and 142 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ __pycache__/
.Python
build/
develop-eggs/
dist/
/dist/
downloads/
eggs/
.eggs/
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
repos:

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-added-large-files

- repo: https://github.com/psf/black
rev: 22.12.0
rev: 24.1.1
hooks:
- id: black
name: black check (Python)

- repo: https://github.com/pycqa/isort
rev: 5.11.3
rev: 5.13.2
hooks:
- id: isort
name: Sort imports (Python)
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# **Upcoming release**

- Check for ast.Attributes when finding occurrences in fstrings (@sandratsy)
- #777, #698 add validation to refuse Rename refactoring to a python keyword
- #730 Match on module aliases for autoimport suggestions
- #755 Remove dependency on `build` package being installed while running tests

# Release 1.12.0

Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
include README.rst COPYING setup.py MANIFEST.in CHANGELOG.md
include README.rst COPYING setup.py MANIFEST.in CHANGELOG.md ropetest-package-fixtures/external_fixturepkg/dist/external_fixturepkg-1.0.0-py3-none-any.whl ropetest-package-fixtures/external_fixturepkg/dist/external_fixturepkg-1.0.0.tar.gz
recursive-include rope *.py
recursive-include docs *.rst
recursive-include ropetest *.py
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#
import os
import sys

sys.path.insert(0, os.path.abspath(".."))


Expand Down
9 changes: 7 additions & 2 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Will be used if [tool.rope] is configured.
[tool.rope]
split_imports = true
autoimport.aliases = [
['dt', 'datetime'],
['mp', 'multiprocessing'],
]
config.py
---------
Expand Down Expand Up @@ -48,9 +53,9 @@ Additionally, you can run an executable function at startup of rope.
pytool.toml
-----------
If neither a config.py or a pyproject.toml is present, rope will use a pytool.toml.
It follows the exact same syntax of the pyproject.toml.
It follows the exact same syntax as ``pyproject.toml``.

- Mac OS X: ``~/Library/Application Support/pytool.toml.``
- Mac OS X: ``~/Library/Application Support/pytool.toml``.
- Unix: ``~/.config/pytool.toml``` or in $XDG_CONFIG_HOME, if defined
- Windows: ``C:\Users\<username>\AppData\Local\pytool.toml``

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ profile = "black"

[tool.pytest.ini_options]

testpaths = "ropetest"
python_files = [
"*test.py",
"__init__.py",
Expand Down
1 change: 1 addition & 0 deletions rope/base/builtins.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module tries to support builtin types and functions."""

import inspect
import io

Expand Down
1 change: 1 addition & 0 deletions rope/base/fscommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
`MercurialCommands` for example.
"""

import os
import re
import shutil
Expand Down
1 change: 1 addition & 0 deletions rope/base/libutils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""A few useful functions for using rope as a library"""

import os.path

import rope.base.project
Expand Down
1 change: 1 addition & 0 deletions rope/base/oi/soi.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package.
"""

import rope.base.builtins # Use full qualification for clarity.
from rope.base import arguments, evaluate, pynames, pyobjects, utils
from rope.base.oi.type_hinting.factory import get_type_hinting_factory
Expand Down
1 change: 1 addition & 0 deletions rope/base/oi/transform.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Provides classes for persisting `PyObject`"""

import os
import re

Expand Down
1 change: 1 addition & 0 deletions rope/base/oi/type_hinting/providers/docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- https://groups.google.com/d/topic/rope-dev/LCFNN98vckI/discussion
"""

import re

from rope.base.oi.type_hinting import utils
Expand Down
1 change: 1 addition & 0 deletions rope/base/oi/type_hinting/providers/numpydocstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
https://github.com/davidhalter/jedi/blob/b489019f5bd5750051122b94cc767df47751ecb7/jedi/evaluate/docstrings.py
Thanks to @davidhalter for this utils under MIT License.
"""

import re

from rope.base.ast import literal_eval
Expand Down
27 changes: 26 additions & 1 deletion rope/base/prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@
from rope.base.resources import Folder


@dataclass
class AutoimportPrefs:
# underlined: bool = field(
# default=False, description="Cache underlined (private) modules")
# memory: bool = field(default=None, description="Cache in memory instead of disk")
# parallel: bool = field(default=True, description="Use multiple processes to parse")

aliases: List[Tuple[str, str]] = field(
default_factory=lambda : [
("np", "numpy"),
("pd", "pandas"),
("plt", "matplotlib.pyplot"),
("sns", "seaborn"),
("tf", "tensorflow"),
("sk", "sklearn"),
("sm", "statsmodels"),
],
description=dedent("""
Aliases for module names. For example, `[('np', 'numpy')]` makes rope recommend
``import numpy as np``.
"""),
)


@dataclass
class Prefs:
"""Class to store rope preferences."""
Expand Down Expand Up @@ -139,7 +163,6 @@ class Prefs:
appear in the importing namespace.
"""),
)

prefer_module_from_imports: bool = field(
default=False,
description=dedent("""
Expand Down Expand Up @@ -206,6 +229,8 @@ class Prefs:
Can only be set in config.py.
"""),
)
autoimport: AutoimportPrefs = field(
default_factory=AutoimportPrefs, description="Preferences for Autoimport")

def set(self, key: str, value: Any):
"""Set the value of `key` preference to `value`."""
Expand Down
1 change: 1 addition & 0 deletions rope/base/project.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from __future__ import annotations

import contextlib
import json
import os
Expand Down
1 change: 1 addition & 0 deletions rope/base/simplify.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This module is here to help source code analysis.
"""

import re

from rope.base import codeanalyze, utils
Expand Down
5 changes: 4 additions & 1 deletion rope/base/versioning.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import dataclasses
import hashlib
import importlib.util
import json
Expand Down Expand Up @@ -31,7 +32,9 @@ def _get_prefs_data(project) -> str:
del prefs_data["project_opened"]
del prefs_data["callbacks"]
del prefs_data["dependencies"]
return json.dumps(prefs_data, sort_keys=True, indent=2)
return json.dumps(
prefs_data, sort_keys=True, indent=2, default=lambda o: o.__dict__
)


def _get_file_content(module_name: str) -> str:
Expand Down
1 change: 1 addition & 0 deletions rope/contrib/autoimport/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""AutoImport module for rope."""

from .pickle import AutoImport as _PickleAutoImport
from .sqlite import AutoImport as _SqliteAutoImport

Expand Down
8 changes: 8 additions & 0 deletions rope/contrib/autoimport/defs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Definitions of types for the Autoimport program."""

import pathlib
from enum import Enum
from typing import NamedTuple, Optional
Expand Down Expand Up @@ -92,6 +93,13 @@ class Package(NamedTuple):
type: PackageType


class Alias(NamedTuple):
"""A module alias to be added to the database."""

alias: str
modname: str


class Name(NamedTuple):
"""A Name to be added to the database."""

Expand Down
29 changes: 25 additions & 4 deletions rope/contrib/autoimport/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,11 @@ def delete_from(self) -> FinalQuery:
class Model(ABC):
@property
@abstractmethod
def table_name(self) -> str:
...
def table_name(self) -> str: ...

@property
@abstractmethod
def schema(self) -> Dict[str, str]:
...
def schema(self) -> Dict[str, str]: ...

@classmethod
def create_table(cls, connection):
Expand All @@ -88,6 +86,29 @@ class Metadata(Model):
objects = Query(table_name, columns)


class Alias(Model):
table_name = "aliases"
schema = {
"alias": "TEXT",
"module": "TEXT",
}
columns = list(schema.keys())
objects = Query(table_name, columns)

@classmethod
def create_table(cls, connection):
super().create_table(connection)
connection.execute(
"CREATE INDEX IF NOT EXISTS aliases_alias_nocase ON aliases(alias COLLATE NOCASE)"
)

modules = Query(
"(SELECT DISTINCT aliases.*, package, source, type FROM aliases INNER JOIN names on aliases.module = names.module)",
columns + ["package", "source", "type"],
)
search_modules_with_alias = modules.where("alias LIKE (?)")


class Name(Model):
table_name = "names"
schema = {
Expand Down
1 change: 0 additions & 1 deletion rope/contrib/autoimport/pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
sqlite-based storage backend (rope.contrib.autoimport.sqlite.AutoImport).
"""


import contextlib
import re

Expand Down
19 changes: 17 additions & 2 deletions rope/contrib/autoimport/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

import contextlib
import json
from hashlib import sha256
import secrets
import re
import secrets
import sqlite3
import sys
import warnings
from collections import OrderedDict
from concurrent.futures import Future, ProcessPoolExecutor, as_completed
from datetime import datetime
from hashlib import sha256
from itertools import chain
from pathlib import Path
from threading import local
Expand All @@ -21,6 +21,7 @@
from rope.base.resources import Resource
from rope.contrib.autoimport import models
from rope.contrib.autoimport.defs import (
Alias,
ModuleFile,
Name,
NameType,
Expand Down Expand Up @@ -330,6 +331,13 @@ def _search_module(
yield SearchResult(
f"import {module}", module, source, NameType.Module.value
)
for alias, module, source in self._execute(
models.Alias.search_modules_with_alias.select("alias", "module", "source"),
(name,),
):
yield SearchResult(
f"import {module} as {alias}", alias, source, NameType.Module.value
)

def get_modules(self, name) -> List[str]:
"""Get the list of modules that have global `name`."""
Expand Down Expand Up @@ -471,11 +479,14 @@ def clear_cache(self):
"""
with self.connection:
self._execute(models.Name.objects.drop_table())
self._execute(models.Alias.objects.drop_table())
self._execute(models.Package.objects.drop_table())
self._execute(models.Metadata.objects.drop_table())
models.Name.create_table(self.connection)
models.Alias.create_table(self.connection)
models.Package.create_table(self.connection)
models.Metadata.create_table(self.connection)
self.add_aliases(self.project.prefs.autoimport.aliases)
data = (
versioning.calculate_version_hash(self.project),
json.dumps(versioning.get_version_hash_data(self.project)),
Expand Down Expand Up @@ -595,6 +606,10 @@ def _convert_name(name: Name) -> tuple:
name.name_type.value,
)

def add_aliases(self, aliases: Iterable[Alias]):
if aliases:
self._executemany(models.Alias.objects.insert_into(), aliases)

def _add_names(self, names: Iterable[Name]):
if names is not None:
self._executemany(
Expand Down
3 changes: 2 additions & 1 deletion rope/contrib/autoimport/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Utility functions for the autoimport code."""

import pathlib
import sys
from collections import OrderedDict
Expand Down Expand Up @@ -53,7 +54,7 @@ def get_package_source(
if "site-packages" in package.parts:
return Source.SITE_PACKAGE
if sys.version_info < (3, 10, 0):
if str(package).startswith(sys.prefix):
if str(package).startswith(sys.base_prefix):
return Source.STANDARD
else:
if name in sys.stdlib_module_names:
Expand Down
1 change: 1 addition & 0 deletions rope/contrib/finderrors.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* ... ;-)
"""

from rope.base import ast, evaluate, pyobjects


Expand Down
1 change: 1 addition & 0 deletions rope/contrib/fixmodnames.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
argument.
"""

from rope.base import taskhandle
from rope.contrib import changestack
from rope.refactor import rename
Expand Down
Loading

0 comments on commit 60d0e02

Please sign in to comment.