Inheritable script Docstrings in Project Library not populating intellisense popup

Hello all,

I’m having an issue with my Python Docstrings where they’re not populating the Intellisense popup when I go to call them. Other Global scripts DO popup properly, just not this new one.

I’ve already restarted the gateway, no change.

I’ve compared the formatting against Google’s Python Style Guide AND against the other Global scripts that operate correctly.

I can call the script and it operates correctly, just no info popup.

Hoping someone like @pturmel can help with the Java wizardry :slight_smile:.

"""
These are all functions for helping with tag read/write functions, starting with tag read/write quality checks.
"""

#---------------------------------------------------------------------------------------------------------------#
# TAG READ/WRITE QUALITY CHECKS BEGIN
#---------------------------------------------------------------------------------------------------------------#

def _all_write_good(results, log):
	"""
	Returns True if all write results report good quality; accepts a single result or a list.
	
	Args:
		results: A single string or iterable list of tag write results.
		log: Gateway logger object initialized by system.util.getLogger(name).
	
	Returns:
		True/False, depending on if all write results are good quality.
		
	Raises:
		Exception: in case of exceptions, reports to gateway logs & returns False.
	"""
	try:
		if results is None:
			return False
		
		### This is for normalizing the results into an iterable, regardless of if they are a single item or multiple.
		# Only list-like objects have the __iter__ attribute (iterable)
		# Therefor, if results are iterable AND If results are not string or unicode:
		if hasattr(results, '__iter__') and not isinstance(results, (str, unicode)):
			iterable = results
		else:
			iterable = [results]
		
		# results have been normalized to a list, evaluate each item.
		for i in iterable:
			if hasattr(i, 'isGood'):
				if not i.isGood():
					return False
			
			# Fallback to string compare (brittle, but better than nothing)
			else:
				if unicode(i) != u'Good':
					return False
		# Assuming none of the fallout conditions have been satisfied, return True
		return True
	except Exception as exc:
		log.error('_all_write_good() returned an exception: {}'.format(exc))
		return False
		
#---------------------------------------------------------------------------------------------------------------#
def _all_read_good(qualified_values, log):
	"""
	Used with system.tag.readBlocking(); Returns True if all read results have .quality.isGood() == True.
	
	Args:
		qualified_values: A single object or list of objects returned by system.tag.readBlocking().
		log: Gateway logger object initialized by system.util.getLogger(name).
		
	Returns:
		True/False, depending on if all read results are good quality.
		
	Raises:
		Exception: in case of exceptions, reports to gateway logs & returns False.
	"""
	try:
		for qv in qualified_values:
			if not hasattr(qv, 'quality') or not qv.quality.isGood():
				return False
		return True
	except Exception as exc:
		log.error('_all_read_good() returned an exception: {}'.format(exc))
		return False
#---------------------------------------------------------------------------------------------------------------#
# TAG WRITE FUNCTION
#---------------------------------------------------------------------------------------------------------------#
def _write_with_retry(paths, values, timeout_ms, retries, log):
	"""
	Write with a limited number of retries.
	
	Args:
		paths: single string ('[default]PKnowlton_Testing/Integer1') or list [].
		values: single value or list [], must match paths.
		timeout_ms: timeout in milleseconds.
		log: Gateway logger object initiated by system.util.getLogger(name)
		
	Returns:
		2 items: True/False, and the last write results.
		
	Raises:
		Exception: in case of exceptions, reports to gateway logs & reports false.
	"""
	attempts = 0
	last_results = None
	while attempts <= retries:
		last_results = system.tag.writeBlocking(paths, values, timeout_ms)
		if _all_write_good(last_results, log):
			return True, last_results
		attempts += 1
		if attempts <= retries:
			log.warn("Write quality not good; retrying {}/{}... Results: {}".format(attempts, retries, last_results))
	return False, last_results

Both of these scripts are inherited and have their Docstring formatting the same. Just in case someone asks, yes I’ve saved & restarted the project/gateway.

Ignition 8.1.47, running on Windows Server 2019 | amd64

Java version 17.0.13+11-LTS

58gb/119gb

Sorry, no clue.

1 Like

Well that sucks.

Only difference I see is the ones that don’t work start with _ while barCodeScan doesn’t?

2 Likes

Yeah I thought that too, so I tried re-naming the functional one to include the underscore. It still worked, the other one still didn’t.

It's the underscore.

3 Likes

@paul-griffith do I need to rename the functions in the script as well, or just the overall script?

Also, I primarily added the underscore since I’m using something so close to ‘tag’ that I didn’t want to unintentionally cause issues/conflicts. Do you see any reason to not name it ‘tags’?

The actual function names.

The logic is that leading underscores 'by convention' mean something that should only be usable within the same script, so no point hinting them in other contexts even if they're technically callable.

The system will prevent you from naming your project library anything with conflicts that'll cause you issues with imports; beyond that I'd avoid anything like list or str or other builtin functions.

2 Likes

Thanks @paul-griffith !

I had to delete the script entirely and add it back in before it would re-parse correctly, but now it’s populating! I love this community so much, you guys are rockstars.

2 Likes