Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ ignore = [
"PYI014",
"PYI053",

# TODO: Handle in its own PR
"PYI021", # https://github.com/microsoft/python-type-stubs/pull/343

# TODO: Investigate and fix or configure
"PYI001",
"PYI002",
Expand All @@ -57,6 +54,10 @@ ignore = [
"PYI052",
]

[tool.ruff.lint.per-file-ignores]
# We keep docstrings in sklearn
"stubs/sklearn/**" = ["PYI021"]

[tool.ruff.lint.isort]
combine-as-imports = true
extra-standard-library = [
Expand All @@ -67,7 +68,6 @@ extra-standard-library = [

[tool.pyright]
exclude = ["build", ".git"]
stubPath = "./stubs"
# Target oldest supported Python version
pythonversion = "3.9"
typeCheckingMode = "standard"
Expand Down
64 changes: 32 additions & 32 deletions stubs/matplotlib/ft2font.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,37 @@ FIXED_SIZES: int
FIXED_WIDTH: int

class FT2Font(_mod_builtins.object):
"Create a new FT2Font object.\n\nAttributes\n----------\nnum_faces\n Number of faces in file.\nface_flags, style_flags : int\n Face and style flags; see the ft2font constants.\nnum_glyphs\n Number of glyphs in the face.\nfamily_name, style_name\n Face family and style name.\nnum_fixed_sizes\n Number of bitmap in the face.\nscalable\n Whether face is scalable; attributes after this one are only\n defined for scalable faces.\nbbox\n Face global bounding box (xmin, ymin, xmax, ymax).\nunits_per_EM\n Number of font units covered by the EM.\nascender, descender\n Ascender and descender in 26.6 units.\nheight\n Height in 26.6 units; used to compute a default line spacing\n (baseline-to-baseline distance).\nmax_advance_width, max_advance_height\n Maximum horizontal and vertical cursor advance for all glyphs.\nunderline_position, underline_thickness\n Vertical position and thickness of the underline bar.\npostscript_name\n PostScript name of the font.\n"

def __init__(self, *args, **kwargs) -> None:
"Create a new FT2Font object.\n\nAttributes\n----------\nnum_faces\n Number of faces in file.\nface_flags, style_flags : int\n Face and style flags; see the ft2font constants.\nnum_glyphs\n Number of glyphs in the face.\nfamily_name, style_name\n Face family and style name.\nnum_fixed_sizes\n Number of bitmap in the face.\nscalable\n Whether face is scalable; attributes after this one are only\n defined for scalable faces.\nbbox\n Face global bounding box (xmin, ymin, xmax, ymax).\nunits_per_EM\n Number of font units covered by the EM.\nascender, descender\n Ascender and descender in 26.6 units.\nheight\n Height in 26.6 units; used to compute a default line spacing\n (baseline-to-baseline distance).\nmax_advance_width, max_advance_height\n Maximum horizontal and vertical cursor advance for all glyphs.\nunderline_position, underline_thickness\n Vertical position and thickness of the underline bar.\npostscript_name\n PostScript name of the font.\n"

...

@classmethod
def __init_subclass__(cls) -> None:
"This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.\n"

...

@classmethod
def __subclasshook__(cls, subclass: typing.Any) -> bool:
"Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).\n"

...

@property
def ascender(self) -> typing.Any: ...
@property
def bbox(self) -> typing.Any: ...
def clear(self) -> typing.Any:
"Clear all the glyphs, reset for a new call to `.set_text`.\n"

...

@property
def descender(self) -> typing.Any: ...
def draw_glyph_to_bitmap(self, bitmap, x, y, glyph) -> typing.Any:
"Draw a single glyph to the bitmap at pixel locations x, y\nNote it is your responsibility to set up the bitmap manually\nwith ``set_bitmap_size(w, h)`` before this call is made.\n\nIf you want automatic layout, use `.set_text` in combinations with\n`.draw_glyphs_to_bitmap`. This function is instead intended for people\nwho want to render individual glyphs (e.g., returned by `.load_char`)\nat precise locations.\n"

...

def draw_glyphs_to_bitmap(self) -> typing.Any:
"Draw the glyphs that were loaded by `.set_text` to the bitmap.\nThe bitmap size will be automatically set to include the glyphs.\n"

...

@property
Expand All @@ -51,73 +51,73 @@ class FT2Font(_mod_builtins.object):
@property
def fname(self) -> typing.Any: ...
def get_bitmap_offset(self) -> typing.Any:
"Get the (x, y) offset in 26.6 subpixels for the bitmap if ink hangs left or below (0, 0).\nSince Matplotlib only supports left-to-right text, y is always 0.\n"

...

def get_char_index(self, codepoint) -> typing.Any:
"Return the glyph index corresponding to a character *codepoint*.\n"

...

def get_charmap(self) -> typing.Any:
"Return a dict that maps the character codes of the selected charmap\n(Unicode by default) to their corresponding glyph indices.\n"

...

def get_descent(self) -> typing.Any:
"Get the descent in 26.6 subpixels of the current string set by `.set_text`.\nThe rotation of the string is accounted for. To get the descent\nin pixels, divide this value by 64.\n"

...

def get_glyph_name(self, index) -> typing.Any:
"Retrieve the ASCII name of a given glyph *index* in a face.\n\nDue to Matplotlib's internal design, for fonts that do not contain glyph\nnames (per FT_FACE_FLAG_GLYPH_NAMES), this returns a made-up name which\ndoes *not* roundtrip through `.get_name_index`.\n"

...

def get_image(self) -> typing.Any:
"Return the underlying image buffer for this font object.\n"

...

def get_kerning(self, left, right, mode) -> typing.Any:
"Get the kerning between *left* and *right* glyph indices.\n*mode* is a kerning mode constant:\n KERNING_DEFAULT - Return scaled and grid-fitted kerning distances\n KERNING_UNFITTED - Return scaled but un-grid-fitted kerning distances\n KERNING_UNSCALED - Return the kerning vector in original font units\n"

...

def get_name_index(self, name) -> typing.Any:
"Return the glyph index of a given glyph *name*.\nThe glyph index 0 means 'undefined character code'.\n"

...

def get_num_glyphs(self) -> typing.Any:
"Return the number of loaded glyphs.\n"

...

def get_path(self) -> typing.Any:
"Get the path data from the currently loaded glyph as a tuple of vertices, codes.\n"

...

def get_ps_font_info(self) -> typing.Any:
"Return the information in the PS Font Info structure.\n"

...

def get_sfnt(self) -> typing.Any:
"Load the entire SFNT names table, as a dict whose keys are\n(platform-ID, ISO-encoding-scheme, language-code, and description)\ntuples.\n"

...

def get_sfnt_table(self, name) -> typing.Any:
"Return one of the following SFNT tables: head, maxp, OS/2, hhea, vhea, post, or pclt.\n"

...

def get_width_height(self) -> typing.Any:
"Get the width and height in 26.6 subpixels of the current string set by `.set_text`.\nThe rotation of the string is accounted for. To get width and height\nin pixels, divide these values by 64.\n"

...

def get_xys(self) -> typing.Any:
"Get the xy locations of the current glyphs.\n"

...

@property
def height(self) -> typing.Any: ...
def load_char(self, charcode, flags) -> typing.Any:
"Load character with *charcode* in current fontfile and set glyph.\n*flags* can be a bitwise-or of the LOAD_XXX constants;\nthe default value is LOAD_FORCE_AUTOHINT.\nReturn value is a Glyph object, with attributes\n width # glyph width\n height # glyph height\n bbox # the glyph bbox (xmin, ymin, xmax, ymax)\n horiBearingX # left side bearing in horizontal layouts\n horiBearingY # top side bearing in horizontal layouts\n horiAdvance # advance width for horizontal layout\n vertBearingX # left side bearing in vertical layouts\n vertBearingY # top side bearing in vertical layouts\n vertAdvance # advance height for vertical layout\n"

...

def load_glyph(self, glyphindex, flags) -> typing.Any:
"Load character with *glyphindex* in current fontfile and set glyph.\n*flags* can be a bitwise-or of the LOAD_XXX constants;\nthe default value is LOAD_FORCE_AUTOHINT.\nReturn value is a Glyph object, with attributes\n width # glyph width\n height # glyph height\n bbox # the glyph bbox (xmin, ymin, xmax, ymax)\n horiBearingX # left side bearing in horizontal layouts\n horiBearingY # top side bearing in horizontal layouts\n horiAdvance # advance width for horizontal layout\n vertBearingX # left side bearing in vertical layouts\n vertBearingY # top side bearing in vertical layouts\n vertAdvance # advance height for vertical layout\n"

...

@property
Expand All @@ -137,19 +137,19 @@ class FT2Font(_mod_builtins.object):
@property
def scalable(self) -> typing.Any: ...
def select_charmap(self, i) -> typing.Any:
"Select a charmap by its FT_Encoding number.\n"

...

def set_charmap(self, i) -> typing.Any:
"Make the i-th charmap current.\n"

...

def set_size(self, ptsize, dpi) -> typing.Any:
"Set the point size and dpi of the text.\n"

...

def set_text(self, string, angle, flags) -> typing.Any:
"Set the text *string* and *angle*.\n*flags* can be a bitwise-or of the LOAD_XXX constants;\nthe default value is LOAD_FORCE_AUTOHINT.\nYou must call this before `.draw_glyphs_to_bitmap`.\nA sequence of x,y positions is returned.\n"

...

@property
Expand All @@ -168,20 +168,20 @@ class FT2Image(_mod_builtins.object):
def __init__(self, *args, **kwargs) -> None: ...
@classmethod
def __init_subclass__(cls) -> None:
"This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.\n"

...

@classmethod
def __subclasshook__(cls, subclass: typing.Any) -> bool:
"Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented. If it returns\nNotImplemented, the normal algorithm is used. Otherwise, it\noverrides the normal algorithm (and the outcome is cached).\n"

...

def draw_rect(self, x0, y0, x1, y1) -> typing.Any:
"Draw an empty rectangle to the image.\n"

...

def draw_rect_filled(self, x0, y0, x1, y1) -> typing.Any:
"Draw a filled rectangle to the image.\n"

...

def __getattr__(self, name) -> typing.Any: ...
Expand Down
81 changes: 2 additions & 79 deletions stubs/sympy-stubs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ 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)
- Running Ruff (`tests/run_hygiene.py`) to cleanup stubs and remove 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)
- Fixing all import errors one at a time (using Pylance and `tests/run_tests.py`)

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
Expand Down Expand Up @@ -78,79 +77,3 @@ def fix_all_stubs() -> None:
fix_all_stubs()

```

### Remove doc comments
```python

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()
```

2 changes: 1 addition & 1 deletion stubs/sympy-stubs/matrices/sparse.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class SparseRepMatrix(RepMatrix):
def nnz(self) -> int: ...
def row_list(self) -> list[tuple[Any, ...]]: ...
def scalar_multiply(self, scalar):
"Scalar element-wise multiplication"

...

def solve_least_squares(self, rhs, method=...): ...
Expand Down