gist-import
GitHub Gist are handy snippets, which are meant to be copy-pasted into one's code... but what if you could import them?
Installation
pip install gist-import
Usage
The main class is GistImporter. This allows one to import cleanly a gist into a project.
Namely it retrieves the gist and executes it with any given additional named arguments
in a local context thus not polluting the global namespace (see background).
If required it does a special import of the gist's imports (<3.8) thanks to get_imports_in_codeblock.
The variables in that namespace are then available as items.
from gist_import import GistImporter
gi = GistImporter('24d9a319d05773ae219dd678a3aa11be')
Safeguard = gi['Safeguard']
Additionally, a module can be made:
from gist_import import GistImporter
from types import ModuleType
gi = GistImporter('24d9a319d05773ae219dd678a3aa11be')
safeguard: ModuleType = gi.to_module('safeguard')
# which can be used elsewhere...
from safeguard import Safeguard
In the case of a codeblock that fails because of, say a terminal line, a warning saying so will be printed.
from gist_import import GistImporter
gi = GistImporter('👾👾👾', foo=1, bar=2) # a gist with a syntax error on the last line will not run...
clean_code = gi.codeblock.split('\n')[:-1] # skip last line
gi = GistImporter.from_code_block(clean_code, foo=1, bar=2)
baz = gi['baz']
The function get_imports_in_codeblock is a helper function that finds any imports and return the modules as
values of a dictionary.
There are four entry points:
- Gist id (regular initialisation)
- codeblock as discussed via
from_code_block - text file url via
from_url - GitHub page url via
from_github
Background
GitHub Gist are snippets that aren't part of regular GitHub, they are intended to be used in blogs etc. to show code-hightlighting by embedding the gist. If one were to use in it Python, one should copy-paste it or do something convoluted.
Say the gist is nice and isolated, with all the correct imports, then this works fine.
import requests
response = requests.get('https://gist.github.com/matteoferla/d0daee35fe6f598bc720ce0eeebbac97/raw/6f7ba15dde86f1066629af61e0724dbe6a62cceb/transmute_FindMCS_parameters.py')
response.raise_for_status()
exec(response.text)
transmute_FindMCS_parameters()
..but things get messy quickly. As seen in the comment in this Gist:
https://gist.github.com/matteoferla/24d9a319d05773ae219dd678a3aa11be
As a placeholder for the response.text in the following examples a string is used.
The following works:
faux_gist:str = 'greet = lambda who: print(f"Hello {who}")' # pretend this is the gist from `response.text`
exec(faux_gist)
greet('World')
But as soon as one moves away from the global namespace issues happen. This would be needed were one to want to wrap the gist execution in a function to avoid global namespace pollution.
This will fail:
def nonglobal(faux_gist:str):
exec(faux_gist)
return greet # NameError: name 'greet' is not defined
# assign to a variable with a different name
salute = nonglobal('greet = lambda who: print(f"Hello {who}")')
salute('Mars')
But this will pollute the global namespace:
def nonglobal(faux_gist:str):
exec(faux_gist, globals())
return greet # NameError: name 'greet' is not defined
# assign to a variable with a different name
salute = nonglobal('greet = lambda who: print(f"Hello {who}")')
salute('Mars')
assert 'greet' not in globals() # AssertionError:
As globals() returns the actual global namespace, not a copy.
If a copy is passed the copy will have the new variable and the namespace will not be polluted.
def nonglobal(faux_gist:str):
faux_globals= {**globals(), **locals()}
exec(faux_gist, faux_globals)
return faux_globals['beware']
# assign to a variable with a different name
enguard = nonglobal('import warnings; beware = lambda who: warnings.warn(f"Beware {who}")')
enguard('Mars')
assert 'beware' not in globals()
This used to not work in Python 3.7 due to the import being lost.
Hence the function get_imports_in_codeblock which returns a dictionary of string to module
of the imports in the codeblock —star imports included.
Metadata
Release files for gist-import 1.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gist-import-1.0.4.tar.gz | 7.0 kB | Details |
Release files / gist-import-1.0.4.tar.gz
| Download URL | gist-import-1.0.4.tar.gz |
|---|---|
| Size | 7.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
605797ee214215e584442cbffa0033a7d8fb3b2c754b5655f140eb57f707e318
|
|
BLAKE2b-256 checksum How to use checksums |
a364025d7dcefc7c3459f554218cbdecc764f19e3f7464b281b0b76f65dd95fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.10.10
|