2

In the __init__.py:

def tp(msg,o=None):
  import datetime
  omsg = ": %s" %repr(o) if o is not None else ""
  dtf = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  print(f"[{dtf}] {msg}{omsg}")

In a .py file in the same directory (/package ?) :

enter image description here

Traceback (most recent call last):
  File "/git/bluej/python/pointr/bluej/fusion/json_generators.py", line 243, in <module>
    tp('Running human-in-loop tests ..')
NameError: name 'tp' is not defined

What is the point of having __init__.py if the contents are not even visible to the files in the same package?

RE: the linked question and answers. It/they do not actually address my question here.

Update I learnt how to run the script as a module within pycharm and that mostly took care of the issue. The tp() runs now: but it is still required to do

  from . import tp

enter image description here

WestCoastProjects
  • 58,982
  • 91
  • 316
  • 560
  • 2
    `__init__.py` is supposed to be a package's initialization code. It's not intended to be pseudo-globals. – user2357112 Mar 24 '20 at 03:29
  • Python won't implicitly follow the package hierarchy upward, looking for a `tp`. This is similar to how instance attributes need to be accessed explicitly as attributes, even inside an object's own methods. If you want to access something in a different namespace (and it is a different namespace), you can do that explicitly. – user2357112 Mar 24 '20 at 03:35
  • What does "initialization code" mean if it does not include defining shared methods. – WestCoastProjects Mar 24 '20 at 03:53
  • I looked at that linked question and it does not address my question here. . – WestCoastProjects Mar 24 '20 at 03:57
  • 1
    There isn't really a better way to answer "why doesn't it work that way?". It can only work one way - in this case, the way described in the link. – Karl Knechtel Mar 24 '20 at 04:50
  • except that it is an _incorrect_ answer. The function _does_ show up - when the package is marked as a _module_ . That was the key – WestCoastProjects Mar 24 '20 at 05:58
  • That makes no sense. What made the function available was the explicit `from . import tp`. – user2357112 Mar 24 '20 at 07:00
  • There is no such thing as marking a package as a module. – user2357112 Mar 24 '20 at 07:00
  • It seems neither of you understood the requirements within `Pycharm` as indicated in the dialog above. It was surprising to me as well. – WestCoastProjects Mar 24 '20 at 07:16
  • Do you think the "Module name:" box is marking a package as a module? It's not. It's specifying a module you want to run. A package is a kind of module; there is no marking involved. – user2357112 Mar 24 '20 at 08:11
  • On closer inspection, I suppose you were running the code by file path before. Running a package submodule by file path does nasty things to the import system, breaking the package and preventing things like `from . import tp` from working. You need to specify it by module name. (On the command line, this would be by running `python -m package.submodule` from somewhere `package` is importable.) – user2357112 Mar 24 '20 at 08:18
  • 2
    Unfortunately, running package submodules by file path is a very natural thing for new Python programmers to try. Python's import system is confusingly designed and full of awkward pitfalls like that. – user2357112 Mar 24 '20 at 08:20
  • There are more red flags here, like the `pointr.bluej` in the package hierarchy, that suggest there may be further problems, and I suspect it may not make sense to use a package here at all, but it's hard to tell from just this. – user2357112 Mar 24 '20 at 08:28
  • We have a few projects and in each project a few packages each with a number of files/modules: and then we work with partners whose code needs to be orthogonal to ours. It's maybe fifty-ish python files - plus the assorted resources. Collapsing one level is maybe possible but probably not more than that. – WestCoastProjects Mar 24 '20 at 08:43

0 Answers0