8000 python binding changes by pca006132 · Pull Request #214 · elalish/manifold · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

python binding changes #214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 25, 2022
Merged

python binding changes #214

merged 3 commits into from
Sep 25, 2022

Conversation

pca006132
Copy link
Collaborator

Copied docstring and added some overloads to make the binding the same as the C++ and JS version. E.g support passing an array for translate instead of just accepting 3 parameters.

< 8000 /batch-deferred-content>
@pca006132
Copy link
Collaborator Author
pca006132 commented Sep 24, 2022

The weird thing for pyright is that it cannot obtain the docstring from binary files, the only way to provide hints to users is to use stubs. However, automatic stub generator such as stubgen from mypy generates really terrible stub (especially for static methods) and doesn't include docstring in the generated stub. I'm still thinking how should we integrate stub with pybind11 output (how to keep them in-sync for example).

Here is a fixed stub modified from stubgen output:

# pymanifold.pyi
from typing import Any, Callable, List, Tuple

from typing import overload
import numpy

class Manifold:
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(self, arg0: List[Manifold]) -> None: ...
    @staticmethod
    @overload
    def cube(size: Tuple[float, float, float], center: boolean = False) -> Manifold: ...
    @staticmethod
    @overload
    def cube(x: float, y: float, z: float, center: boolean = False) -> Manifold: ...
    @staticmethod
    def cylinder(height: float, radiusLow: float, radiusHigh: float=-1.0, circular_segments: int = 0) -> Manifold: ...
    @staticmethod
    def from_mesh(mesh: Any) -> Manifold: ...
    def refine(self, n: int) -> Manifold: ...
    @overload
    def rotate(self, v: numpy.ndarray[numpy.float32]) -> Manifold: ...
    @overload
    def rotate(self, x_degrees: float = ..., y_degrees: float = ..., z_degrees: float = ...) -> Manifold: ...
    @overload
    def scale(self, scale: float) -> Manifold: ...
    @overload
    def scale(self, v: numpy.ndarray[numpy.float32]) -> Manifold: ...
    @overload
    def scale(self, v: List[float]) -> Manifold: ...
    def smooth(self, *args, **kwargs) -> Any: ...
    def sphere(self, *args, **kwargs) -> Any: ...
    def tetrahedron(self, *args, **kwargs) -> Any: ...
    def to_mesh(self, *args, **kwargs) -> Any: ...
    def transform(self, m: numpy.ndarray[numpy.float32]) -> Manifold: ...
    @overload
    def translate(self, x: float = ..., y: float = ..., z: float = ...) -> Manifold: ...
    @overload
    def translate(self, t: numpy.ndarray[numpy.float32]) -> Manifold: ...
    def warp(self, f: Callable[[Tuple[float,float,float]],Tuple[float,float,float]]) -> Manifold: ...
    def __add__(self, arg0: Manifold) -> Manifold: ...
    def __sub__(self, arg0: Manifold) -> Manifold: ...
    def __xor__(self, arg0: Manifold) -> Manifold: ...

class Mesh:
    def __init__(self, vert_pos: numpy.ndarray[numpy.float32], tri_verts: numpy.ndarray[numpy.int32], vert_normal: numpy.ndarray[numpy.float32], halfedge_tangent: numpy.ndarray[numpy.float32]) -> None: ...
    @property
    def halfedge_tangent(self) -> numpy.ndarray[numpy.float32]: ...
    @property
    def tri_verts(self) -> numpy.ndarray[numpy.int32]: ...
    @property
    def vert_normal(self) -> numpy.ndarray[numpy.float32]: ...
    @property
    def vert_pos(self) -> numpy.ndarray[numpy.float32]: ...

class Polygons:
    def __init__(self, polygons: List[List[Tuple[float,float]]]) -> None: ...
    def extrude(self, height: float, n_divisions: int = ..., twist_degrees: float = ..., scale_top: Tuple[float,float] = ...) -> Manifold: ...
    def revolve(self, circular_segments: int = ...) -> Manifold: ...

The staticmethod issue seems to be a known issue: python/mypy#13574

@codecov-commenter
Copy link
codecov-commenter commented Sep 24, 2022

Codecov Report

Base: 92.31% // Head: 92.31% // No change to project coverage 👍

Coverage data is based on head (56420ad) compared to base (975a6e6).
Patch has no changes to coverable lines.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #214   +/-   ##
=======================================
  Coverage   92.31%   92.31%           
=======================================
  Files          32       32           
  Lines        3395     3395           
=======================================
  Hits         3134     3134           
  Misses        261      261           

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Owner
@elalish elalish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@@ -36,7 +36,7 @@ python binding documentation:

```
>>> import pymanifold
>>> help(manifold)
>>> help(pymanifold)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reminds me; our library is just called manifold, the JS is manifold.js. What do you say we just call the python bindings manifold as well?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name manifold was taken by another package in pypi, so we need another name.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bah! Hasn't even been updated since 2009; wish there was a way to take over abandoned names. Oh well.

@elalish
Copy link
Owner
elalish commented Sep 25, 2022

I'm not familiar with stubs in python, but it looks fairly equivalent to .d.ts in JS. It sounds like the automatic stub generators often need some cleanup anyway. Considering we're manually maintaining our .d.ts, I suppose we can also manually maintain a stub file. A little annoying, but at least our API isn't huge.

@pca006132
Copy link
Collaborator Author

The problem with Python is that we will need documentation in both the stub file and C++ binding file, so users can read the documentation from both the editor and in python prompt. I think we can probably write something that extracts the doc string in python and put it into the stub file, so it will be automatically synchronized. Anyway, I think we can leave it later.

@pca006132
Copy link
Collaborator Author

I guess we can merge this and open an issue to track python stub?

@elalish elalish merged commit ae2ba3e into elalish:master Sep 25, 2022
@pca006132 pca006132 deleted the py-binding branch August 15, 2023 12:54
cartesian-theatrics pushed a commit to cartesian-theatrics/manifold that referenced this pull request Mar 11, 2024
* python documentation

* fixed error in readme

Co-authored-by: Emmett Lalish <elalish@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0