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

Management commands error after protect in Django #107

Open
sfcl opened this issue May 22, 2024 · 5 comments
Open

Management commands error after protect in Django #107

sfcl opened this issue May 22, 2024 · 5 comments
Labels

Comments

@sfcl
Copy link

sfcl commented May 22, 2024

Django doesn't see commands executed from the command line using the manage.py script
protected by the pyconcrete package.

There is an operating system: Ubuntu 22.04.4 LTS x86_64
Interpreter: Python 3.10.12
Packages installed: Django==5.0.6, pyconcrete==0.15.1
Installed compiler: apt-get install gcc python3-dev

To reproduce the error, we used a simple Django project https://github.com/deparkes/simple-django-app.
Next, a simple management command is created in the file counter/management/commands/inventory.py

Its contents are very simple:

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Command example: ./manage.py inventory'

    def handle(self, *args, **options):
        print('Hello, World!')

Executable files were protected with the command:

pyconcrete-admin.py compile --source=counter --pye  --remove-py  --remove-pyc 

After protecting the files, the manage.py script stopped seeing the inventory command.
Command line output:

Unknown command: 'inventory'
Type 'manage.py help' for usage.

Please advise how to solve the problem?

@Falldog
Copy link
Owner

Falldog commented May 23, 2024

FYI, here is a workable example for django, https://github.com/Falldog/pyconcrete/tree/master/example/django

For your case, I think that you need to make sure 2 things as below

  1. The entry point manage.py need to add import pyconcrete
  2. For your django commands, need to make sure it is workable even if pyconcrete is non installed. For example, counter/management/commands/ folder need to include __init__.py.

@sfcl
Copy link
Author

sfcl commented May 23, 2024

Screenshot before running the program pyconcrete-admin.py compile

1

As you can see, the inventory command is present.

Here is the result of the program python manage.py inventory

2

After execution pyconcrete-admin.py compile management the command has disappeared.

3

I added import pyconcrete to the manage.py file.

Here are its contents:

(venv) root@3000745-cs84966:~/venv/simple-django-app/cool_counters# cat manage.py 
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys

import pyconcrete


def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cool_counters.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

counter application directory structure

(venv) root@3000745-cs84966:~/venv/simple-django-app/cool_counters# tree counter
counter
├── admin.pye
├── apps.pye
├── __init__.pye
├── management
│   ├── commands
│   │   ├── __init__.pye
│   │   ├── inventory.pye
│   │   └── __pycache__
│   │       ├── __init__.cpython-310.pyc
│   │       └── inventory.cpython-310.pyc
│   ├── __init__.pye
│   └── __pycache__
│       └── __init__.cpython-310.pyc
├── migrations
│   ├── 0001_initial.pye
│   ├── __init__.pye
│   └── __pycache__
│       ├── 0001_initial.cpython-310.pyc
│       └── __init__.cpython-310.pyc
├── models.pye
├── __pycache__
│   ├── admin.cpython-310.pyc
│   ├── apps.cpython-310.pyc
│   ├── __init__.cpython-310.pyc
│   ├── models.cpython-310.pyc
│   ├── urls.cpython-310.pyc
│   └── views.cpython-310.pyc
├── templates
│   └── counter
│       └── index.html
├── tests.pye
├── urls.pye
└── views.pye

9 directories, 24 files


The web application also continues to run after the command is executed python manage.py runserver 0.0.0.0:9000.

4

But the error persists. Please help me resolve the error.

@Falldog
Copy link
Owner

Falldog commented May 23, 2024

It's a litter strange. Can you help to remove all of __pycache__ and then try it again?

@sfcl
Copy link
Author

sfcl commented May 23, 2024

I cleared the python file cache with the command

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

Result of the command python -B manage.py inventory

(venv) root@3001431-cs84966:~/venv/simple-django-app/cool_counters# python -B manage.py inventory
Unknown command: 'inventory'
Type 'manage.py help' for usage.

counter application directory structure

(venv) root@3001431-cs84966:~/venv/simple-django-app/cool_counters# tree counter/
counter/
├── admin.pye
├── apps.pye
├── __init__.pye
├── management
│   ├── commands
│   │   ├── __init__.pye
│   │   └── inventory.pye
│   └── __init__.pye
├── migrations
│   ├── 0001_initial.pye
│   └── __init__.pye
├── models.pye
├── templates
│   └── counter
│       └── index.html
├── tests.pye
├── urls.pye
└── views.pye

5 directories, 13 files

The error persists. Please help me resolve the error. I suggest that the author of the library reproduce the error on his computer to make sure that my words are correct.

My error is duplicate this issue

@Falldog
Copy link
Owner

Falldog commented May 24, 2024

I can reproduce this issue now.
The root cause would be Django try to find command by pkgutil as below logic
file: django/core/management/__init__.py

def find_commands(management_dir):
    """
    Given a path to a management directory, return a list of all the command
    names that are available.
    """
    command_dir = os.path.join(management_dir, "commands")
    return [
        name
        for _, name, is_pkg in pkgutil.iter_modules([command_dir])
        if not is_pkg and not name.startswith("_")
    ]

Current pyconcrete Metapath solution doesn't compatible with it. Need to implement path_hooks handler. I think it will need some time to add the feature.

@Falldog Falldog added the bug label May 24, 2024
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