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

inspect.stack() role in code #21

Closed
epogrebnyak opened this issue Aug 8, 2019 · 6 comments
Closed

inspect.stack() role in code #21

epogrebnyak opened this issue Aug 8, 2019 · 6 comments
Labels

Comments

@epogrebnyak
Copy link
Contributor

What is the purpose of look-through in Handout class:

for info in inspect.stack():
      if info.filename == __file__:
        continue
      break

My first impression is that nothing happens in the loop.

@danijar
Copy link
Owner

danijar commented Aug 8, 2019

Feel free to add a comment to the code:

Find the file that created the Handout object, to include its source code in the output document. The loop walks through the call stack, skips entries that are in handout.py which are internal, and breaks at the first external Python file.

@epogrebnyak
Copy link
Contributor Author

@danijar - it is more clear from the comment, but is there a possiblity to move dealing with source file into own class?

Handout class is busy constructing the html - I think there can be a separate class that provides access to source file:

class Source:
    def __init__(self, info: inspect.FrameInfo):  
        self._info = info
        
    def filename(self) -> str:
       """Return path to a file where Handout object was created.""" 
       return self._info.filename
   
    def text(self) -> str:
        """Return contents of a file where Handout object was created."""
        module = inspect.getmodule(self._info.frame)
        return inspect.getsource(module)   
    
    def current_line(self) -> int:
        """Return current line in a file where Handout object was created."""
        for info in inspect.stack():
          if info.filename == self.filename():
            return info.lineno
        message = (
            "Handout object was created in '{}' and accessed in '{}'. The file in "
            "which you create the handout will be rendered. Thus, it only makes "
            "sense to add to the handout from this file or functions called from "
            "this file. You should not pass the handout object to a parent file.")
        raise RuntimeError(message.format(self.filename(), info.filename))
   
    

class Handout:
    def __init__(self, ...):
        # ... 
        # The loop walks through the call stack, skips 
        # internal entries in handout.py, and breaks at 
        # the first external Python file. We assume this 
        # is the file is where a Handout instance was created.
        for info in inspect.stack():
            if info.filename == __file__:
                continue
            break
        self.source = Source(info)
        
    #later:
        self.source.text()
        self.source.current_line()

As a benefit I see:

  • _get_current_line() moves away from Handout class
  • the constructor in Handout gets cleaner, for example there is no need to save self._source_name

@danijar
Copy link
Owner

danijar commented Aug 8, 2019

I'm not sure whether this restructuring is desirable. I think it would make more sense to move everything HTML related into a separate HTMLBackend and also contains the Block classes as separate functions. That would open the door to add a LaTeXBackend in the future. That being said, I'd say it's a bit early to do this refactoring since we don't know if it will be necessary.

@danijar danijar closed this as completed Aug 8, 2019
@epogrebnyak
Copy link
Contributor Author

epogrebnyak commented Aug 8, 2019

Handout minus HTMLBackend probably equals Source or similar, imo, but sure differentiating backends is a bigger task than style preferences for Handout alone.

@danijar
Copy link
Owner

danijar commented Aug 9, 2019

Exactly, that's what I was thinking. On a philosophical level, both could be separated out to separate different sources and targets. But for now I don't see why this would be necessary and I like to defer refactorings until they become necessary, because the "optimal solution" may change until then.

@epogrebnyak
Copy link
Contributor Author

Right, refactoring options may be wider than we think now when new concerns emerge. Lets try tackle making a pdf and latex outputs in #18 and #9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants