How to create a console script using if __name__ == ' __main__' condition?

Question:

I am creating a setup file for python script installation. Commonly, the documentation use for example the next setup file:

from setuptools import setup

# setup.py file
setup(name='test',
      version='0.0.0',
      packages=['test'],
      entry_points={
      'console_scripts': [
              'test = test.test:main'
           ]
         },
      )

to call this:

# test/test.py file
def main():
    print('Hello!')

if __name__ == '__main__':
    main()

But, my problem is that I have my “main” code function below the if __ name__ == ‘__ main __’ condition. I Can not create a main() function because this represents a big change an effort of development

Are there any solution? or I have to spend time creating a main() (or any name) function?

Asked By: Emmanuel Arias

||

Answers:

As I understand it, you’ve got a bunch of code that you want to call only when the file isn’t being imported (that’s what that if statement does). However, it’d be very annoying, I’m sure, to add a tab before each line.

Solution: use something like this (works if you have linux; sure there are alternate solutions), which is sed -i 's/^/tt/' <filename> on a separate file with your main code copy-pasted in to add tabs. Copy paste this tabbed code into your def main(): and voila.

However, it looks like this is just meant to be imported, and that’s why you’re using the setup.py file…in which case you don’t need to do this, because presumably you want this code to run, and that’s why you’re importing it. (Unless it’s some testing stuff.)

Answered By: auden

You can use the following run_module helper to run a module as a function to fit setuptools’ entry_points syntax.

# run_module/__init__.py

import runpy
from dataclasses import dataclass


def __getattr__(name: str):
    return _RunModule(name)


@dataclass
class _RunModule:
    module: str

    def __getattr__(self, name: str) -> "_RunModule":
        return _RunModule(f"{self.module}.{name}")

    def __call__(self) -> None:
        runpy.run_module(self.module, run_name="__main__")

Given a module my_package.my_module that can be run with python -m my_package.my_module, with the run_module helper, you can use run_module:my_package.my_module as the setuptools entry point.

Answered By: Yang Bo
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.