pytransitions / transitions

A lightweight, object-oriented finite state machine implementation in Python with many extensions
MIT License
5.49k stars 525 forks source link

Project dependencies may have API risk issues #609

Closed PyDeps closed 1 year ago

PyDeps commented 1 year ago

Hi, In transitions, inappropriate dependency versioning constraints can cause risks.

Below are the dependencies and version constraints that the project is using

six

The version constraint == will introduce the risk of dependency conflicts because the scope of dependencies is too strict. The version constraint No Upper Bound and * will introduce the risk of the missing API Error because the latest version of the dependencies may remove some APIs.

After further analysis, in this project, The version constraint of dependency six can be changed to >=1.4.0,<=1.16.0.

The above modification suggestions can reduce the dependency conflicts as much as possible, and introduce the latest version as much as possible without calling Error in the projects.

The invocation of the current project includes all the following methods.

In version six-1.3, the API six.add_metaclass whch is used by the current project in transitions/extensions/diagrams_base.py is missing.

image
The calling methods from the six
six.add_metaclass
six.iteritems
The calling methods from the all methods
asyncio.ensure_future
self.get_nested_transitions.extend
self.Machine.super.__init__
self._get_elements
self.machine._process
self.Tags.super.__init__
transitions.Machine.__init__
self.fsm_graph.add_edge
self.get_nested_state_names
container.edge
self.build_state_tree.get
self.HierarchicalMachine.super.get_transitions
_copy_agraph.delete_edge
trigger.self.events.transitions.items
self.get_state
logging.getLogger.addHandler
self.GraphMachine.super.__init__
self._get_enum_path
NestedEventData
event.transitions.items
resolve_order.append
self.state_cls.separator.join.pop
state_name_path.pop
self._add_string_state
mod.id.self.model_context_map.extend
self.__init__
repr
self.get_nested_transitions
state_name.self.get_state.add_callback
super.__init__
self.machine.get_model_state
dict
copy.copy
drop_event.append
self.LockedMachine.super.add_model
event_data.machine.get_state
self._init_graphviz_engine
self.add_transitions
self.create_timer
self._checked_assignment
format_references
functools.partial.append
transitions.core.listify
NestedEventData.machine
self.get_triggers
attr.update
EventData
graph.__class__
warnings.filterwarnings
scope.get
core.EventData
_build_state_list
queue.popleft
setuptools.find_packages
transitions.extend
PicklableLock
isinstance.split
_copy_agraph
container.node
collections.defaultdict.items
self.Volatile.super.enter
event_data.machine.get_triggers
cls.transition_cls
trans.add_callback
_DictionaryMock
self._get_state_path.append
id.get_graph
self.get_states
self._add_may_transition_func_for_trigger
self.get_state.pop
graph.get_subgraph
event_data.machine.resolve_callable
self.runner.get.start
self.lock.__enter__
model.get_graph
self.machine.callbacks
copy.copy.pop
result.append
event_data.machine.callbacks
logging.getLogger
diagrams.GraphMachine.format_references
self._init_state
self.states.keys
all
set.add
self._update_model
sub.subgraph
self.TransitionGraphSupport.super.__init__
self._change_state
inspect.isawaitable
cond.target.conditions.unless.append
contextlib.ExitStack
self.models.append
self.LockedMachine.super._add_model_to_state
event_data.event.trigger_nested.setdefault
rep
path.pop.get
_copy_agraph.in_edges
inspect.getmro
codecs.open
collections.OrderedDict
self._get_state_path
remapped_transitions.append
self.Volatile.super.exit
container.add_subgraph
isinstance.startswith
self.machine
root.node
markup.get
cls
self._convert_state_attributes
core.listify
running_task.cancel
graphviz.Digraph
getattr
self.Timeout.super.exit
self._has_state
copy.deepcopy
self.LockedMachine.super.__init__
dests.items
self.LockedMachine.super.__getattribute__
trans.get
hasattr
self.fsm_graph.get_node
self.Error.super.enter
callable
range
asyncio.gather
self._recursive_initial
self.add_substates
self.reset_styling
container.add_edge
self.separator.join
self.NestedEventData.super.__init__
self._process
AsyncEventData.update
self.transitions.values
self.NestedGraph.super.set_previous_transition
self._stack.append
self._set_state
predicate
self._add_machine_states
name.startswith
fsm_graph.graph_attr.update
self.resolve_callable
collections.Counter
_copy_agraph.has_node
self.Tags.super.__getattribute__
get_attr
separator.join
label_pos.startswith.startswith
logging.getLogger.debug
self.fsm_graph.style_attributes.get.get
self.get_global_name
self.get_transitions
self.add_states
self._add_dict_state
functools.reduce.get
self.Volatile.super.__init__
running_task.done
self.HierarchicalMachine.super._has_state
self.fsm_graph.subgraphs_iter
pygraphviz.AGraph
root.pop
functools.reduce.clear
self._cluster_states.append
self._convert_states_and_transitions
path.pop
self.build_state_tree.keys
c.check
threading.Lock
MachineError
self.current_context.get
id.set_node_style
container.add_subgraph.add_subgraph
state.split.append
self.fsm_graph.get_edge
self._add_nodes
self._trigger_event_nested
_convert
machine.state_cls.separator.join
drop_trans.append
trigger
mod.get_graph
self._create_edge_attr
self._add_enum_state
self._check_event_result
self.Timeout.super.__init__
iter
self.add_transition
graph.render
self._resolve_transition
self.Error.super.__init__
self.MarkupMachine.super._identify_callback
str
nesting.resolve_order
self.add_state
event.trigger
machine.get_state
event_data.machine.callback
self._identify_callback
sub_graph.graph_attr.update
logging.NullHandler
any
self.machine.process_context
self.await_all
self._is_auto_transition
self.dest.split
state.states.values.items
re.sub
container.get_edge
self._trigger_event_nested.values
id
kwargs.get.append
self.Timeout.super.enter
AttributeError
self.Retry.super.__init__
state.events.values
self._stack.pop
self._trigger_event_nested.get
self._create_transition
dst.transition.edge_labels.append
_get_subgraph
self.condition_cls
value.split.pop
default_style.self.machine.style_attributes.copy.update
inspect.ismethod
self
self.machine_context.append
event.name.startswith
_timeout
getattr.rsplit
graph.write
self.events.keys
self.get_state.copy
self._markup.pop.append
root.pop.pop
self.fsm_graph.nodes_iter
self.fsm_graph.style_attributes.get
self._get_qualified_state_name
trigger.self.events.transitions.items.v.k.dest.t.dest.dest.source.t.source.source.v.t.t.k.items
resolve_order.extend
self._markup.pop
_trigger.self.events.trigger_nested
self.__dict__.update
self.HierarchicalMachine.super.get_triggers
trigger.startswith
self.MachineError.super.__init__
container.add_node
self.GraphMachine.super.remove_transition
queue.append
machine.build_state_tree
itertools.chain
self.states.items
node.attr.update
self.Retry.super.enter
setattr
self.events.values
self.callbacks
self.enter
open
machine.get_global_name
remapped_transitions.extend
self.source.event_data.machine.get_state.exit
path.model.getattr.add
event_data.machine.get_states
model.id.self.async_tasks.remove
IdentManager
self.volatile_cls
_copy_agraph.delete_node
self._get_state_names
trigger.self.events.add_transition
edge.attr.update
state_cls.getattr.join
elems.pop
self._process_timeout
exec
filename.write
FunctionWrapper
self._can_trigger_nested
self.NestedGraph.super.set_node_style
list.extend
self.runner.get.cancel
default_style.self.machine.style_attributes.copy
fhandle.close
_filter_states
self._convert_models
type
self.process_context
self.has_trigger
cls.event_cls
self.__getattribute__
six.add_metaclass
self.GraphMachine.super.add_transition
os.path.splitext
listify
self._create_state
state_name.split.pop
itertools.chain.from_iterable
self._get_state_path.values
self.machine.get_state
attr.pop
self.MarkupMachine.super.add_states
state_name_path.pop.split
self.runner.get.done
functools.reduce
cls.__new__
contextvars.ContextVar
self.MarkupMachine.super.__init__
trigger.self.events.transitions.get
self._is_valid_source
self._create_event
kwargs.update
self.LockedMachine.super.remove_model
self.LockedMachine.super.__getattr__
drop_source.append
self.add_ordered_transitions
self.build_state_tree
ValueError
trigger.model.getattr
states.append
trans.execute
model.id.self.async_tasks.append
self.get_global_name.isdigit
core.Event
kwargs.keys
kwargs.pop
self._func
self.HierarchicalMachine.super.add_transition
self.models.remove
graph.pipe
self.HierarchicalMachine.super.add_model
warnings.simplefilter
event_data.machine.build_state_tree
self.runner.get
resolve_order
tmp_tree.get.get
container.subgraph
self.get_state.add_callback
self.NestedGraph.super.__init__
logging.getLogger.warning
list.index
self._convert_states
src.startswith
self.conditions.append
self.states.values
machine.callbacks
self._set_node_style
self.NestedState.super.__init__
setuptools.setup
state.pop.extend
self._convert_transitions
event_data.machine.await_all
self.state_cls.separator.join
_build_state_list.split
getattr.append
self.machine._get_enum_path
self.__dict__.items.add_callback
func
core.MachineError
cls.state_cls
machine.switch_model_context
dst.split
getattr.split
reversed
self._transition_queue
sub.add_subgraph.add_node
module_name.split
self.get_state.split
sum
contextlib.nested
state_name.event.source_name.self._create_transition.execute
stack.enter_context
id.set_previous_transition
self._omit_auto_transitions
model.id.self._transition_queue_dict.append
self.custom_styles.items
self.runner.get.is_alive
self.build_state_tree.items
issubclass
_copy_agraph.out_edges_iter
_copy_agraph.nodes
self.async_tasks.get
self.MarkupMachine.super.remove_transition
self.callback
self.HierarchicalMachine.super.__init__
self.retry_counts.update
self._remap_state
self.fsm_graph.node_attr.update
model.id.self._transition_queue_dict.popleft
functools.partial
asyncio.shield
len
__import__
set
self.exit
model.id.self._transition_queue_dict.clear
state.states.values
self.machine.get_markup_config
self.__class__.HierarchicalMachine.super.initial.fset
id.reset_styling
self.events.items
Exception
self.trigger_event
self._transition_queue.popleft
self.machine.state_cls.separator.join
_copy_agraph.edges
tests_require.append
self.lock.__exit__
kwargs.get
self.get_nested_triggers
self.fsm_graph.edges_iter
self._eval_conditions
list
self._transition_queue.append
self.current_context.set
self.get_markup_config
self._get_global_name.split
format
event_data.update
self.machine.get_global_name
self.TransitionGraphSupport.super._change_state
event_data.machine.set_state
tempfile.TemporaryFile
threading.Timer
trans_source.remove
self.set_node_style
func.func.__name__.startswith
root.append
self._get_graph
subgraph.graph_attr.update
super
markup.rsplit
self._add_trigger_to_model
self._get_state_path.get
edge_attr.container._get_subgraph.has_node
model.id.self._transition_queue_dict
self._add_nested_nodes
threading.get_ident
self.fsm_graph.style_attributes.get.get.copy
super.enter
six.iteritems
self._process_async
dict.get
transition.source.self.transitions.append
self.graph_cls
self.MarkupMachine.super.add_transition
to_scope.split
container.has_edge
self._transition_queue.extend
src.split
logging.getLogger.info
AsyncEventData
graph.subgraphs_iter
self.dest.event_data.machine.get_state.enter
queue.pop
name.self.getattr.add
self.GraphMachine.super.add_states
self.state_cls.separator.join.split
self.get_model_state
self._add_markup_model
importlib.import_module
key.root.append
self.set_state
trigger.split
self._add_edges
self._event_list.append
asyncio.current_task
self.fsm_graph.edge_attr.update
event_data.event.trigger_nested
delattr
self.LockedEvent.super.trigger
transitions.append
isinstance
self.generate
collections.deque
self.add
state.get
event_data.machine.get_global_name
asyncio.sleep
super.add_model
self._resolve_initial
cond.check
self.__dict__.items
_prep_ordered_arg
self._transition_queue.clear
logging.getLogger.error
self.GraphMachine.super.add_model
RuntimeError
self.add_model
super.exit
collections.defaultdict
tmp.seek
entered_states.append
self._enter_nested
self.HierarchicalMachine.super.add_ordered_transitions
self.get_global_name.split
self._get_global_name.startswith
self._add_model_to_state
event.transitions.values
self._transition_label
f.read
machine_cls
self._get_global_name
self.machine_attributes.update
self.Graph.super.__init__
item.startswith
join

@developer Could please help me check this issue? May I pull a request to fix it? Thank you very much.

aleneum commented 1 year ago

Hello @PyDeps,

sorry for not answering earlier. An interesting project/mission you have there going and I can follow your reasoning. What took me so long was that I had to make up my mind whether a version limit would make transitions easier and/or more reliable to use and I came to the conclusion it would not.

You mention add_metaclass as a 'problematic' method since it was introduced in six 1.4.0. However, you can nevertheless use transitions with an earlier version. Only the diagrams extension would be affected but this is as the name suggests just an optional extension.

six is mostly used for its string_types which I hope won't go away in the foreseeable future. This is also why I decided to not introduce upper version limits since this might limit future releases of transitions to be used in for instance poetry projects with rather strictly pinned six versions even though transitions would work perfectly fine in this context.

I guess I should take a look at the other requirements_*.txt files since the APIs of pygraphviz, mypy or pytest might be more volatile than six. A lower version limit for six might be a good fit for requirements_diagrams.txt.

I will close this issue (and the related PR) but if you (or any future reader) think(s) I overlooked important factors, let me know by leaving a comment.

Thanks again for your input. I appreciate your work and effort to make open source software better.