Git Product home page Git Product logo

pinliner's Introduction

pinliner - Python Inliner

image

image

This tool allows you to merge all files that comprise a Python package into a single file and be able to use this single file as if it were a package.

Not only will it behave as if it were the original package, but it will also show code in exceptions and debug sessions, and will display the right line number and file when logging.

Imports will work as usual so if you have a package structure like:

.
└── [my_package]
     ├── file_a.py
     ├── [sub_package]
     │    ├── file_b.py
     │    └── __init__.py
     ├── __init__.py

And with pinliner installed you execute:

$ mkdir inlined
$ pinliner my_package -o inlined/my_package.py
$ cd inlined
$ python

You'll be able to use generated my_package.py file as if it were the real package:

>>> import my_package
>>> from my_package import file_a as a_file
>>> from my_package.sub_package import file_b

And __init__.py contents will be executed as expected when importing my_package package and you'll be able to access its contents like you would with your normal package.

Modules will also behave as usual.

If your package is checking __name__ for __main__ it will also work as usual. Although given the fact that we only have 1 file we will no longer be able to call other packages/modules directly from the command line to trigger code conditioned to __name__ having __main__ as its value.

Loader code will automatically compile packages and modules to byte code, before running it. When a module is imported for the first time, or when the specific's package/module source (not the whole inlined file) is more recent than the current compiled file, a .pyc file containing the compiled code will be created in the same directory as the pinlined .py file.

If the byte code is up to date then it will be used instead, thus avoiding a recompilation, exactly the same as python normally does, with the only exception that all .pyc files will be in the same directory and the filenames will include the full path to the original file.

Bundle

Pinliner is now capable of acting like a bundle where multiple packages can be inlined into a single file.

When including multiple files the default is not to automatically load any of the packages from the module when loading the bundle.

$ pinliner my_package another_package -o bundle.py
$ python
>>> import bundle

>>> import my_package
>>> from my_package import file_a as a_file
>>> from my_package.sub_package import file_b

>>> import another_package

We can default to automatically load a specific package from the bundle:

$ pinliner my_package another_package -d another_package -o another_package.py

This is convenient if we include multiple packages but we have a main program that we want to execute automatically and the others are just libraries required by this probram.

Inlined file name

For inlined package and bundles to work as expected one must pay attention to the inlined file name following these rules:

  • Output filename of an inlined single package must have the same name as the package itself: $ pinliner my_package -o inlined/my_package.py
  • Output filename of a bundle with no default package must not match ANY of the packages included in the bundle: $ pinliner my_package another_package -o bundle.py
  • Output filename of a bundle with a default package must match the default package name: $ pinliner my_package another_package -d another_package -o another_package.py
  • Output filename of a single package with an empty default must have a name that doesn't match the inlined package name: $ pinliner my_package -d '' -o inlined.py

Installation

You can install pinliner globally in your system or use a virtual environment, this is how it could be done using a virtual environment:

$ virtualenv .venv
$ source .venv/bin/activate
$ pip install pinliner

After that you can run the tool with pinliner.

pinliner's People

Contributors

akrog avatar maienm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pinliner's Issues

Error with parser

When I try and run:
pinliner ./my_package_name -o ../my_package_name.py

I get the error:
parser = MyParser(description=general_description, version=__version__, TypeError: __init__() got an unexpected keyword argument '

Any fix ideas?

Python 3 Support

There are a few features currently in use that are have breaking changes in python 3. I was able to patch my local copy with minimal effort.

Would you be interested in supporting python 3 if I opened a PR with these changes?

Multiple packages

Can this inline multiple packages? Say for instance, a folder of a few different packages.

Support being called from a string

Right now, pinliner assumes that the module is in it's own file and reads from it as needed. However, given that the file already has the different modules, it can just save the different parts of the strings to the appropriate parts of the dictionary directly instead of being grepped from the outside.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.