.. | ||
algebras | ||
assumptions | ||
calculus | ||
categories | ||
codegen | ||
combinatorics | ||
concrete | ||
core | ||
crypto | ||
diffgeom | ||
discrete | ||
external | ||
functions | ||
geometry | ||
holonomic | ||
integrals | ||
interactive | ||
liealgebras | ||
logic | ||
matrices | ||
multipledispatch | ||
ntheory | ||
parsing | ||
physics | ||
plotting | ||
polys | ||
printing | ||
series | ||
sets | ||
simplify | ||
solvers | ||
stats | ||
strategies | ||
tensor | ||
testing | ||
unify | ||
utilities | ||
vector | ||
__init__.pyi | ||
conftest.pyi | ||
py.typed | ||
README.md |
These stubs were generated by:
- Running
pyright --createstub sympy
after installing sympy into a venv - Running a script that uncommented all of the return values in the generated stubs
- Running a script that removed all doc strings from the stubs (as sympy has docstrings itself)
- Adding a
partial
py.typed file - Fixing all import errors one at a time (using Pylance)
The last part took the longest. It might be quicker to just add any changes by hand, rather than regenerating from scratch.
Scripts for future use:
Uncomment return values
import os
import re
import shutil
from typing import List
SOURCE_DIR = "typings\\sympy"
DEST_DIR = "typings\\sympy-returnvalues"
def read_file(file_path: str) -> List[str]:
with open(file_path, "r") as file:
return file.readlines()
def write_file(file_path: str, lines: List[str]) -> None:
try:
os.makedirs(os.path.dirname(file_path))
except FileExistsError:
pass
with open(file_path, "w") as file:
file.writelines(lines)
def fix_file(file_path: str, dest_path: str, sub_package: str) -> None:
lines = read_file(file_path)[4:]
# Turn the return type comments into actual return types
changed = [re.sub(r":\s+#(.*)", r"\1", line) for line in lines]
# Replace `from .` imports with `from sympy.<subpackage>.`
replace_str = f"from sympy.{sub_package + '.' if sub_package else ''}"
changed = [re.sub(r"from \.", replace_str, line) for line in changed]
any_changes = [line for line in changed if line not in lines]
if len(any_changes) > 0:
# Find this same file in the '.venv/lib/site-packages/sympy' directory and see if it has typing information in it.
site_packages_file = file_path.replace(SOURCE_DIR, ".venv\\lib\\site-packages\\sympy").replace(".pyi", ".py")
if os.path.exists(site_packages_file):
site_packages_lines = read_file(site_packages_file)
if "->" in site_packages_lines:
return
else:
print(f"Writing {dest_path}")
write_file(dest_path, changed)
def fix_all_stubs() -> None:
stubs_dir = SOURCE_DIR
dest_dir = DEST_DIR
shutil.rmtree(dest_dir, ignore_errors=True)
os.makedirs(dest_dir, exist_ok=True)
# First write a partial py.typed file to the destination directory
write_file(os.path.join(dest_dir, "py.typed"), ["partial"])
# Then iterate over all of the generated files and fix them up so they're valid
for root, dirs, files in os.walk(stubs_dir):
for file in files:
if file.endswith(".pyi"):
file_path = os.path.join(root, file)
dest_path = file_path.replace(stubs_dir, dest_dir)
sub_dir_pos = root.index(stubs_dir) + len(stubs_dir) + 1
sub_dir = root[sub_dir_pos:]
sub_package = sub_dir.replace("\\", ".")
fix_file(file_path, dest_path, sub_package)
fix_all_stubs()
Remove doc comments
from codecs import ignore_errors
import os
import shutil
from typing import List
SOURCE_DIR = "typings\\sympy-returnvalues"
DEST_DIR = "typings\\sympy-docs"
def fix_file(file_path:str, dest_path:str):
# Read the file one char at a time until we find one of r""", b""", or """
with open(file_path, mode="r") as file:
lines = file.readlines()
contents = "".join(lines)
new_contents = ""
in_docstring = False
ignoring_line = False
line_start = 0
i = 0
while i < len(contents):
char = contents[i]
if contents[i] == "\n":
line_start = len(new_contents)
if ignoring_line and not in_docstring:
ignoring_line = False
if contents[i:i+3] == "\"\"\"" or contents[i:i+3] == "\'\'\'":
in_docstring = not in_docstring
new_contents = new_contents[:line_start]
ignoring_line = True
i += 3
elif contents[i:i+4] == "r\"\"\"" or contents[i:i+4] == "r\'\'\'" and not in_docstring:
in_docstring = True
new_contents = new_contents[:line_start]
ignoring_line = True
i += 4
elif not in_docstring and not ignoring_line:
new_contents += char
i += 1
else:
i += 1
try:
os.makedirs(os.path.dirname(dest_path))
except FileExistsError:
pass
print(f"Writing {dest_path}")
with open(dest_path, mode="w") as file:
file.write(new_contents)
def fix_all_stubs() -> None:
stubs_dir = SOURCE_DIR
dest_dir = DEST_DIR
shutil.rmtree(dest_dir, ignore_errors=True)
os.makedirs(dest_dir, exist_ok=True)
# Then iterate over all of the generated files and fix them up so they're valid
for root, dirs, files in os.walk(stubs_dir):
for file in files:
if file.endswith(".pyi"):
file_path = os.path.join(root, file)
dest_path = file_path.replace(stubs_dir, dest_dir)
sub_dir_pos = root.index(stubs_dir) + len(stubs_dir) + 1
sub_dir = root[sub_dir_pos:]
sub_package = sub_dir.replace("\\", ".")
fix_file(file_path, dest_path)
fix_all_stubs()