IBMStreams / streamsx.topology

Develop streaming applications for IBM Streams in Python, Java & Scala.
http://ibmstreams.github.io/streamsx.topology
Apache License 2.0
29 stars 43 forks source link

Python: import streamsx.rest_primitives raises ImportError #2476

Closed ghost closed 4 years ago

ghost commented 4 years ago
>>> from streamsx.rest_primitives import Instance
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/rolef/infosphereStreams/development/tk/streamsx.topology/com.ibm.streamsx.topology/opt/python/packages/streamsx/rest_primitives.py", line 40, in <module>
    import streamsx.topology.context
  File "/home/rolef/infosphereStreams/development/tk/streamsx.topology/com.ibm.streamsx.topology/opt/python/packages/streamsx/topology/context.py", line 27, in <module>
    import streamsx.rest
  File "/home/rolef/infosphereStreams/development/tk/streamsx.topology/com.ibm.streamsx.topology/opt/python/packages/streamsx/rest.py", line 71, in <module>
    from .rest_primitives import (Domain, Instance, Installation, RestResource, Toolkit, _StreamsRestClient, StreamingAnalyticsService, _streams_delegator,
ImportError: cannot import name 'Domain'

Importing the whole module import streamsx.rest_primitives also raises ImportError.

Current workaround: Do import streamsx.topology.context before importing anything from rest_primitives.

ghost commented 4 years ago

There are lots of circular imports, which cause these problem. A good discussion about circular imports and its problems is on stackoverflow.com: https://stackoverflow.com/questions/22187279/python-circular-importing

ghost commented 4 years ago

There are multiple dependencies between the modules streamsx.topology.context, streamsx.rest, streamsx.rest_primitives, and streamsx.build. When a module is imported, all code in it is executed. The role of __init__.py is not considered here.

When importing streamsx.rest_primitives, following happens:

  1. streamsx.topology.context is imported
  2. context imports streamsx.rest
  3. streamsx.rest imports various identifiers from streamsx.rest_primitives. (from streamsx.rest_primitives import ...)
  4. These identifiers are not yet defined as the importer is still at the beginning importing this module --> ImportError

With circular dependencies no from xyz import nnn should be done. The better choice would be to avoid circular imports by a clean refactoring.