Skip to content
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

feat: parse functions into objects #12

Closed
wants to merge 15 commits into from
Closed

feat: parse functions into objects #12

wants to merge 15 commits into from

Conversation

jakebrinkmann
Copy link

Mostly looking for feedback/thoughts as I don't think this is quite ready for use as-is.

Here is some example Python-3.8 code:

from dataclasses import dataclass
from enum import Enum
from typing import List, Union


class Foo(Enum):
    SPAM: str = "SPAM"
    HAM: str = "HAM"


@dataclass
class Bar(Enum):
    EGGS: List[str]


def greeting(name: Union[Foo, None]) -> Bar:
    if name is None:
        return Bar([])
    else:
        return Bar([name])

which results in the following diagram:

image

My idea is to represent functions in such a way that the inputs/outputs are clear what class/datatype are being used in the functions. Again, not quite there yet, but motivated to explore this idea if anyone else is 😄

Perhaps the idea diverges too far from py2puml goals, but curious if this community had thoughts.

Thanks for reading!

@lucsorel
Copy link
Owner

lucsorel commented Jul 2, 2021

hi @jakebrinkmann 😃

Thank you for your interest and contribution to the library. My original need was to document domain datastructures (dataclasses and namedtuples, mainly), but documenting domain logic seems also interesting (since it is your needs, someone else is likely to need it too).

I think the issue is to find a way to represent a function entity in UML, which I think do not include functions in its modelling approach. In your example we would have liked to find the greeting function in the same py2puml_example.example package, along with Foo and Bar.

Maybe we could use the plantuml Entity or Interface to document functions? What do you think?

@lucsorel
Copy link
Owner

lucsorel commented Jul 2, 2021

What about producing this kind of plantuml code for functions: http://www.plantuml.com/plantuml/uml/LOz1Iu1048NlyoiUT2bGy2Q8Y0Mj7Ie2woGU5XjbGMTZTpr4-DyRFGHT7lCUZ-ynRKmsf7rRYMNVOBp73m7zs_rBTQcQf_DMeGD4qsfZn8CDL--nw_eApowc8QOmqa54JXA7sKwC9J0d9mlg6hSckp6cB8lY3lCkKt9Uq3GNvKFK3BgTuTKBltz_yLXXzfw0FCzLTUzaQqM3Fovf_C-tB9_wooy0

I used the interface type, customized with an F letter (see the Specific Spot section of https://plantuml.com/en/class-diagram):

@startuml
enum Foo {
  SPAM: SPAM
  HAM: HAM
} 

class Bar {
  EGGS: List[str]
}


interface greeting << (F,#FF7700) function >> {
  Union[Foo, NoneType]: foo
  ---
  Bar
}

Foo -- greeting
Bar -- greeting
@enduml

@jakebrinkmann
Copy link
Author

jakebrinkmann commented Jul 2, 2021

Oh Wow!! Your version is amazing! I love it!

@lucsorel
Copy link
Owner

lucsorel commented Jul 4, 2021

slight changes:

  • for better items alignment
  • and composition arrows
  • Return instead of Returns

http://www.plantuml.com/plantuml/uml/POz1ImCn48NlyoiUUD7IBhqLbbAgOAgW8XPFfOUmJaiWcPHa0eBqlvkkKXRsChp3nxplhRFQf2LuOYa1_6t3oNDZOiGF0Tlt-zUslmGyNN8zT0PHvstEL_x1ffv_t6osBLvSrbtMjASp4JbHJWVRyPK-9cPrSiHoYLiplJ5ciPZFxt0eqgcBWjMg_zOqU9PJqLmJ0M83j_YKIkogu1HlKNZ_ntsmbYJ_OBMvD0_7p2QZTXhfJ6R3GRHc-Ih1_m80

What do you think?
Would you be able to produce the code that generates that?
And what PlantUML code would you yield for functions that:

  • have no inputs?
  • return nothing?

@lucsorel
Copy link
Owner

lucsorel commented Sep 3, 2021

hi @jakebrinkmann, how are you?

I am wondering what the state of this PR is? Do you need any help?

I refactored the code base in a pull request that was merged. I can help you resolving the conflicts with this PR, if you want.

@doyou89
Copy link
Contributor

doyou89 commented Sep 6, 2021

hi @jakebrinkmann ,
It's very interesting contribution.

I have some suggestion about UML representation.
According to the definition of the UML relations, I would like to determine the type of relation depending on where the function is called.
(This is a different example from above.)

  1. Passed in init as a parameter
class Foo:
    def __init__(self, bar: Bar):
        self.bar = bar

The type of relation may be aggregation. (bar may be instantiated at another class)

@startuml
Foo o-- Bar
@enduml
  1. Instantiated in init
class Foo:
    def __init__(self):
        self.bar = Bar()

The type of relation may be composition or aggregation. (When the object of Foo is deleted, self.bar deleted also)

@startuml
Foo *-- Bar
@enduml
  1. Instantiated in a method
class Foo:
    def func1(self):
        self.func2(Bar())    # instantiated in `func1`

    def func2(self, bar: Bar):    # passed in `func2` as a parameter
        bar.run()

The type of relation is association. (It's temporary relations)

@startuml
Foo ..> Bar
@enduml

@lucsorel
Copy link
Owner

lucsorel commented Sep 6, 2021

hi @doyou89

As far as I understand, @jakebrinkmann' s feature request is related to module functions (functions that take inputs and return outputs, detached from any class or instance), not to class or instance methods. The feature would include those functions alongside other data structures already handled by py2puml (classes, dataclasses, namedtuples, enums).

However, your suggestions could be the basis to improvements of py2puml about the ways associations are drawn between datastructures. I am not a big fan of instantiating components inside the constructor (use case 2.) because it makes unit testing harder.

@lucsorel
Copy link
Owner

lucsorel commented Oct 4, 2021

hi @jakebrinkmann

What is the status of this PR? Do you need some help to finalize it?

@lucsorel
Copy link
Owner

hi @jakebrinkmann

I am wondering if you want some help to rebase and merge this PR?

@jonykalavera
Copy link
Contributor

I am interested in getting this done too. maybe we need to align these ideas with #11 too?

@jonykalavera jonykalavera mentioned this pull request Apr 21, 2022
@lucsorel lucsorel added the enhancement New feature or request label Nov 24, 2022
@lucsorel lucsorel added the waiting for feedback questions waiting to be answered label Feb 12, 2023
@jakebrinkmann jakebrinkmann closed this by deleting the head repository Mar 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request waiting for feedback questions waiting to be answered
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants