Disclaimer: the following method isn't very clean (but that's what you're asking for).
Now, the good news is that this method will never break your Python. In fact, it will only affect the IDE.
However, note that PyCharm may become smarter in the future, and get autocomplete to work anyway. I don't think this would be a priority for the Jetbrains team, though!
Here we go.
All you have to do is confuse PyCharm a bit. PyCharm won't be able to reliably follow imports performed using __import__
, so we'll use that to import your django modules (if PyCharm doesn't which module you're importing, it can't know which class you are using and which methods to present in the autocomplete window!).
In the following example, we'll assume that:
_base.py
is the django file that contains the class you want to extend (and whose methods you want to hide)base.py
is the file that contains the class you want to provide your students with (whose methods you want to show)test.py
is the file that your students will write
_base.py
Nothing in particular here
class DjangoBaseClass(object):
def method_that_is_hidden(self):
print "The hidden method is there!"
base.py
Note the import
base = __import__("_base") # This is equivalent to `import base`. Python understands it, but PyCharm doesn't.
class YourBaseClass(base.DjangoBaseClass): # PyCharm doesn't know what class this is! No autocomplete.
def method_that_shows(self):
print "The method that shows is there!"
Important note: in the case of a multi-level import, the syntax is a bit different. For example, to inherit from django.views.generic.base.View
, do:
base = __import('django.views.generic.base', fromlist=['View',])
class MyView(base.View):
# Your stuff
Note that if PyCharm gets smarter in the future, you'll have to add some more indirection (e.g. instead of __import__('base')
, you could use __import__(''.join(['b', 'a', 's', 'e']))
. This will get messy, though.
test.py
Nothing in particular here
from base import YourBaseClass
class StudentClass(YourBaseClass):
pass
if __name__ == "__main__":
c = StudentClass()
c.method_that_is_hidden()
c.method_that_shows()
When you run the test.py
script, the methods both work:
$ python test.py
The hidden method is there!
The method that shows is there!
But when you use PyCharm, method_that_is_hidden
does not show up in autocomplete:
Note: I believe PyCharm now has features to follow call trees when you run tests, so if your students run tests using PyCharm, PyCharm may pick up the existence of those methods. I suppose they won't show in class definitions, but they may show if your students write c.
. You should try it and see for yourself.