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

Make pyp a library that can be used by other tools like VisiData #26

Open
frosencrantz opened this issue Feb 27, 2022 · 2 comments
Open

Comments

@frosencrantz
Copy link

I think pyp is a very cool tool. I don't actually use it, but I'm impressed by what you've created, and there is a way I would use this code more.

It would be useful if someone created a VisiData plugin that used pyp as the way to evaluate values. Visidata has commands that allow the user to enter Python expressions, which are evaluated to add/modify/select rows of values. If you want to use one of the modules that isn't already imported, you need to manually add the import either via a command or your visidatarc file. For example there is the addcol-expr command:

I think it would be useful if pyp could be used to evaluate these expressions, adding the magic that pyp provides.

I had made a Visidata request, but there is no interest yet from the developers, but I think the users would find it useful:

I don't really think that a Visidata plugin would necessarily make sense for you to create. But I think it would be much easier if pyp could be used as a module in other tools, and used with in a REPL or eval loop like Visisdata does.

@hauntsaninja
Copy link
Owner

Thanks!

The ultimate source of all magic in pyp comes from the code that is statically able to identify unused names. The code for this is actually already quite reusable (and well-tested, e.g. handling some edge cases better than popular linters at the time I first wrote this). You can use it like so:

>>> import pyp, ast
>>> pyp.NameFinder(ast.parse("statistics.mean(range(5))")).undefined
{'range', 'statistics'}

As you can see, this will include builtin names, so you usually want to remove set(dir(__import__("builtins"))), like we do here:

pyp/pyp.py

Line 522 in 8228a26

self.undefined -= set(dir(__import__("builtins")))
If VisiData already provides some names, e.g. by providing locals and globals wherever it calls eval / exec, you could subtract those off as well.

Anyway, I'm open to making changes (within reason) to pyp to enable library use cases. But it's still a little unclear to me exactly what APIs you're interested in. From your links, it seems like your interests are:

  • automatic imports
  • maybe some other pyp stuff

Automatic imports should be pretty easy to use get working with pyp.NameFinder, as above. A lot of people use pyp's configuration to alias imports or use import wildcards ( https://github.com/hauntsaninja/pyp#pyp-is-configurable ); if you're interested in a similar configuration scheme, you might need use of more of pyp's code.

What other pyp stuff are you interested in? A lot of other code in pyp assumes a CLI context where you have stdin and stdout (e.g. the magic variables just correspond to various ways of setting up stdin). I'm not familiar with VisiData, but I assume it's mostly just eval-ing expressions of variables that already exist. For example, use of the magic variable x automatically sets up a loop in pyp; is there any equivalent of that in what you're asking for?

If you just want eval except it has automatic imports, that's relatively easy for me to add. Something like def eval(code, globals, locals, pyp_config). But maybe you want more than that?

@frosencrantz
Copy link
Author

I do think the most useful thing is the automatic imports, so the eval() looks like a good choice.

Like you said the Pyp runs in the context of the CLI w/stdout&stdin. Visidata context is more the current row in many ways like the input line. Visidata adds some special magic variables for each of the columns. It feels like it might be useful to have some before and after computation, but I’m not clear how that would be setup. Visidata typically has one input line.

There are potentially other magic variables like other sheets in Visidata’s memory, or the frequency sheet, where each row represents multiple other lines.

Visidata already provides a .visidatarc file that can be used to add default imports. I was hoping the automatically imports would help eliminate/reduce the need for using that.

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

No branches or pull requests

2 participants